我从 http://bost.ocks.org/mike/sankey/ 修改了 D3.Js 中桑基图的 Mike Bostok 示例将每个节点的值显示为:
Sankey http://uweb.cs.uvic.ca/~maleh2/sankey.png
node.append("text")
.attr("class","nodeValue");
///align vertically??
node.selectAll("text.nodeValue")
.attr("x", sankey.nodeWidth() / 2)
.attr("y", function (d) { return (d.dy / 2) })
.text(function (d) { return formatNumber(d.value); })
.attr("text-anchor", "middle");
//.attr("transform", "rotate(-90)")
Mike 示例中的所有代码和我的修改都在 jsfiddle (http://jsfiddle.net/4xNK5/)。我的问题是如何垂直显示节点的值?我假设了一个简单的 .attr("transform", "rotate(-90)");会做的。事实上,我得到了垂直对齐但不合适的节点的值。我无法理解其背后的逻辑。任何想法将不胜感激...
最佳答案
我将引导您完成几个实验(所有实验都附带 jsfiddle),这些实验将指导您解决问题。
起点
这是对您的问题稍作修改的示例:
它已经过修改,因此它包含 JavaScript 而不是 JSON 文件中的数据,并且它还包含来自 Sankey 插件的代码。这样做只是为了在 JsFiddle 中有工作示例。您当然可以调整它以满足您在数据等方面的需求......
关键代码在这里,正如你已经提到的:
node.selectAll("text.nodeValue")
.attr("x", sankey.nodeWidth() / 2)
.attr("y", function (d) { return (d.dy / 2) })
.text(function (d) { return formatNumber(d.value); })
.attr("text-anchor", "middle");
实验一
我真的很烦节点的值和名称没有对齐,所以我添加了这段代码来稍微向下移动值:
.attr("dy", 5)
结果在这里:
实验二
现在让我们尝试添加此代码(我故意使用 45 度以便更容易地发现旋转的工作原理):
.attr("transform", "rotate(-45)")
令人惊讶的是,我们得到了这个:
如果我们在 firebug 或类似工具中检查 html/svg,我们会注意到这种旋转行为的原因是值标签实际上是其他容器的一部分:(并且旋转中心不是标签的中心,但是那个容器的来源)
实验三
在这个实验中,我想完全避免使用旋转。我想使用 svg 文本属性 writing-mode
,像这样:
.style("writing-mode", "tb")
我得到了这个:
但是,我无法将值标签设置为顶部向左。另外,我听说这个方法有一些Firefox兼容性问题,所以我放弃了。
解决方案
经过上面的实验,我的结论是应该先进行旋转,然后应用平移,以便将已经旋转的值标签移动到节点的中心。由于此翻译是数据相关的,因此代码应如下所示:
node.selectAll("text.nodeValue")
.text(function (d) { return formatNumber(d.value); })
.attr("text-anchor", "middle")
.attr("transform", function (d) {
return "rotate(-90) translate(" +
(-d.dy / 2) +
", " +
(sankey.nodeWidth() / 2 + 5) +
")";});
结果是:
关于javascript - 如何在 Sankey 图(D3.JS)中的节点上垂直对齐文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23434850/