我想从D3 Sankey chart using circle node instead of rectangle node重现这个过程,但是,我想只选择某些节点从矩形变为圆形。
例如,在示例中使用的jsfiddle中,您如何仅选择Node 4
和Node 7
转换为圆圈?
答案 0 :(得分:3)
我更新了您的fiddle。
基本上你只需要一些方法来选择你想要变化的节点。我使用了唯一的类名,因此您也可以使用CSS来设置它们的样式。我并不想编写代码来选择4和7(我懒惰),所以我只是选择了所有偶数节点。
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", function (d, i) { return i % 2 ? "node rect" : "node circle";
})
然后你可以用它来选择节点并添加圆圈而不是矩形。
svg.selectAll(".node.circle").append("circle")
.attr("r", sankey.nodeWidth() / 2)
.attr("cy", function(d) { return d.dy/2; })
.attr("cx", sankey.nodeWidth() / 2)
.style("fill", function (d) {
答案 1 :(得分:2)
还有另一种类似的方法,如下面的jsfiddle所示。
我是从this fiddle(来自你提到的另一个SO question)开始的,其中所有节点都已转换为圆圈:
然后我修改了现有的并添加了一些涉及在创建圆圈期间进行过滤的新代码:
// add the circles for "node4" and "node7"
node
.filter(function(d){ return (d.name == "node4") || (d.name == "node7"); })
.append("circle")
.attr("cx", sankey.nodeWidth()/2)
.attr("cy", function (d) {
return d.dy/2;
})
.attr("r", function (d) {
return Math.sqrt(d.dy);
})
.style("fill", function (d) {
return d.color = color(d.name.replace(/ .*/, ""));
})
.style("fill-opacity", ".9")
.style("shape-rendering", "crispEdges")
.style("stroke", function (d) {
return d3.rgb(d.color).darker(2);
})
.append("title")
.text(function (d) {
return d.name + "\n" + format(d.value);
});
// add the rectangles for the rest of the nodes
node
.filter(function(d){ return !((d.name == "node4") || (d.name == "node7")); })
.append("rect")
.attr("y", function (d) {
return d.dy/2 - Math.sqrt(d.dy)/2;
})
.attr("height", function (d) {
return Math.sqrt(d.dy);
})
.attr("width", sankey.nodeWidth())
.style("fill", function (d) {
return d.color = color(d.name.replace(/ .*/, ""));
})
.style("fill-opacity", ".9")
.style("shape-rendering", "crispEdges")
.style("stroke", function (d) {
return d3.rgb(d.color).darker(2);
})
.append("title")
.text(function (d) {
return d.name + "\n" + format(d.value);
});
为了在矩形旁边准确定位文本,必须修改类似的代码。
我相信最终结果看起来很自然,即使它失去了原始Sankey的一些特质(如更广泛的连接)。