双层D3分区/森伯斯特布局上的标签

时间:2013-07-21 05:02:29

标签: d3.js label hierarchy sunburst-diagram

我正在尝试为此处显示的双层旭日/分区添加标签 - http://bl.ocks.org/mbostock/5944371

enter image description here

我已在前两个级别添加标签并正确旋转它们。但我现在无法在过渡期间添加新级别的标签。为了开始,我已经把...

text = text.data(partition.nodes(root).slice(1), function(d) { return d.key; });

直接......

path = path.data(partition.nodes(root).slice(1), function(d) { return d.key; });

但它会引发以下错误...

Uncaught TypeError: Cannot read property '__data__' of undefined

我做错了什么?

3 个答案:

答案 0 :(得分:2)

我使用双层分区通过鼠标悬停添加标签,并发现在此版本中(与其他sunburst分区不同),有两个不同的部分,其中“path”被定义和更新。第一个是:

var path = svg.selectAll(“path”)

然后再次在代码中突出显示的转换下方: path.enter()。附加( “路径”)

当我添加鼠标悬停标签时,我需要在两个地方引用我的文本功能,否则在转换后它将无效。

如果您可以将代码发布到JSFiddle或bl.ocks.org,我们可以尝试使用它并查看,但这是我最初被绊倒的地方。

希望有所帮助。

*注意:评论未发布: 对不起,我无法提供更多帮助,但我也是D3的新手。这是我得到的地方:

将svg.selectAll(“text”)片段复制并粘贴到第二个“path.enter()。append(”path“)片段之后。这将导致它出现在后续缩放上。

我看到的问题:没有“g”元素,所以你需要单独的文本转换或者它们都堆积起来。此外,我无法理解为什么它们位于原始分区点而不是现在存在弧的位置。

我的方法是在mouseOver上添加标签。我已在此处上传:https://github.com/johnnymcnugget/d3-bilevelLabels

在这里,我在两组“路径”片段中调用两个函数,并且转换在“legend”的单个变量中处理

答案 1 :(得分:1)

另一个D3新手,但我设法解决了这个问题。从原始Bilevel Partition开始:

  1. 首次添加文本时绘制图表:
  2. var path = svg.selectAll("path")
          .data(partition.nodes(root).slice(1))
        .enter().append("path")
          .attr("d", arc)
          .style("fill", function(d) { return d.fill; })
          .each(function(d) { this._current = updateArc(d); })
          .on("click", zoomIn);
    
    
    var text = svg.selectAll("text")
          .data(partition.nodes(root).slice(1))
        .enter().append("text")
        .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
        .attr("x", function(d) {return radius / 3 * d.depth; })
        .attr("dx", "6") // margin
        .attr("dy", ".35em") // vertical-align
        .html(function(d) { return d.name; });
    
    1. 放大或缩小时必须重绘标签,请在function zoom(root, p)
    2. 中添加以下内容
      text.enter().append("text")
          .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
          .attr("x", function(d) {return radius / 3 * d.depth; })
          .attr("dx", "6") // margin
          .attr("dy", ".35em") // vertical-align
          .text(function(d) { return d.name; });
      
      text.exit().transition()
          .style("fill-opacity", function(d) { return d.depth === 1 + (root === p) ? 1 : 0; })
          .remove();
      text.transition()
          .style("fill-opacity", 1)
          .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
          .attr("x", function(d) {return radius / 3 * d.depth; })
          .attr("dx", "6") // margin
          .attr("dy", ".35em") // vertical-align
      
      1. 最后将computeTextRotation函数修改为:
      2. function computeTextRotation(d) {
          return (d.x + (d.dx)/2) * 180 / Math.PI - 90;
        }
        

        希望我没有错过任何东西。

答案 2 :(得分:0)

确实在" 2中缺少一条修改过的线。"。在function zoom(root, p)中,您还应在path = path.data(partition ... .key; });之后添加一行:

        path = path.data(partition.nodes(root).slice(1), function (d) {
            return d.key;
        });

        text = text.data(partition.nodes(root).slice(1), function (d) {
            return d.key;
        });