2013-04-01 127 views
2

我創建基於示例折線圖這裏找到:D3線圖標籤重疊

http://bl.ocks.org/mbostock/3884955

然而,我的數據線標籤(市)結束重疊,因爲在最終值不同線的y軸經常靠近在一起。我知道我需要比較每行的最後一個值,並在值相差12個單位或更少時向上或向下移動標籤。我的想法是看由該位的代碼

city.append("text") 
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; }) 
.attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.temperature) + ")"; }) 
.attr("x", 3) 
.attr("dy", ".35em") 
.text(function(d) { return d.name; }); 

書面文字標籤如果Y(d.value.temperature)值由12個或更少的不同,直到他們至少有移開值他們之間有12個單位。有關如何完成此任務的任何想法?這是我的第一個d3項目,語法仍然適合我!

回答

2

你可能會更好地傳遞所有的標籤 - 這也是更符合一般d3的想法。然後,您可以有代碼是這樣的:

svg.selectAll("text.label").data(data) 
    .enter() 
    .append("text") 
    .attr("transform", function(d, i) { 
     var currenty = y(d.value.temperature); 
     if(i > 0) { 
      var previousy = y(data[i-1].value.temperature), 
      if(currenty - previousy < 12) { currenty = previousy + 12; } 
     } 
     return "translate(" + x(d.value.date) + "," + currenty + ")"; 
    }) 
    .attr("x", 3) 
    .attr("dy", ".35em") 
    .text(function(d) { return d.name; }); 

這不解釋這個事實,以前的標籤可能已被移動。您可以明確地獲得前一個標籤的位置,並根據該標籤移動當前標籤的位置。代碼將幾乎相同,只不過您需要保存對當前元素的引用(this),以便稍後可以訪問它。

所有這些都不會阻止標籤與最終標註的標籤之間的距離可能很遠。如果你需要移動每一個標籤,最後一個將會很遠。更好的行動方式可能是單獨創建一個圖例,您可以根據需要在其中分隔標籤和線條。

+0

除非我失去了一些東西,相鄰線重疊,這只是檢查標籤。例如,如果第1行的標籤和第3行的標籤重疊,則不會使用此例程檢測並修復該標籤。請讓我知道,如果我誤解了這段代碼的作用。謝謝! –

+0

你是對的 - 這是考慮到以前的標籤的位置,而不是以前的數據點,但考慮到這一點。我的觀點是,如果您在標籤擺放方面遇到問題,那麼最好有一個單獨的圖例。 –

+0

好的點...感謝您讓我放心,我不會錯過簡單的事情。 –

1

考慮使用D3強制佈局來放置標籤。在這裏看到一個例子:https://bl.ocks.org/wdickerson/bd654e61f536dcef3736f41e0ad87786

假設你有一個value屬性包含對象data陣列和規模y

// Create some nodes 
const labels = data.map(d => { 
    return { 
    fx: 0, 
    targetY: y(d.value) 
    }; 
}); 

// Set up the force simulation 
const force = d3.forceSimulation() 
    .nodes(labels) 
    .force('collide', d3.forceCollide(10)) 
    .force('y', d3.forceY(d => d.targetY).strength(1))  
    .stop(); 

// Execute thte simulation 
for (let i = 0; i < 300; i++) force.tick(); 

// Assign values to the appropriate marker 
labels.sort((a, b) => a.y - b.y); 
data.sort((a, b) => b.value - a.value); 
data.forEach((d, i) => d.y = labels[i].y); 

現在你data陣列將有y屬性代表其最佳位置。

示例使用D3 4.0,在這裏閱讀更多:https://github.com/d3/d3-force