javascript - 可折叠桑基图 - D3

标签 javascript d3.js sankey-diagram

我想知道如何使桑基图基于鼠标单击折叠/展开节点。

我的图表是这样的:https://bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22

例如,我想单击节点“PAGOU”并将所有后续链接和节点(右侧)删除。 我是根据 Vasco Asturiano(引用 readme.md)对齐选项制作的。

最佳答案

我根据之前的回答改编了以下代码: Collapsible D3 force directed graph with non-tree data

我向节点添加了属性,以跟踪它们是否折叠以及有多少个父节点折叠。另外,它们是否可折叠 - 源节点不应该是可折叠的,因为该库似乎不喜欢没有链接的图形。

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;
});

我更改了链接的代码,使其指向整个源或目标节点而不是索引,因为我们需要源节点进行过滤。我还设置所有目标节点都是可折叠的。

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;   
});

我将布局代码提取到一个函数中,以便我们可以在每次单击节点时调用它。我还添加了代码来根据图表节点和链接及其父级是否折叠来过滤它们。

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();
}

我必须注释掉这一行,因为它干扰了点击处理程序,我不确定我在那里更改了什么。

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

我添加了一个点击处理程序来执行折叠。

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();
}

完整代码在 cirofdo's Gist

关于javascript - 可折叠桑基图 - D3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42701752/

相关文章:

javascript - 使用 CSS 过滤器后保存图像

javascript - 为什么 JavaScript 中 "5"+ 2+3 和 2+3+ "5"不同?

r - 桑基网络手动换色

javascript - d3 桑基图 - 如何设置 y 位置

r - ggalluvial - 对地层的顺序进行排序

javascript - Discord bot TypeError : client. guilds.forEach 不是函数

JavaScript 表单验证

javascript - 带更新按钮的 D3.js 将新数据添加到旧数据而不是替换旧数据

svg - 如何获得笔画的轮廓?

javascript - 在 D3 力导向图中突出显示所选节点、其链接及其子节点