Customize position for certain node in d3 org chart

27 views Asked by At

How to customize position of certain node in d3 org chart? You can use layout bindings such as nodeUpdateTransform to modify each node. But the node is just a parameter-object with no identifier { x: 0, y: 0, width: 100, height: 100 }. For example, how to identify the "node2" in the code snippet below to modify x value?

const data = [
    { customId: 1, customParentId: null, customName: 'node1' },
    { customId: 2, customParentId: 1, customName: 'node2' },
    { customId: 3, customParentId: 1, customName: 'node3' },
  ];

    chart = new d3.OrgChart()
      .nodeId((dataItem) => dataItem.customId)
      .parentNodeId((dataItem) => dataItem.customParentId)
      .nodeWidth((node) => 100)
      .nodeHeight((node) => 100)
      .nodeContent((node) => {
        return `<div customId="${node.data.customId}" 
            style="background-color:aqua;width:${node.width}px;height:${node.height}px"
          > 
               ${node.data.customName}
           </div>`;
      })
      .container('.chart-container')
      .data(data).render();

   const layout = chart.layoutBindings();
   layout.top.nodeUpdateTransform = node => `translate(${(node.x-100) - node.width / 2},${node.y})`;
    chart.layoutBindings(layout).render();
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/d3-flextree.js"></script>

<div class="chart-container"></div>

I can think about two approaches:

  1. Modify the element after DOM is generated (d3.select('[customId="2"]');). But then you have to modify position each time, when the chart is .onExpandOrCollapse.

  2. Count through the tree. But disadvantage of this approach is, if the amount of nodes changes, the index could be change.

     i=0;
     layout.top.nodeUpdateTransform = function(node){
       if(i==1){
         i+=1;
         return `translate(${(node.x-100) - node.width / 2},${node.y})`;
       }
       i+=1;
       return `translate(${(node.x) - node.width / 2},${node.y})`;
     }
    
0

There are 0 answers