2015-06-04 18 views
3

我想顯示小切片(chart.minAngleForLabel(0.05))的標籤以避免文本重疊。如何在dc.js餅圖上定位標籤?

我添加了朝向外邊緣移動一個標籤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

但它會引起惱人的過渡 - 標籤向質心移動,然後跳回。有沒有解決方法?

回答

4

我的解決辦法是有點過分,但我想知道,如果它現在可以替換轉變立場,在now that we have the pretransition event 2.0 dc.js公測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) + ')'; 
      }) 
     }); 

這裏最大的想法是,如果你指定一個元素的新轉變,它將取代過渡那已經很活躍了。所以我們完全消除原來的位置和轉換,並用我們自己的替換它。沒有「跳躍」!

+0

感謝您添加新活動! 使標籤佈局更加靈活的方法之一是允許'_externalLabelRadius'成爲一個函數(在'labelPosition()')中。我認爲負面的'_externalLabelRadius'可能會被濫用來設置內部半徑。只是一個想法。 – marcin

+0

啊,這是一個好主意。我也在考慮一個標籤位置調整器,以幫助您改變原來的計算位置,但是您所建議的可能會更有幫助。 – Gordon

+0

討論/解決方案的新增問題:https://github.com/dc-js/dc.js/issues/945 – Gordon

2

沒有真正解決您的問題,但可能看起來更好的位置過渡?

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

'延遲'是不好的,但有了額外的轉換,它確實看起來更好。其實很滑稽 - 標籤走向中央,彼此碰撞然後展開。 – marcin