我将引导您完成几个实验(所有实验都附带 jsfiddles),以指导您解决问题。
初始点
(点击查看jsfiddle http://jsfiddle.net/Ars7m/)
这是您的问题的稍微修改过的示例:
它已被修改,以便它包含 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");
实验1
(点击查看jsfiddle http://jsfiddle.net/QwMPS/)
我真的很烦恼节点的值和名称没有对齐,所以我添加了这段代码,稍微向下移动值:
.attr("dy", 5)
结果在这里:
实验2
(点击查看jsfiddle http://jsfiddle.net/CRJ5J/)
现在让我们尝试添加此代码(我故意使用 45 度来更容易发现旋转的工作原理):
.attr("transform", "rotate(-45)")
令人惊讶的是,我们得到了这个:
如果我们在 firebug 或类似工具中检查 html/svg,我们会注意到这种旋转行为的原因是值标签实际上是其他容器的一部分:(并且旋转中心不是标签的中心,而是标签的原点)那个容器)
实验3
(点击查看jsfiddle http://jsfiddle.net/T5Rju/)
在这个实验中,我想完全避免使用旋转。我想使用 svg 文本属性writing-mode
, 像这样:
.style("writing-mode", "tb")
我得到了这个:
但是,我无法让值标签的顶部朝左。另外,我听说这个方法有一些Firefox兼容性问题,所以我放弃了。
Solution
(点击查看jsfiddle http://jsfiddle.net/mF27g/)
经过上述实验,我的结论是应该首先进行旋转,然后应用平移,以便已经旋转的值标签移动到节点的中心。由于此转换依赖于数据,因此代码应如下所示:
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) +
")";});
结果是: