useLayout.ts 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import dagre from "dagre";
  2. import { ref } from "vue";
  3. import { Position, useVueFlow } from "@vue-flow/core";
  4. export function useLayout() {
  5. const { findNode } = useVueFlow();
  6. const graph = ref(new dagre.graphlib.Graph());
  7. const previousDirection = ref("LR");
  8. function layout(nodes, edges, direction) {
  9. const dagreGraph = new dagre.graphlib.Graph();
  10. graph.value = dagreGraph;
  11. dagreGraph.setDefaultEdgeLabel(() => ({}));
  12. const isHorizontal = direction === "LR";
  13. dagreGraph.setGraph({ rankdir: direction });
  14. previousDirection.value = direction;
  15. for (const node of nodes) {
  16. const graphNode = findNode(node.id);
  17. dagreGraph.setNode(node.id, {
  18. width: graphNode.dimensions.width || 150,
  19. height: graphNode.dimensions.height || 50
  20. });
  21. }
  22. for (const edge of edges) {
  23. dagreGraph.setEdge(edge.source, edge.target);
  24. }
  25. dagre.layout(dagreGraph);
  26. return nodes.map(node => {
  27. const nodeWithPosition = dagreGraph.node(node.id);
  28. return {
  29. ...node,
  30. targetPosition: isHorizontal ? Position.Left : Position.Top,
  31. sourcePosition: isHorizontal ? Position.Right : Position.Bottom,
  32. position: { x: nodeWithPosition.x, y: nodeWithPosition.y }
  33. };
  34. });
  35. }
  36. return { graph, layout, previousDirection };
  37. }