在 dc.js 饼图中旋转饼图标签

Rotate Pie Label in dc.js Pie Chart

假设我在 dc.js 中有以下代码来创建饼图:

var chart = dc.pieChart("#test");
d3.csv("morley.csv", function(error, experiments) {
  var ndx           = crossfilter(experiments),
      runDimension  = ndx.dimension(function(d) {return "run-"+d.Run;})
      speedSumGroup = runDimension.group().reduceSum(function(d) {return d.Speed * d.Run;});
  chart
    .width(768)
    .height(480)
    .slicesCap(4)
    .innerRadius(100)
    .dimension(runDimension)
    .group(speedSumGroup)
    .legend(dc.legend())
    // workaround for #703: not enough data is accessible through .label() to display percentages
    .on('pretransition', function(chart) {
        chart.selectAll('text.pie-slice').text(function(d) {
            return d.data.key + ' ' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
        })
    });
  chart.render();
});

我想做的是旋转标签,但是当我这样做时,所有标签都平移到饼图的中心。

chart.renderlet(function (chart) {
    chart.selectAll('text.pie-slice')
    .attr('transform', 'rotate(315)');
});

有没有办法在不改变标签在图表上的位置的情况下旋转标签?

问题是您要替换这些元素的 transform 属性,该属性当前用于 "translate" 位置中的标签。

由于很难深入了解这里使用的计算,我认为最好的方法是拉出现有的转换属性并对其进行修改,如下所示:

chart.on('renderlet', function (chart) {
    chart.selectAll('text.pie-slice')
        .attr('transform', function(d) {
            var translate = d3.select(this).attr('transform');
            var ang = ((d.startAngle + d.endAngle) / 2 * 180 / Math.PI)%360;
            if(ang<180) ang -= 90; else ang += 90;
            return translate + ' rotate(' + ang + ')';
        });
});

为了娱乐,我还使用饼图切片的开始和结束角度旋转了标签。

不幸的是,您不能将此作为过渡前事件并避免 "jump"。它只会被动画覆盖。如果您有兴趣,正确地执行此操作需要对 dc.js - file an issue 进行一些更改。

添加到戈登的答案中,所有饼图都具有此功能;我在 dc.js.

中更改标签位置函数
return 'translate(' + centroid + ')';

var ang = ((d.startAngle + d.endAngle) / 2 * 180 / Math.PI)%360; 
if(ang<180) ang -= 90; else ang += 90; 
return 'translate(' + centroid + ') rotate(' + ang +')';