dagrejs / dagre

Directed graph layout for JavaScript
MIT License
4.72k stars 606 forks source link

Question: Can we control positioning of siblings based its relation with parent node when laid out as TB? #452

Open sagunji opened 2 months ago

sagunji commented 2 months ago

Imagine a branching logic with True and False branch laid out Top-Bottom structure. What I wish to do is always have True branch on the left side and False on the right. Currently, I have a function that applies dagre layout and returns new position.

import type { LayoutAlgorithm } from '.';

const dagreLayout: LayoutAlgorithm = async (nodes, edges, options) => {
  const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
  dagreGraph.setGraph({
    rankdir: options.direction,
    nodesep: options.spacing[0],
    ranksep: options.spacing[1],
  });

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

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

  dagre.layout(dagreGraph);

  const nextNodes = nodes.map(node => {
    const { x, y } = dagreGraph.node(node.id);

    const position = {
      x: x - (node.width ?? 0) / 2,
      y: y - (node.height ?? 0) / 2,
    };

    return { ...node, position };
  });

  return { nodes: nextNodes, edges };
};

export default dagreLayout;

The node can be updated to have data such that they can have hand: TRUE | FALSE. But the caveat is, only the immediate children of branch will have the value and subsequent children of those nodes will not. How do I make control the position and also, make sure a linear structure?

PS. Apologies, as I wasn't sure where to actually put this question on this repo.

kanekv commented 2 months ago

Is there any workaround available for this?

sagunji commented 2 months ago

Is there any workaround available for this?

I haven't, sadly. Though I am looking at alternatives now, this may be solvable in elkjs.