react-d3-graph icon indicating copy to clipboard operation
react-d3-graph copied to clipboard

align nodes as in the tree

Open MikeBelyayaev opened this issue 4 years ago • 4 comments

We are building a tree graph with some nodes having multiple parents. As this was not possible to achieve with the tree graph, we've decided to use network graph instead and your library seemed to be a great fit.

However I don't seem to see how we could align all the nodes like they do on the tree, so it is clear which node is actually a child of what parent and what level of hierarchy it belongs to. Like having root node on the top, then next level, then third level with some nodes connected to two different parents on the second level and so on.

Maybe it is already possible to do with current configuration, can't find the way.

Thank you

MikeBelyayaev avatar Feb 23 '21 22:02 MikeBelyayaev

Hi @belyayevxom ,

You can provide x and y values to your nodes, in order to place them wherever you want. You can see an example here (related data file)

Is this what you are looking for?

antoninklopp avatar Mar 06 '21 16:03 antoninklopp

Hi @belyayevxom, were you able to find any solution?

singhkumarpratik avatar Jan 21 '22 06:01 singhkumarpratik

Setting x and y along with staticGraphWithDragAndDrop = true helped in aligning the nodes

singhkumarpratik avatar Jan 21 '22 08:01 singhkumarpratik

Hi @MikeBelyayaev,

You can assign fx and fy properties to each node, representing their initial locations within the graph. To facilitate this, you might opt to utilize a dedicated package such as dagre, which can provide the necessary fx and fy values specifically tailored for tree structures. And also make sure you set staticGraphWithDragAndDrop to true. <Graph config={{staticGraphWithDragAndDrop: true}} />

here is code snippet you can use

import dagre from "dagre";

const getLayoutedElements = (canvasNodes: any[], canvasEdges: any[]) => {
  const dagreGraph = new dagre.graphlib.Graph();
  dagreGraph.setDefaultEdgeLabel(() => ({}));

  const nodeWidth = 470;
  const nodeHeight = 207;

  dagreGraph.setGraph({
    rankdir: "TB",
    edgesep: 50,
    ranksep: 100,
  });

  canvasNodes.forEach((node) => {
    dagreGraph.setNode(node.id, { width: nodeWidth, height: nodeHeight });
  });

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

  dagre.layout(dagreGraph);

  const layoutedNodes = canvasNodes.map((node) => {
    const newNode = { ...node };
    const nodeWithPosition = dagreGraph.node(node.id);

    newNode.fx = nodeWithPosition.x - nodeWidth / 2;
    newNode.fy = nodeWithPosition.y - nodeHeight / 2;

    return newNode;
  });

  return { layoutedNodes, layoutedEdges: canvasEdges };
};

sahil8453 avatar Feb 23 '24 20:02 sahil8453