如何在 dc.js 饼图上放置标签?
How to position labels on dc.js pie chart?
我想为小切片 (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 之后):
但它会产生烦人的过渡——标签向质心移动然后跳回。有解决办法吗?
没有真正解决您的问题,但在位置上进行转换可能看起来更好?
chart.selectAll('text')
.transition()
.delay(800)
.attr("transform", ...
我的解决方案有点过分,但我想知道现在是否可以替换转换位置,now that we have the pretransition event dc.js 2.0 beta 11。
事实上,它是。不切实际的部分是您的代码依赖于已经拥有的最终位置,如果我们替换转换,我们将不会拥有。相反,我们必须从头开始计算位置,这意味着从饼图中复制一堆代码。
我无法让您的代码正常工作,所以我只是通过将所有标签位置偏移 -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) + ')';
})
});
这里的主要思想是,如果您为元素指定新的过渡,它将替换已经处于活动状态的过渡。所以我们要完全删除原来的位置和过渡,并用我们自己的代替。没有"jump"!
我有解决这个问题的办法。尝试一次,这样可以避免饼图中标签名称的重叠。
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) + ')';
})
});
我想为小切片 (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 之后):
但它会产生烦人的过渡——标签向质心移动然后跳回。有解决办法吗?
没有真正解决您的问题,但在位置上进行转换可能看起来更好?
chart.selectAll('text')
.transition()
.delay(800)
.attr("transform", ...
我的解决方案有点过分,但我想知道现在是否可以替换转换位置,now that we have the pretransition event dc.js 2.0 beta 11。
事实上,它是。不切实际的部分是您的代码依赖于已经拥有的最终位置,如果我们替换转换,我们将不会拥有。相反,我们必须从头开始计算位置,这意味着从饼图中复制一堆代码。
我无法让您的代码正常工作,所以我只是通过将所有标签位置偏移 -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) + ')';
})
});
这里的主要思想是,如果您为元素指定新的过渡,它将替换已经处于活动状态的过渡。所以我们要完全删除原来的位置和过渡,并用我们自己的代替。没有"jump"!
我有解决这个问题的办法。尝试一次,这样可以避免饼图中标签名称的重叠。
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) + ')';
})
});