【发布时间】:2014-04-22 00:10:15
【问题描述】:
我想使用Sankey 图表,但使用的是圆形而不是矩形。
我正在学习Mike Bostock的例子。
我通过设置半径更改了那里的代码以使用圆形,但是如何将连接节点的线放置在圆形周围。
任何线索。
谢谢。
【问题讨论】:
-
分享你的代码会让其他人更容易帮助你。
标签: javascript svg d3.js transformation sankey-diagram
我想使用Sankey 图表,但使用的是圆形而不是矩形。
我正在学习Mike Bostock的例子。
我通过设置半径更改了那里的代码以使用圆形,但是如何将连接节点的线放置在圆形周围。
任何线索。
谢谢。
【问题讨论】:
标签: javascript svg d3.js transformation sankey-diagram
首先,我想告诉你,我喜欢你的想法。
我将引导您完成几个简单的步骤,以获得一个像样的带圆圈的桑基图。最终结果可能不适合您的应用程序,但我想它可能对您有用作为起点。一旦您了解了 d3 Sankey 插件的内部和外部功能,您应该能够准确地构建您设计和希望的内容。
这只是一个基本的 Sankey 示例。我在 jsfiddle 中包含了数据和 Sankey 插件代码。这只是为了方便,因为 jsfiled 没有合适的方法来包含多个文件。所以,这里是:
现在我们将做您已经做过的事情 - 将矩形转换为圆形。
让我们修改这段代码:
// add the rectangles for the nodes
node.append("rect")
.attr("height", function (d) {
return d.dy;
})
.attr("width", sankey.nodeWidth())
到此代码:
// add the circles for the nodes
node.append("circle")
.attr("cx", sankey.nodeWidth()/2)
.attr("cy", function (d) {
return d.dy/2;
})
.attr("r", function (d) {
return Math.sqrt(d.dy);
})
我选择使用 Math.sqrt() 因为这样圆的面积将与它所代表的值成比例。我认为这是circle最自然的选择。
结果在这里:
链接现在异常宽。让它们的宽度与它们所代表的流量的平方根成正比。
让我们修改这段代码:
.style("stroke-width", function (d) {
return Math.max(1, d.dy);
})
到此代码:
.style("stroke-width", function (d) {
return Math.max(1, Math.sqrt(d.dy));
})
结果在这里:
现在让我们修复链接的端点。
我将使用来自 answer to another SO question 的代码。
这段代码:
var path = sankey.link();
替换为这个:
var path = d3.svg.diagonal()
.source(function(d) { return {"x":d.source.y, "y":d.source.x}; })
.target(function(d) { return {"x":d.target.y, "y":d.target.x}; })
.projection(function(d) { return [d.y, d.x]; });
结果在这里:
现在链接节点的链接原点,但我们需要它们来连接我们的圆心
这就是我们要更改此代码的原因:
var path = d3.svg.diagonal()
.source(function(d) { return {"x":d.source.y, "y":d.source.x}; })
.target(function(d) { return {"x":d.target.y, "y":d.target.x}; })
.projection(function(d) { return [d.y, d.x]; });
.attr("width", sankey.nodeWidth())
到此代码:
var path = d3.svg.diagonal()
.source(function(d) {
return {"x":d.source.y + d.source.dy / 2,
"y":d.source.x + sankey.nodeWidth()/2};
})
.target(function(d) {
return {"x":d.target.y + d.target.dy / 2,
"y":d.target.x + sankey.nodeWidth()/2};
})
.projection(function(d) { return [d.y, d.x]; });
结果在这里:
快完成了。在最后一张图中仍然困扰我的是节点标签的位置。如果圆圈更大,它将与其标签重叠。我在最后一个版本中修复了这个问题。结果是:
【讨论】: