如何在dc.js饼图上定位标签?

时间:2015-06-04 23:22:58

标签: dc.js

我想显示小切片的标签(chart.minAngleForLabel(0.05)),以避免文字重叠。

我添加了一个将标签移向外边缘的renderlet:

  .on('renderlet', function(chart) {
      chart.selectAll('text').attr('transform', function(d, i) {
          var old = this.getAttribute('transform');
          if (d.endAngle-d.startAngle > 0.3) { return old; }
          var xy = old.slice(10,-1).split(',');
          var m = 1.25 + (i%3) * 0.25;
          return 'translate(' + (+xy[0]*m) + ',' + (+xy[1]*m) + ')';
      })
     })

我对它很满意(第二张图片是在renderlet之后):

before after

但它会产生令人讨厌的过渡 - 标签向质心方向移动然后向后跳跃。有解决方法吗?

3 个答案:

答案 0 :(得分:4)

我的解决方案有点过分,但我想知道现在是否可以在dc.js 2.0 beta 11中替换过渡位置now that we have the pretransition event

事实上,确实如此。不切实际的部分是你的代码依赖于已经拥有最终位置,如果我们替换过渡,我们就不会有。相反,我们必须从头开始计算位置,这意味着从饼图中复制一堆代码。

我无法让你的代码工作,所以我只是通过将所有标签位置偏移-25,-25来测试它。但这是同样的想法,我们使用原始代码来获取质心,然后修改那个位置:

// copied from pieChart
function buildArcs(chart) {
    return d3.svg.arc().outerRadius(chart.radius()).innerRadius(chart.innerRadius());
}

function labelPosition(d, arc) {
    var centroid = arc.centroid(d);
    if (isNaN(centroid[0]) || isNaN(centroid[1])) {
        return [0,0];
    } else {
        return centroid;
    }
}
//
        .on('pretransition', function(chart) {
            chart.selectAll('text.pie-slice').transition().duration(chart.transitionDuration())
                .attr('transform', function(d, i) {
                    var arc = buildArcs(chart);
                    var xy = labelPosition(d, arc);
                    return 'translate(' + (+xy[0] - 25) + ',' + (+xy[1] - 25) + ')';
            })
        });

这里的一个重要想法是,如果为元素指定新的转换,它将替换已经处于活动状态的转换。所以我们完全删除了原来的位置和转换,并用我们自己的替换它。没有“跳”!

答案 1 :(得分:2)

不是真的解决了你的问题,但是对于这个职位的过渡可能看起来更好吗?

chart.selectAll('text')
  .transition()
  .delay(800)
  .attr("transform", ...

答案 2 :(得分:0)

我有解决此问题的方法。尝试一次,这样可以避免饼图中的标签名称重叠。

function buildArcs(chart) {
return 
d3.svg.arc().outerRadius(chart.radius()).innerRadius(chart.innerRadius());
}

function labelPosition(d, arc) {
var centroid = arc.centroid(d);
if (isNaN(centroid[0]) || isNaN(centroid[1])) {
    return [0,0];
} else {
    return centroid;
}
}


.on('pretransition', function(chart) {            
chart.selectAll('text.pieslice').transition()
.duration(chart.transitionDuration())
         .attr('transform', function(d, i) {
           var j = 0;
           var arc = buildArcs(chart);
           var xy = labelPosition(d, arc);
           if (xy[1] < 0) {
             j = -(10 * (i + 1));
           }
           else {
             j = 10 * (i + 1);
           }
           return 'translate(' + (+xy[0] - 25) + ',' + (j) + ')';
        })
    });