Dagre Layout
This example shows how to use Dagre for automatic hierarchical graph layout in Svelte Flow. Dagre is a JavaScript library that can automatically arrange nodes in a hierarchical structure, making it perfect for creating tree-like diagrams and flowcharts.
<script lang="ts">
import dagre from '@dagrejs/dagre';
import {
SvelteFlow,
Background,
Position,
ConnectionLineType,
Panel,
type Node,
type Edge,
} from '@xyflow/svelte';
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);
const layoutedNodes = nodes.map((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).
return {
...node,
position: {
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - nodeHeight / 2,
},
};
});
return { nodes: layoutedNodes, edges };
}
const { nodes: layoutedNodes, edges: layoutedEdges } = getLayoutedElements(
initialNodes,
initialEdges,
);
let nodes = $state.raw<Node[]>(layoutedNodes);
let edges = $state.raw<Edge[]>(layoutedEdges);
function onLayout(direction: string) {
const layoutedElements = getLayoutedElements(nodes, edges, direction);
nodes = layoutedElements.nodes;
edges = layoutedElements.edges;
}
</script>
<SvelteFlow
bind:nodes
bind:edges
fitView
connectionLineType={ConnectionLineType.SmoothStep}
defaultEdgeOptions={{ type: 'smoothstep', animated: true }}
>
<Panel position="top-right">
<button onclick={() => onLayout('TB')}>vertical layout</button>
<button onclick={() => onLayout('LR')}>horizontal layout</button>
</Panel>
<Background />
</SvelteFlow>
Last updated on