可折叠桑基图 - D3
Collapsible Sankey Diagram - D3
我想知道如何根据鼠标点击制作桑基图collapse/expand节点。
我的图表是这样的:https://bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22
例如,我想单击节点 "PAGOU" 以及所有后续链接和节点(右侧)以将其删除。
我是根据 Vasco Asturiano(参考 readme.md)对齐选项制作的。
我根据我之前在这里的回答改编了下面的代码:
我向节点添加了属性以跟踪它们是否折叠以及折叠了多少父节点。还有它们是否可折叠——源节点不应该是可折叠的,因为图书馆似乎不喜欢没有链接的图表。
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
上面的 fiddle 适用于每个子节点都有一个父节点的标准树。但是,对于传统sankey特别适合的多亲子关系('lattice')场景;这种可折叠的表示可能不那么简单。例如,展开节点 A 以显示其子节点时,如果 A 的任何子节点有其他未展开的父节点,则自动展开父节点。这可能就是您想要的,因为仅显示部分出身会产生误导,但无论如何它确实会让您感到意外。可以通过不重新定位节点来减轻迷失方向。可能会有意想不到的组合扩展效应,尤其是对于高度网格化的数据结构。
我想知道如何根据鼠标点击制作桑基图collapse/expand节点。
我的图表是这样的:https://bl.ocks.org/TheBiro/f73a2a0625bb803179f3905fe7624e22
例如,我想单击节点 "PAGOU" 以及所有后续链接和节点(右侧)以将其删除。 我是根据 Vasco Asturiano(参考 readme.md)对齐选项制作的。
我根据我之前在这里的回答改编了下面的代码:
我向节点添加了属性以跟踪它们是否折叠以及折叠了多少父节点。还有它们是否可折叠——源节点不应该是可折叠的,因为图书馆似乎不喜欢没有链接的图表。
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
上面的 fiddle 适用于每个子节点都有一个父节点的标准树。但是,对于传统sankey特别适合的多亲子关系('lattice')场景;这种可折叠的表示可能不那么简单。例如,展开节点 A 以显示其子节点时,如果 A 的任何子节点有其他未展开的父节点,则自动展开父节点。这可能就是您想要的,因为仅显示部分出身会产生误导,但无论如何它确实会让您感到意外。可以通过不重新定位节点来减轻迷失方向。可能会有意想不到的组合扩展效应,尤其是对于高度网格化的数据结构。