2

我正在使用 d3.js 制作一个旭日形图创建工具,并且我正在尝试复制此页面上的标签方式上标签翻转的方式,以便它们永远不会倒置。问题是我会使用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属性,但结果证明这是一条红鲱鱼,因为它旋转了各个字母。我的图表基于此页面

提前致谢!

4

1 回答 1

2

一种选择是将文本嵌套在组内。该组的定位主要就像您当前定位文本一样,除了不使用“x”属性,您将使用除了现有指令之外的transform属性。请注意,转换的顺序在这里很重要;你需要先旋转然后翻译。translaterotate

然后,您将对组内的文本应用本地转换。即,如果需要翻转,它将旋转 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;});
  });
于 2013-04-18T22:40:39.880 回答