Skip to content

Aligning nodes X position #472

@philcon93

Description

@philcon93

Is there a way to ensure the nodes X axis doesn't get pushed out like the following:

Image

I don't really understand why these nodes get an X position further out

import dagre from '@dagrejs/dagre';
import { Edge, Node, Position } from '@xyflow/react';
import { Task } from './nodes/types';

const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));

/**
 * TB - top to bottom,
 * BT - bottom to top,
 * LR - left to right,
 * RL - right to left
 */
type Direction = 'TB' | 'BT' | 'LR' | 'RL';

export const getLayoutedElements = (nodes: Node[], edges: Edge[], direction: Direction = 'TB') => {
  const isHorizontal = direction === 'LR';
  dagreGraph.setGraph({
    rankdir: direction,
    ranksep: 24,
  });

  nodes.forEach((node) => {
    dagreGraph.setNode(node.id, { width: node.measured?.width, height: node.measured?.height });
  });

  edges.forEach((edge) => {
    dagreGraph.setEdge(edge.source, edge.target);
  });

  dagre.layout(dagreGraph);

  const newNodes = nodes.map((node) => {
    const nodeWithPosition = dagreGraph.node(node.id);
    const isTaskNode = node.type === 'task' && 'task' in node.data;
    const task = node.data.task as Task;
    const isApproveTask = isTaskNode && task.type === 'approve';
    const nodeXMargin = isApproveTask ? 20 : 0;

    const newNode: Node = {
      ...node,
      targetPosition: isHorizontal ? Position.Left : Position.Top,
      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).
      position: {
        x: nodeWithPosition.x - (node.measured?.width || 0) / 2 + nodeXMargin,
        y: nodeWithPosition.y - (node.measured?.height || 0) / 2,
      },
    };

    return newNode;
  });

  return { nodes: newNodes, edges };
};

I would like to be able to ensure all the tasks with green icons are aligned like the following, but the only way I can do that is by manually defining the X position for those nodes which wouldn't work with a dynamic layout

Image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions