feat(docs): add shuffle to layout example
This commit is contained in:
@@ -18,7 +18,7 @@ import { IntersectionApp, IntersectionCSS } from './intersection'
|
||||
import { SnapToHandleApp, SnappableConnectionLine } from './connection-radius'
|
||||
import { NodeResizerApp, ResizableNode } from './node-resizer'
|
||||
import { ToolbarApp, ToolbarNode } from './node-toolbar'
|
||||
import { LayoutApp, LayoutEdge, LayoutElements, LayoutNode, LayoutScript } from './layout'
|
||||
import { LayoutApp, LayoutEdge, LayoutElements, LayoutIcon, LayoutNode, useRunProcess, useShuffle } from './layout'
|
||||
|
||||
export const exampleImports = {
|
||||
basic: {
|
||||
@@ -129,7 +129,9 @@ export const exampleImports = {
|
||||
'initial-elements.js': LayoutElements,
|
||||
'ProcessNode.vue': LayoutNode,
|
||||
'AnimationEdge.vue': LayoutEdge,
|
||||
'useRunProcess.js': LayoutScript,
|
||||
'useRunProcess.js': useRunProcess,
|
||||
'useShuffle.js': useShuffle,
|
||||
'Icon.vue': LayoutIcon,
|
||||
'additionalImports': {
|
||||
'@vueuse/core': 'https://cdn.jsdelivr.net/npm/@vueuse/core@10.7.0/index.mjs',
|
||||
'@vueuse/shared': 'https://cdn.jsdelivr.net/npm/@vueuse/shared@10.7.0/index.mjs',
|
||||
|
||||
@@ -3,11 +3,13 @@ import dagre from 'dagre'
|
||||
import { nextTick, ref } from 'vue'
|
||||
import { Panel, Position, VueFlow, useVueFlow } from '@vue-flow/core'
|
||||
import { Background } from '@vue-flow/background'
|
||||
import Icon from './Icon.vue'
|
||||
import ProcessNode from './ProcessNode.vue'
|
||||
import AnimationEdge from './AnimationEdge.vue'
|
||||
|
||||
import { initialEdges, initialNodes } from './initial-elements.js'
|
||||
import { useRunProcess } from './useRunProcess'
|
||||
import { useShuffle } from './useShuffle'
|
||||
|
||||
const nodes = ref(initialNodes)
|
||||
|
||||
@@ -17,7 +19,9 @@ const dagreGraph = ref(new dagre.graphlib.Graph())
|
||||
|
||||
const cancelOnError = ref(true)
|
||||
|
||||
const { run, stop, isRunning } = useRunProcess({ dagreGraph, cancelOnError })
|
||||
const shuffle = useShuffle()
|
||||
|
||||
const { run, stop, reset, isRunning } = useRunProcess({ dagreGraph, cancelOnError })
|
||||
|
||||
const { findNode, fitView } = useVueFlow()
|
||||
|
||||
@@ -37,6 +41,7 @@ function handleLayout(direction) {
|
||||
dagreGraph.value.setNode(node.id, { width: graphNode.dimensions.width || 150, height: graphNode.dimensions.height || 50 })
|
||||
}
|
||||
|
||||
console.log(edges.value)
|
||||
for (const edge of edges.value) {
|
||||
dagreGraph.value.setEdge(edge.source, edge.target)
|
||||
}
|
||||
@@ -59,6 +64,16 @@ function handleLayout(direction) {
|
||||
fitView()
|
||||
})
|
||||
}
|
||||
|
||||
function shuffleGraph() {
|
||||
reset(nodes.value)
|
||||
|
||||
edges.value = shuffle(nodes.value)
|
||||
|
||||
nextTick(() => {
|
||||
handleLayout('LR')
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -86,26 +101,23 @@ function handleLayout(direction) {
|
||||
|
||||
<Panel class="process-panel" position="top-right">
|
||||
<div class="layout-panel">
|
||||
<button v-if="isRunning" @click="stop">🛑</button>
|
||||
<button v-else @click="run(nodes)">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 5v14l11-7z" fill="currentColor" />
|
||||
</svg>
|
||||
<button v-if="isRunning" title="stop" @click="stop">
|
||||
<Icon name="stop" />
|
||||
</button>
|
||||
<button v-else title="start" @click="run(nodes)">
|
||||
<Icon name="play" />
|
||||
</button>
|
||||
|
||||
<button title="horizontal" @click="handleLayout('LR')">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2,12 L22,12" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M7,7 L2,12 L7,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
<path d="M17,7 L22,12 L17,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
</svg>
|
||||
<button title="set horizontal layout" @click="handleLayout('LR')">
|
||||
<Icon name="horizontal" />
|
||||
</button>
|
||||
<button title="vertical" @click="handleLayout('TB')">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12,2 L12,22" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M7,7 L12,2 L17,7" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
<path d="M7,17 L12,22 L17,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
</svg>
|
||||
|
||||
<button title="set vertical layout" @click="handleLayout('TB')">
|
||||
<Icon name="vertical" />
|
||||
</button>
|
||||
|
||||
<button title="shuffle graph" @click="shuffleGraph">
|
||||
<Icon name="shuffle" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
40
docs/examples/layout/Icon.vue
Normal file
40
docs/examples/layout/Icon.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
name: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg v-if="name === 'play'" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 5v14l11-7z" fill="currentColor" />
|
||||
</svg>
|
||||
|
||||
<svg v-else-if="name === 'stop'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 16h8V8H8zm4 6q-2.075 0-3.9-.788t-3.175-2.137q-1.35-1.35-2.137-3.175T2 12q0-2.075.788-3.9t2.137-3.175q1.35-1.35 3.175-2.137T12 2q2.075 0 3.9.788t3.175 2.137q1.35 1.35 2.138 3.175T22 12q0 2.075-.788 3.9t-2.137 3.175q-1.35 1.35-3.175 2.138T12 22"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<svg v-else-if="name === 'horizontal'" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M2,12 L22,12" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M7,7 L2,12 L7,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
<path d="M17,7 L22,12 L17,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
</svg>
|
||||
|
||||
<svg v-else-if="name === 'vertical'" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12,2 L12,22" stroke="currentColor" stroke-width="2" />
|
||||
<path d="M7,7 L12,2 L17,7" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
<path d="M7,17 L12,22 L17,17" stroke="currentColor" stroke-width="2" fill="none" />
|
||||
</svg>
|
||||
|
||||
<svg v-else-if="name === 'shuffle'" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M14 20v-2h2.6l-3.175-3.175L14.85 13.4L18 16.55V14h2v6zm-8.6 0L4 18.6L16.6 6H14V4h6v6h-2V7.4zm3.775-9.425L4 5.4L5.4 4l5.175 5.175z"
|
||||
/>
|
||||
</svg>
|
||||
</template>
|
||||
@@ -2,4 +2,6 @@ export { default as LayoutApp } from './App.vue?raw'
|
||||
export { default as LayoutElements } from './initial-elements.js?raw'
|
||||
export { default as LayoutNode } from './ProcessNode.vue?raw'
|
||||
export { default as LayoutEdge } from './AnimationEdge.vue?raw'
|
||||
export { default as LayoutScript } from './useRunProcess.js?raw'
|
||||
export { default as useRunProcess } from './useRunProcess.js?raw'
|
||||
export { default as useShuffle } from './useShuffle.js?raw'
|
||||
export { default as LayoutIcon } from './Icon.vue?raw'
|
||||
|
||||
44
docs/examples/layout/useShuffle.js
Normal file
44
docs/examples/layout/useShuffle.js
Normal file
@@ -0,0 +1,44 @@
|
||||
function shuffleArray(array) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1))
|
||||
;[array[i], array[j]] = [array[j], array[i]]
|
||||
}
|
||||
}
|
||||
|
||||
// generate a list of all possible edges, excluding duplicates and self-references
|
||||
function generatePossibleEdges(nodes) {
|
||||
const possibleEdges = []
|
||||
|
||||
for (const sourceNode of nodes) {
|
||||
for (const targetNode of nodes) {
|
||||
if (sourceNode.id !== targetNode.id) {
|
||||
const edgeId = `e${sourceNode.id}-${targetNode.id}`
|
||||
possibleEdges.push({ id: edgeId, source: sourceNode.id, target: targetNode.id, type: 'animation', animated: true })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return possibleEdges
|
||||
}
|
||||
|
||||
// Function to create a new shuffled edges array
|
||||
export function useShuffle() {
|
||||
return (nodes) => {
|
||||
const possibleEdges = generatePossibleEdges(nodes)
|
||||
shuffleArray(possibleEdges)
|
||||
|
||||
const usedNodes = new Set()
|
||||
const newEdges = []
|
||||
|
||||
// ensure every node is used, maintaining a single starting node and no duplicate connections
|
||||
for (const edge of possibleEdges) {
|
||||
if (!usedNodes.has(edge.target) && (usedNodes.size === 0 || usedNodes.has(edge.source))) {
|
||||
newEdges.push(edge)
|
||||
usedNodes.add(edge.source)
|
||||
usedNodes.add(edge.target)
|
||||
}
|
||||
}
|
||||
|
||||
return newEdges
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user