2017-06-08 63 views
1

我使用Andrew的d3和絃圖示例,並希望將所有文本標籤居中在曲面切片內。我嘗試了很多東西,但永遠無法將文本居中。你知道需要什麼wizzard技巧嗎?d3和絃:圓上的中心文字

enter image description here

var width = 720, 
height = 720, 
outerRadius = Math.min(width, height)/2 - 10, 
innerRadius = outerRadius - 24; 

var formatPercent = d3.format(".1%"); 

var arc = d3.svg.arc() 
.innerRadius(innerRadius) 
.outerRadius(outerRadius); 

var layout = d3.layout.chord() 
.padding(.04) 
.sortSubgroups(d3.descending) 
.sortChords(d3.ascending); 

var path = d3.svg.chord() 
.radius(innerRadius); 

var svg = d3.select("body").append("svg") 
.attr("width", width) 
.attr("height", height) 
.append("g") 
.attr("id", "circle") 
.attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

svg.append("circle") 
.attr("r", outerRadius); 

d3.csv("ex_csv.csv", function(cities) { 
d3.json("ex_json.json", function(matrix) { 

// Compute the chord layout. 
layout.matrix(matrix); 

// Add a group per neighborhood. 
var group = svg.selectAll(".group") 
.data(layout.groups) 
.enter().append("g") 
.attr("class", "group") 
.on("mouseover", mouseover); 


// Add the group arc. 
var groupPath = group.append("path") 
.attr("id", function(d, i) { return "group" + i; }) 
.attr("d", arc) 
.style("fill", function(d, i) { return cities[i].color; }); 

// Add a text label. 
var groupText = group.append("text") 
.attr("x", 6) 
.attr("dy", 15); 

groupText.append("textPath") 
.attr("xlink:href", function(d, i) { return "#group" + i; }) 
.text(function(d, i) { return cities[i].name; }); 

// Remove the labels that don't fit. :(
groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength()/2 - 16 < this.getComputedTextLength(); }) 
.remove(); 

// Add the chords. 
var chord = svg.selectAll(".chord") 
.data(layout.chords) 
.enter().append("path") 
.attr("class", "chord") 
.style("fill", function(d) { return cities[d.source.index].color; }) 
.attr("d", path); 


} 
}); 
}); 

</script> 

回答

3

順便說一句,我建議希望升級到V4,對V2文檔幾乎是不存在的,是很難幫助。

您可以同時設置text-anchorstartOffset屬性以實現您要查找的內容。

首先,您需要將text-anchor設置爲middle,因爲指定中間點比找到中間點更容易,然後返回找到文本的起始位置。

其次,您需要設置一個startOffset。請注意,如果您使用50%,文本將不會出現在您想要的位置,因爲文本路徑的總長度是您要追加的閉環(和絃錨)的所有邊。如果你沒有不同的外徑和內徑,將其設置爲25%將起作用。但是,當你有一個外半徑大於內半徑更大的24個像素,你可以嘗試這樣的事情來計算的像素數,你需要以抵消文本的中心:

groupText.append("textPath") 
.attr("xlink:href", function(d, i) { return "#group" + i; }) 
.text(function(d, i) { return cities[i].name; }) 
.attr("startOffset",function(d,i) { return (groupPath[0][i].getTotalLength() - 48)/4 }) 
.style("text-anchor","middle"); 

我減去48,因爲錨的兩側各有24個像素(半徑上的差異)。我除以四分之一,因爲路徑本身加倍。如果這是一條總路線,我只會將其分成兩部分。

這種方法有點簡單,因爲外圓周不同於每個弦錨的內圓周,所以我稍微偏離了一點,但它應該是可行的。

對於正在顯示的尖端的標籤,這將變得非常笨拙:內半徑較短,因此如果字符串足夠短以便顯示可能會導致出現錯誤的公式 - 這可能會導致某些字符爬上錨的一側(你的例子也是16像素的半徑差,以計算文本是否過長,而不是24)。

這是最終的結果:

enter image description here

Here是一個演示。