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