javascript - 如何在 Sankey 图(D3.JS)中的节点上垂直对齐文本?

标签 javascript svg d3.js label sankey-diagram

我从 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),这些实验将指导您解决问题。

起点

( click for jsfiddle )

这是对您的问题稍作修改的示例:

enter image description here

它已经过修改,因此它包含 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");

实验一

( click for jsfiddle )

我真的很烦节点的值和名称没有对齐,所以我添加了这段代码来稍微向下移动值:

      .attr("dy", 5)

结果在这里:

enter image description here


实验二

( click for jsfiddle )

现在让我们尝试添加此代码(我故意使用 45 度以便更容易地发现旋转的工作原理):

      .attr("transform", "rotate(-45)")

令人惊讶的是,我们得到了这个:

enter image description here

如果我们在 firebug 或类似工具中检查 html/svg,我们会注意到这种旋转行为的原因是值标签实际上是其他容器的一部分:(并且旋转中心不是标签的中心,但是那个容器的来源)

enter image description here


实验三

( click for jsfiddle )

在这个实验中,我想完全避免使用旋转。我想使用 svg 文本属性 writing-mode,像这样:

      .style("writing-mode", "tb")

我得到了这个:

enter image description here

但是,我无法将值标签设置为顶部向左。另外,我听说这个方法有一些Firefox兼容性问题,所以我放弃了。


解决方案

( click for jsfiddle )

经过上面的实验,我的结论是应该先进行旋转,然后应用平移,以便将已经旋转的值标签移动到节点的中心。由于此翻译是数据相关的,因此代码应如下所示:

  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) +
       ")";});

结果是:

enter image description here

关于javascript - 如何在 Sankey 图(D3.JS)中的节点上垂直对齐文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23434850/

相关文章:

javascript - 使用 For-Loop 使隐藏的表行在填充时显示

javascript - json 和空值

python - 从交互式图表中抓取数据

javascript - 简单堆叠行图

javascript - 更新形状属性时的对象一致性

javascript - d3 中的 d3.time.interval.range() 不返回等距间隔

JavaScript 元素在图像上的绝对位置

javascript - 如何从父组件访问路由信息?

jakarta-ee - 如何将动态生成的 SVG 包含到 Vaadin UI?

html - 我如何增加这个 SVG 的大小?