refactor(svelte): update node automatically when source-/ targetPos change

This commit is contained in:
moklick
2023-10-19 15:47:09 +02:00
parent 909e7f77aa
commit e5f877a9bd
8 changed files with 269 additions and 479 deletions
+1
View File
@@ -29,6 +29,7 @@
},
"type": "module",
"dependencies": {
"@dagrejs/dagre": "^1.0.4",
"@xyflow/svelte": "workspace:^"
}
}
@@ -3,21 +3,22 @@
import { page } from '$app/stores';
const routes = [
'add-node-on-drop',
'custom-connection-line',
'customnode',
'dagre',
'drag-n-drop',
'edges',
'figma',
'interaction',
'intersections',
'overview',
'stress',
'subflows',
'two-way-viewport',
'usesvelteflow',
'useupdatenodeinternals',
'validation',
'intersections',
'add-node-on-drop'
'validation'
];
const onChange = (event: Event) => {
@@ -0,0 +1,79 @@
<script lang="ts">
import { writable } from 'svelte/store';
import { SvelteFlow, Background, Position, ConnectionLineType, Panel } from '@xyflow/svelte';
import type { Edge, Node } from '@xyflow/svelte';
import dagre from '@dagrejs/dagre';
import '@xyflow/svelte/dist/style.css';
import { initialNodes, initialEdges } from './nodes-and-edges';
const dagreGraph = new dagre.graphlib.Graph();
dagreGraph.setDefaultEdgeLabel(() => ({}));
const nodeWidth = 172;
const nodeHeight = 36;
function getLayoutedElements(nodes: Node[], edges: Edge[], direction = 'TB') {
const isHorizontal = direction === 'LR';
dagreGraph.setGraph({ rankdir: direction });
nodes.forEach((node) => {
dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
});
edges.forEach((edge) => {
dagreGraph.setEdge(edge.source, edge.target);
});
dagre.layout(dagreGraph);
nodes.forEach((node) => {
const nodeWithPosition = dagreGraph.node(node.id);
node.targetPosition = isHorizontal ? Position.Left : Position.Top;
node.sourcePosition = isHorizontal ? Position.Right : Position.Bottom;
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
node.position = {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2
};
});
return { nodes, edges };
}
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(
initialNodes,
initialEdges
);
const nodes = writable<Node[]>(layoutedNodes);
const edges = writable<Edge[]>(layoutedEdges);
function onLayout(direction: string) {
const layoutedElements = getLayoutedElements($nodes, $edges, direction);
$nodes = layoutedElements.nodes;
$edges = layoutedElements.edges;
// nodes.set(layoutedElements.nodes);
// edges.set(layoutedElements.edges);
}
</script>
<div style="height:100vh;">
<SvelteFlow
{nodes}
{edges}
fitView
connectionLineType={ConnectionLineType.SmoothStep}
defaultEdgeOptions={{ type: 'smoothstep', animated: true }}
>
<Panel position="top-right">
<button on:click={() => onLayout('TB')}>vertical layout</button>
<button on:click={() => onLayout('LR')}>horizontal layout</button>
</Panel>
<Background />
</SvelteFlow>
</div>
@@ -0,0 +1,72 @@
import type { Node, Edge } from '@xyflow/svelte';
const position = { x: 0, y: 0 };
const edgeType = 'smoothstep';
export const initialNodes: Node[] = [
{
id: '1',
type: 'input',
data: { label: 'input' },
position
},
{
id: '2',
data: { label: 'node 2' },
position
},
{
id: '2a',
data: { label: 'node 2a' },
position
},
{
id: '2b',
data: { label: 'node 2b' },
position
},
{
id: '2c',
data: { label: 'node 2c' },
position
},
{
id: '2d',
data: { label: 'node 2d' },
position
},
{
id: '3',
data: { label: 'node 3' },
position
},
{
id: '4',
data: { label: 'node 4' },
position
},
{
id: '5',
data: { label: 'node 5' },
position
},
{
id: '6',
type: 'output',
data: { label: 'output' },
position
},
{ id: '7', type: 'output', data: { label: 'output' }, position }
];
export const initialEdges: Edge[] = [
{ id: 'e12', source: '1', target: '2', type: edgeType, animated: true },
{ id: 'e13', source: '1', target: '3', type: edgeType, animated: true },
{ id: 'e22a', source: '2', target: '2a', type: edgeType, animated: true },
{ id: 'e22b', source: '2', target: '2b', type: edgeType, animated: true },
{ id: 'e22c', source: '2', target: '2c', type: edgeType, animated: true },
{ id: 'e2c2d', source: '2c', target: '2d', type: edgeType, animated: true },
{ id: 'e45', source: '4', target: '5', type: edgeType, animated: true },
{ id: 'e56', source: '5', target: '6', type: edgeType, animated: true },
{ id: 'e57', source: '5', target: '7', type: edgeType, animated: true }
];
-8
View File
@@ -1,8 +0,0 @@
/* this gets exported as style.css and can be used for the default theming */
@import '../../../system/src/styles/init.css';
@import '../../../system/src/styles/base.css';
.svelte-flow__edge-label {
text-align: center;
position: absolute;
}
-8
View File
@@ -1,8 +0,0 @@
/* this gets exported as style.css and can be used for the default theming */
@import '../../../system/src/styles/init.css';
@import '../../../system/src/styles/style.css';
.svelte-flow__edge-label {
text-align: center;
position: absolute;
}