2

I'm trying to modify the width of a d3 sankey chart, so I can put expanded content (details about a node) into the space created by the resize. So user clicks node, chart shrinks to half it's width, and I can append content into the new space...

Thing is, the d3 sankey layout affects many other elements, and I'm not sure how to make a sankey change trickle through all the elements.

After defining the layout:

var sankey = d3.sankey()
    .nodeWidth(15)
    .nodePadding(10)
    .size([width, height]);

and then building the layout from the data

sankey
    .nodes(data.nodes)
    .links(data.links)
    .layout(32); 

I tried to update the layout via

d3.selectAll(".node")
    .on("click",function(d){
        sankey.size([width/2, height])
    })

which obviously doesn't work. Not sure how to push it back through the elements!

Plunker to show the whole picture: http://plnkr.co/edit/udEOog?p=preview

abenrob
  • 878
  • 10
  • 23

1 Answers1

1

This was more straightforward than I thought... The sankey layout functions just define the size and locations of things, so that needs to be called to determine the changes, then I just need to re-define the node and link attributes based on the sankey results.

(updated plunker: http://plnkr.co/edit/ICyqJk?p=preview)

d3.selectAll(".node")
    .on("click",function(d){
      var newwidth;
      if (this.className.baseVal.indexOf("shift")>=0){
        newwidth = width;
        d3.selectAll(".node")
          .classed("shift",false)
      } else {
        newwidth = width*.5;
        d3.selectAll(".node")
          .classed("shift",true)
      }
      sankey
        .size([newwidth, height])
        .layout(32)
      link
        .transition()
        .attr("d", path)
      node
        .transition()
        .attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        })
    })
abenrob
  • 878
  • 10
  • 23