Collapsible Sankey Diagram - D3

*爱你&永不变心* 提交于 2020-01-24 15:15:07

问题


I want to know how to make a sankey diagram collapse/expand the nodes based on mouse click.

My diagram is this: https://bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22

For example, I want to click on the node "PAGOU" and all of the subsequent links and nodes (on the right) to be removed. I made it based on the Vasco Asturiano (reference on readme.md) aligment options.


回答1:


I adapted the code below from my previous answer here: Collapsible D3 force directed graph with non-tree data

I added properties to the nodes to keep track of whether they are collapsed and how many of their parent nodes are collapsed. Also whether they are collapsible - the source node should not be collapsible because the library doesn't seem to like graphs with no links.

graph.nodes.forEach(function (d, i) {
  graph.nodes[i] = { "name": d };
  graph.nodes[i].collapsing = 0;    // count of collapsed parent nodes
  graph.nodes[i].collapsed = false;
  graph.nodes[i].collapsible = false;
});

I changed the code for the links to point to the whole source or target node rather than the index because we need the source nodes for filtering. I also set all target nodes are collapsible.

graph.links.forEach(function(e) {
  e.source = graph.nodes.filter(function(n) {
        return n.name === e.source;
      })[0],
  e.target = graph.nodes.filter(function(n) {
        return n.name === e.target;
      })[0];
  e.target.collapsible = true;   
});

I pulled the layout code out into a function so that we can call it every time a node is clicked. I also added code to filter the graph nodes and links each time based on whether they and their parents are collapsed.

update();

var nodes, links;

function update() {
  nodes = graph.nodes.filter(function(d) {
    // return nodes with no collapsed parent nodes
    return d.collapsing == 0;
  });

  links = graph.links.filter(function(d) {
    // return only links where source and target are visible
    return d.source.collapsing == 0 && d.target.collapsing == 0;
  });

  // Sankey properties
  sankey
    .nodes(nodes)
    .links(links)
    .layout(32);

  // I need to call the function that renders the sakey, remove and call it again, or the gradient coloring doesn't apply (I don't know why)
  sankeyGen();
  svg.selectAll("g").remove();
  sankey.align("left").layout(32);
  sankeyGen();
}

I had to comment out this line because it was interfering with the click handler, I'm not sure what I've changed there.

.on("start", function() {
    //this.parentNode.appendChild(this);
})

I added a click handler to perform the collapsing.

node.on('click', click);
function click(d) {
  if (d3.event.defaultPrevented) return;
  if (d.collapsible) {
    // If it was visible, it will become collapsed so we should decrement child nodes count
    // If it was collapsed, it will become visible so we should increment child nodes count
    var inc = d.collapsed ? -1 : 1;
    recurse(d);

    function recurse(sourceNode){
      //check if link is from this node, and if so, collapse
      graph.links.forEach(function(l) {
        if (l.source.name === sourceNode.name){
          l.target.collapsing += inc;
          recurse(l.target);
        }
      });
    }
    d.collapsed = !d.collapsed;  // toggle state of node
  }      
  update();
}

Complete code in cirofdo's Gist




回答2:


The above fiddle works great for standard trees where each child has a single parent. However, for the multiple parentage ('lattice') scenario where the traditional sankey is uniquely suited; this collapsible representation is perhaps less straightforward. For instance, when expanding node A to show its children, if any A's children have other parents that are not expanded, the parents get expanded automatically. This is probably what you want, since showing only partial parentage would be misleading but it does take you a bit by surprise anyway. Disorientation could be mitigated by not re-centering the nodes. There may be unintended combinatorial expansion effects, especially for highly-latticed data structures.



来源:https://stackoverflow.com/questions/42701752/collapsible-sankey-diagram-d3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!