bumbeishvili / org-chart

Highly customizable org chart. Integrations available for Angular, React, Vue
https://stackblitz.com/edit/web-platform-o5t1ha
MIT License
928 stars 330 forks source link

How to alter the positions of certain nodes based on data? #268

Closed codingsisya closed 1 year ago

codingsisya commented 1 year ago

We have a requirement to place certain nodes lower to its siblings. I tried playing around with transform attribute in nodeUpdate method but it is not working on chart render, works for a second when expand/collapse button is clicked and goes back to original location.

Something like this, the firs child node is positioned slightly lower to its siblings. image

bumbeishvili commented 1 year ago

You can set different height and different top margins for specific node

chart
     .nodeContent(d=>{
            let topMargin = 0
            if(d.id=='O-6068') topMargin = 20
            return `<div style='margin-top:${topMargin}px;width:130px;height:100px;border:1px solid black'>${d.id}</div>`
      })
     .nodeHeight(d=>d.id=='O-6068'?120:100)

Here is a full code (copy pase it to https://realtimehtml.com)

   <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/d3-org-chart@2"></script>
    <script src="https://cdn.jsdelivr.net/npm/d3-flextree@2.1.2/build/d3-flextree.js"></script>
    <div
      class="chart-container"
    ></div>

    <script>
      var chart;
      d3.csv(
        'https://raw.githubusercontent.com/bumbeishvili/sample-data/main/org.csv'
      ).then(data => {
        chart = new d3.OrgChart()
          .container('.chart-container')
          .data(data) 
          .nodeWidth(d=>130)
          .nodeContent(d=>{
                 let topMargin = 0
                 if(d.id=='O-6068') topMargin = 20
                 return `<div style='margin-top:${topMargin}px;width:130px;height:100px;border:1px solid black'>${d.id}</div>`
           })
          .nodeHeight(d=>d.id=='O-6068'?120:100)
          .compact(false)
          .render();
      });
    </script>

This will be the result

image