所以,下面的方法可以給不同層次的佈局提供不同的「高度」,你必須謹慎使用徑向佈局,否則你的風險不足以傳播給小圈子文字沒有重疊,但我們暫時忽略它
關鍵是要認識到樹佈局只是簡單地將事物映射到任意寬度和高度的空間,並且對角線投影將寬度(x)映射到角度和高度(y)到半徑。此外,半徑是樹的深度的簡單函數。
所以here是重新分配基於文本的長度深處方式:
首先,我用下面(jQuery的)來計算最大文本尺寸:
var computeMaxTextSize = function(data, fontSize, fontName){
var maxH = 0, maxW = 0;
var div = document.createElement('div');
document.body.appendChild(div);
$(div).css({
position: 'absolute',
left: -1000,
top: -1000,
display: 'none',
margin:0,
padding:0
});
$(div).css("font", fontSize + 'px '+fontName);
data.forEach(function(d) {
$(div).html(d);
maxH = Math.max(maxH, $(div).outerHeight());
maxW = Math.max(maxW, $(div).outerWidth());
});
$(div).remove();
return {maxH: maxH, maxW: maxW};
}
現在我將遞歸地用每個級別的字符串數組構建一個數組:
var allStrings = [[]];
var childStrings = function(level, n) {
var a = allStrings[level];
a.push(n.name);
if(n.children && n.children.length > 0) {
if(!allStrings[level+1]) {
allStrings[level+1] = [];
}
n.children.forEach(function(d) {
childStrings(level + 1, d);
});
}
};
childStrings(0, root);
然後計算每個級別的最大文本長度。
var maxLevelSizes = [];
allStrings.forEach(function(d, i) {
maxLevelSizes.push(computeMaxTextSize(allStrings[i], '10', 'sans-serif'));
});
然後我計算所有級別的總文本寬度(爲小圓圈圖標添加間距和使其看起來不錯)。這將是最終佈局的半徑。請注意,稍後我會再使用相同的填充量。
var padding = 25; // Width of the blue circle plus some spacing
var totalRadius = d3.sum(maxLevelSizes, function(d) { return d.maxW + padding});
var diameter = totalRadius * 2; // was 960;
var tree = d3.layout.tree()
.size([360, totalRadius])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2)/a.depth; });
現在我們可以像往常一樣調用佈局。還有一件事:爲了找出不同級別的半徑,我們需要先前級別半徑的累計和。一旦我們有了,我們只需將新半徑分配給計算節點。
// Compute cummulative sums - these will be the ring radii
var newDepths = maxLevelSizes.reduce(function(prev, curr, index) {
prev.push(prev[index] + curr.maxW + padding);
return prev;
},[0]);
var nodes = tree.nodes(root);
// Assign new radius based on depth
nodes.forEach(function(d) {
d.y = newDepths[d.depth];
});
呃瞧!這可能不是最乾淨的解決方案,也許不能解決每一個問題,但它應該讓你開始。玩的開心!
哇,對不起,它花了這麼長的時間來回應,但我直到現在纔看到。最後,我從來沒有最終解決這個問題,但感謝您的回答。我會看看是否可以找到舊代碼並嘗試解決問題。 – alengel