From 61f4b0d447fde0eff6324cb7d1f5ae00f9f397bd Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:53:16 +0300 Subject: [PATCH] docs(examples): add simple layout example (#1678) * docs(examples): cleanup animated layout example Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * chore(docs,deps): update deps Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> * docs(examples): add animated and simple layout examples Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --------- Signed-off-by: braks <78412429+bcakmakoglu@users.noreply.github.com> --- docs/examples/index.ts | 11 + docs/examples/layout-simple/App.vue | 133 +++ docs/examples/layout-simple/Icon.vue | 40 + docs/examples/layout-simple/index.ts | 4 + .../layout-simple/initial-elements.js | 94 ++ docs/examples/layout-simple/useLayout.js | 56 ++ docs/examples/layout/App.vue | 7 +- docs/examples/layout/initial-elements.js | 21 +- docs/package.json | 22 +- docs/src/.vitepress/config.mts | 9 +- docs/src/examples/layout/animated.md | 10 + .../examples/{layout.md => layout/simple.md} | 4 +- pnpm-lock.yaml | 911 +++++++++++------- 13 files changed, 959 insertions(+), 363 deletions(-) create mode 100644 docs/examples/layout-simple/App.vue create mode 100644 docs/examples/layout-simple/Icon.vue create mode 100644 docs/examples/layout-simple/index.ts create mode 100644 docs/examples/layout-simple/initial-elements.js create mode 100644 docs/examples/layout-simple/useLayout.js create mode 100644 docs/src/examples/layout/animated.md rename docs/src/examples/{layout.md => layout/simple.md} (88%) diff --git a/docs/examples/index.ts b/docs/examples/index.ts index 0ba4d3b7..cf9f6141 100644 --- a/docs/examples/index.ts +++ b/docs/examples/index.ts @@ -19,6 +19,8 @@ import { SnapToHandleApp, SnappableConnectionLine } from './connection-radius' import { NodeResizerApp, ResizableNode } from './node-resizer' import { ToolbarApp, ToolbarNode } from './node-toolbar' import { LayoutApp, LayoutEdge, LayoutElements, LayoutIcon, LayoutNode, useLayout, useRunProcess, useShuffle } from './layout' +import { SimpleLayoutApp, SimpleLayoutElements, SimpleLayoutIcon, useSimpleLayout } from './layout-simple' + import { MathApp, MathCSS, MathElements, MathIcon, MathOperatorNode, MathResultNode, MathValueNode } from './math' import { ConfirmApp, ConfirmDialog, useDialog } from './confirm-delete' @@ -140,6 +142,15 @@ export const exampleImports = { '@dagrejs/dagre': 'https://cdn.jsdelivr.net/npm/@dagrejs/dagre@1.1.2/+esm', }, }, + layoutSimple: { + 'App.vue': SimpleLayoutApp, + 'initial-elements.js': SimpleLayoutElements, + 'useLayout.js': useSimpleLayout, + 'Icon.vue': SimpleLayoutIcon, + 'additionalImports': { + '@dagrejs/dagre': 'https://cdn.jsdelivr.net/npm/@dagrejs/dagre@1.1.2/+esm', + }, + }, math: { 'App.vue': MathApp, 'ValueNode.vue': MathValueNode, diff --git a/docs/examples/layout-simple/App.vue b/docs/examples/layout-simple/App.vue new file mode 100644 index 00000000..2e2ed4f4 --- /dev/null +++ b/docs/examples/layout-simple/App.vue @@ -0,0 +1,133 @@ + + + + + diff --git a/docs/examples/layout-simple/Icon.vue b/docs/examples/layout-simple/Icon.vue new file mode 100644 index 00000000..a69d9cc7 --- /dev/null +++ b/docs/examples/layout-simple/Icon.vue @@ -0,0 +1,40 @@ + + + diff --git a/docs/examples/layout-simple/index.ts b/docs/examples/layout-simple/index.ts new file mode 100644 index 00000000..30166481 --- /dev/null +++ b/docs/examples/layout-simple/index.ts @@ -0,0 +1,4 @@ +export { default as SimpleLayoutApp } from './App.vue?raw' +export { default as SimpleLayoutElements } from './initial-elements.js?raw' +export { default as useSimpleLayout } from './useLayout.js?raw' +export { default as SimpleLayoutIcon } from './Icon.vue?raw' diff --git a/docs/examples/layout-simple/initial-elements.js b/docs/examples/layout-simple/initial-elements.js new file mode 100644 index 00000000..2c2f3b38 --- /dev/null +++ b/docs/examples/layout-simple/initial-elements.js @@ -0,0 +1,94 @@ +const position = { x: 0, y: 0 } + +export const initialNodes = [ + { + id: '1', + position, + data: { + label: 'Node 1', + }, + }, + { + id: '2', + position, + data: { + label: 'Node 2', + }, + }, + { + id: '2a', + position, + data: { + label: 'Node 2a', + }, + }, + { + id: '2b', + position, + data: { + label: 'Node 2b', + }, + }, + { + id: '2c', + position, + data: { + label: 'Node 2c', + }, + }, + { + id: '2d', + position, + data: { + label: 'Node 2d', + }, + }, + { + id: '3', + position, + data: { + label: 'Node 3', + }, + }, + { + id: '4', + position, + data: { + label: 'Node 4', + }, + }, + { + id: '5', + position, + data: { + label: 'Node 5', + }, + }, + { + id: '6', + position, + data: { + label: 'Node 6', + }, + }, + { + id: '7', + position, + data: { + label: 'Node 7', + }, + }, +] + +export const initialEdges = [ + { id: 'e1-2', source: '1', target: '2' }, + { id: 'e1-3', source: '1', target: '3' }, + { id: 'e2-2a', source: '2', target: '2a' }, + { id: 'e2-2b', source: '2', target: '2b' }, + { id: 'e2-2c', source: '2', target: '2c' }, + { id: 'e2c-2d', source: '2c', target: '2d' }, + { id: 'e3-7', source: '3', target: '4' }, + { id: 'e4-5', source: '4', target: '5' }, + { id: 'e5-6', source: '5', target: '6' }, + { id: 'e5-7', source: '5', target: '7' }, +] diff --git a/docs/examples/layout-simple/useLayout.js b/docs/examples/layout-simple/useLayout.js new file mode 100644 index 00000000..652aced6 --- /dev/null +++ b/docs/examples/layout-simple/useLayout.js @@ -0,0 +1,56 @@ +import dagre from '@dagrejs/dagre' +import { Position, useVueFlow } from '@vue-flow/core' +import { ref } from 'vue' + +/** + * Composable to run the layout algorithm on the graph. + * It uses the `dagre` library to calculate the layout of the nodes and edges. + */ +export function useLayout() { + const { findNode } = useVueFlow() + + const graph = ref(new dagre.graphlib.Graph()) + + const previousDirection = ref('LR') + + function layout(nodes, edges, direction) { + // we create a new graph instance, in case some nodes/edges were removed, otherwise dagre would act as if they were still there + const dagreGraph = new dagre.graphlib.Graph() + + graph.value = dagreGraph + + dagreGraph.setDefaultEdgeLabel(() => ({})) + + const isHorizontal = direction === 'LR' + dagreGraph.setGraph({ rankdir: direction }) + + previousDirection.value = direction + + for (const node of nodes) { + // if you need width+height of nodes for your layout, you can use the dimensions property of the internal node (`GraphNode` type) + const graphNode = findNode(node.id) + + dagreGraph.setNode(node.id, { width: graphNode.dimensions.width || 150, height: graphNode.dimensions.height || 50 }) + } + + for (const edge of edges) { + dagreGraph.setEdge(edge.source, edge.target) + } + + dagre.layout(dagreGraph) + + // set nodes with updated positions + return nodes.map((node) => { + const nodeWithPosition = dagreGraph.node(node.id) + + return { + ...node, + targetPosition: isHorizontal ? Position.Left : Position.Top, + sourcePosition: isHorizontal ? Position.Right : Position.Bottom, + position: { x: nodeWithPosition.x, y: nodeWithPosition.y }, + } + }) + } + + return { graph, layout, previousDirection } +} diff --git a/docs/examples/layout/App.vue b/docs/examples/layout/App.vue index c6123bbb..766f77f2 100644 --- a/docs/examples/layout/App.vue +++ b/docs/examples/layout/App.vue @@ -52,7 +52,12 @@ async function layoutGraph(direction) {