如何旋转文本标签以使它们不能颠倒(SVG)?

时间:2013-04-18 18:58:57

标签: javascript svg d3.js label sunburst-diagram

我正在使用d3.js创建一个sunburst图表创建工具,我正在尝试复制this page上的标签翻转方式,以便它们永远不会颠倒。问题是我会将rotatetransform属性一起使用,但这已经用于定位标签。这是我目前的代码:

svg.selectAll("text")
    .data(partition.nodes)
    .enter()
    .append("text")
    .attr("transform", function(d) { return "rotate(" + ((d.x + d.dx / 2 - Math.PI / 2) / Math.PI * 180) + ")"; }) 
    .attr("x", function(d) { return Math.sqrt(d.y); })
    .attr("dx", "6") // margin
    .attr("dy", ".35em") // vertical-align
    .text(function(d) { return d.name;});

我找到了tspan rotate属性,但当它旋转单个字母时,结果证明是红鲱鱼。我的图表基于this page

提前致谢!

1 个答案:

答案 0 :(得分:2)

一种选择是将文本嵌套在一个组中。该群组的位置大部分与您目前正在定位文字一样,除了使用“x”属性外,除了现有transform之外,您还会使用translate属性rotate 1}}指令。请注意,转换的顺序在这里很重要;你需要先旋转那么翻译。

然后,您将本地转换应用于组内的文本。即如果需要翻转,它会旋转180度。通过这种方式,文本不需要移动到位 - 该组负责处理 - 但是当它被翻转时可能需要进行小的局部调整(在这种情况下,ir可能必须正确对齐) )。

下面的代码应该或多或少地做到这一点,虽然我不可能在没有工作的jsFiddle的情况下测试和调整它。

svg.selectAll("g.label")
  .data(partition.nodes)
  .enter()
  .append("g")
  .attr("class", "label")
  .attr("transform", function(d) {
    // First, rotate the group (not the text) and then translate it
    // by the same amount that used to be applied via "x" attr
    return
      "rotate(" + ((d.x + d.dx / 2 - Math.PI / 2) / Math.PI * 180) + ") " +
      "translate(" + Math.sqrt(d.y) + ")";
  })
  .each(function(d, i) {
    d3.select(this) // select the containing group (which was just created above)
      .append('text') // append text inside the group
      .attr("dx", "6") // margin
      .attr("dy", ".35em") // vertical-align
      .attr("transform", function(d) {
        // Locally transform the text within the containing group:
        // Label should be flipped if group's rotation is greater than Math.PI (aka 180 degs)
        var shouldBeFlipped = d.x + d.dx / 2 - Math.PI / 2 > Math.PI;
        return "rotate(" + (shouldBeFlippled ? 180 : 0) + ")"
      })
      .text(function(d) { return d.name;});
  });