d3js在饼图周围重新分布标签 [英] d3js Redistributing labels around a pie chart

查看:166
本文介绍了d3js在饼图周围重新分布标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用d3.js在外部创建一个带有标签的圆环图。使用基于饼图的每个切片的质心的一些三角学,我定位标签。

I'm using d3.js to create a donut chart with labels on the outside. Using some trigonometry based on the centroids of each slice of the pie, I position the labels.

g.append("g")
        .attr("class", "percentage")
        .append("text")
            .attr("transform", function(d)
                { 
                    var c = arc.centroid(d);
                    var x = c[0];
                    var y = c[1];
                    var h = Math.sqrt(x*x + y*y);
                    return "translate(" + (x/h * obj.labelRadius) +  ',' + (y/h * obj.labelRadius) +  ")"; 
                }
            ) 
            .attr("dy", ".4em")
            .attr("text-anchor", function(d) 
                {
                    return (d.endAngle + d.startAngle)/2 > Math.PI ? "end" : "start";
                }
            )
            .text(function(d) { return d.data.percentage+"%"; });

我最终要实现的是重新排列饼图边缘以外的标签,以防止重叠。

What I'm ultimately trying to accomplish is to rearrange labels that are outside the edges of the pie chart, to prevent overlaps.

我试图解决问题的方法之一是定义set锚点,其中可以定位标签,保证它们不会重叠。问题是将质心映射到锚点,并保持切片和标签之间的视觉对应感(特别是当切片很薄时很难)。

One of the ways I have tried to solve the problem is to define set "anchor points", where labels can be positioned, guaranteeing that they will no overlap. Problem is mapping the centroids to the anchors and preserving some sense of visual correspondence between the slices and the labels (Specially difficult when slices are slim).

上面的图片显示了锚点的可能位置所示切片的质心)。使用这些位置不可能有重叠。

Image above shows the possible location of the anchors (centroids of the slices shown). With these positions it is impossible to have an overlap.

这个问题的复杂性是当标签(它们是水平的)靠近顶部或底部的饼图,他们更容易重叠,比当他们在饼图的右边或左边。

Adding complexity to the problem is the fact that when labels (they're horizontal) are close to the top or bottom of the pie, they are more easily overlapped, than when they are on the right or left of the pie.

有关如何处理此问题的任何想法吗?

Any ideas on how to approach this problem?

根据meetamit的建议,以下:

Following the suggestion of meetamit, I implemented the following:

.attr("dy", function(d)
{
    var c = arc.centroid(d);
        var x = c[0];
        var y = c[1];
        var h = Math.sqrt(x*x + y*y);
        var dy = y/h * obj.labelRadius; 
    dy=dy*fontSizeParam*.14/heightParam);
    return (dy)+"em";
})

它有点帮助,给标签一些空间, 。

It helps a bit, and gives some room to the labels, still looking for a solution that will cover all cases though...

推荐答案

有一个好的,务实的 d3.js - 程序员约翰·威廉姆斯在这里提出的解决方案:

There is a good, pragmatic d3.js-based solution by programmer John Williams presented here:

https://www.safaribooksonline .com / blog / 2014/03/11 / solving-d3-label-placement-constraint-relaxing /

限制,例如最多12个标签,如上所述。文章中还有更多高级算法的指针,但是这种简单的方法实际上在使用足够的标签内容约束时,给出的结果比其他方法产生的视觉外观更有序。

It should work well for cases with reasonable restrictions, e.g. a maximum of 12 labels as discussed above. There are also pointers in the article to more advanced algorithms, but this simple approach may actually, when used with sufficient label-content constraints, give results that have a more orderly visual appearance than other methods would yield.

这篇关于d3js在饼图周围重新分布标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆