簡體   English   中英

d3js在餅圖周圍重新分發標簽

[英]d3js Redistributing labels around a pie chart

我正在使用d3.js創建一個帶有外部標簽的圓環圖。 使用基於餅圖的每個切片的質心的一些三角法,我定位標簽。

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+"%"; });

我最終要完成的是重新排列餅圖邊緣之外的標簽,以防止重疊。

在此輸入圖像描述

我試圖解決問題的方法之一是定義設置“錨點”,其中可以定位標簽,保證它們不會重疊。 問題是將質心映射到錨點並保留切片和標簽之間的一些視覺對應感(當切片很細時特別困難)。

在此輸入圖像描述

上圖顯示了錨點的可能位置(所示切片的質心)。 有了這些位置,就不可能有重疊。

增加問題的復雜性的事實是,當標簽(它們是水平的)靠近餅的頂部或底部時,它們比在餅的右側或左側更容易重疊。

關於如何解決這個問題的任何想法?

[編輯]根據meetamit的建議,我實施了以下內容:

.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";
})

它有點幫助,並為標簽提供了一些空間,仍在尋找能夠覆蓋所有情況的解決方案......

你不能創建兩個弧嗎? 一個用於圖表,一個用於標簽?

// first arc used for drawing the pie chart
var arc = d3.svg.arc()
  .outerRadius(radius - 10)
  .innerRadius(0);

// label attached to first arc
g.append("text")
  .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
  .attr("dy", ".35em")
  .style("text-anchor", "middle")
  .text(function(d) { return d.data.age; });

// second arc for labels
var arc2 = d3.svg.arc()
  .outerRadius(radius + 20)
  .innerRadius(radius + 20);

// label attached to second arc
g.append("text")
  .attr("transform", function(d) { return "translate(" + arc2.centroid(d) + ")"; })
  .attr("dy", ".35em")
  .style("text-anchor", "middle")
  .text(function(d) { return d.data.age; });

程序員John Williams在這里提出了一個基於d3.js的良好,實用的解決方案:

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

它應該適用於具有合理限制的情況,例如,如上所述最多12個標簽。 本文還提供了更高級算法的指針,但實際上,當使用足夠的標簽內容約束時,這種簡單方法可以提供比其他方法產生的結果更有序的視覺效果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM