1
我正在關注this tutorial以生成雙樹並將肘形連接器轉換爲對角連接器。 這是我試過的在d3 js雙樹中單獨鏈接鏈接
截至目前,應該走向左邊的邊也朝着正確的方向走,我該如何將這些邊翻轉到左邊。
我試着替換nodes.forEach
函數如下。在第二種情況下,鏈接被翻轉,但節點從右向左移動。
nodes.forEach(function(d) {
if(d.isRight)
{
d.y = d.depth * 180 + halfWidth;
}
else
{
d.y = width - (d.depth * 180 + halfWidth);
}
});
沒有工作。任何幫助表示讚賞。
var margin = {
top: 30,
right: 10,
bottom: 10,
left: 10
},
width = 960 - margin.left - margin.right,
halfWidth = width/2,
height = 500 - margin.top - margin.bottom,
i = 0,
duration = 500,
root;
var getChildren = function(d) {
var a = [];
if (d.winners)
for (var i = 0; i < d.winners.length; i++) {
d.winners[i].isRight = false;
d.winners[i].parent = d;
a.push(d.winners[i]);
}
if (d.challengers)
for (var i = 0; i < d.challengers.length; i++) {
d.challengers[i].isRight = true;
d.challengers[i].parent = d;
a.push(d.challengers[i]);
}
return a.length ? a : null;
};
var tree = d3.layout.tree()
.size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function(d) {
return [d.y, d.x];
});
var connector = diagonal;
var calcLeft = function(d) {
var l = d.y;
if (!d.isRight) {
l = d.y - halfWidth;
l = halfWidth - l;
}
return {
x: d.x,
y: l
};
};
var vis = d3.select("#chart").append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
setTimeout(function() {
var json = {
"name": "Overall Winner",
"winners": [{
"name": "Winner Left 1",
"winners": [{
"name": "Winner Left 3"
}, {
"name": "Winner Left 4"
}]
}, {
"name": "Winner Left 2"
}],
"challengers": [{
"name": "Challenger Right 1",
"challengers": [{
"name": "Challenger Right 3"
}, {
"name": "Challenger Right 4"
}]
}, {
"name": "Challenger Right 2",
"challengers": [{
"name": "Challenger Right 5"
}, {
"name": "Challenger Right 6"
}]
}]
};
root = json;
root.x0 = height/2;
root.y0 = width/2;
var t1 = d3.layout.tree().size([height, halfWidth]).children(function(d) {
return d.winners;
}),
t2 = d3.layout.tree().size([height, halfWidth]).children(function(d) {
return d.challengers;
});
t1.nodes(root);
t2.nodes(root);
var rebuildChildren = function(node) {
node.children = getChildren(node);
if (node.children) node.children.forEach(rebuildChildren);
}
rebuildChildren(root);
root.isRight = false;
update(root);
});
var toArray = function(item, arr, d) {
arr = arr || [];
var dr = d || 1;
var i = 0,
l = item.children ? item.children.length : 0;
arr.push(item);
if (item.position && item.position === 'left') {
dr = -1;
}
item.y = dr * item.y;
for (; i < l; i++) {
toArray(item.children[i], arr, dr);
}
return arr;
};
function update(source) {
// Compute the new tree layout.
var nodes = toArray(source);
// Normalize for fixed-depth.
nodes.forEach(function(d) {
d.y = d.depth * 180 + halfWidth;
});
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + source.y0 + "," + source.x0 + ")";
})
.on("click", click);
nodeEnter.append("circle")
.attr("r", 1e-6)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeEnter.append("text")
.attr("dy", function(d) {
return d.isRight ? 14 : -8;
})
.attr("text-anchor", "middle")
.text(function(d) {
return d.name;
})
.style("fill-opacity", 1e-6);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
p = calcLeft(d);
return "translate(" + p.y + "," + p.x + ")";
});
nodeUpdate.select("circle")
.attr("r", 4.5)
.style("fill", function(d) {
return d._children ? "lightsteelblue" : "#fff";
});
nodeUpdate.select("text")
.style("fill-opacity", 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) {
p = calcLeft(d.parent || source);
return "translate(" + p.y + "," + p.x + ")";
})
.remove();
nodeExit.select("circle")
.attr("r", 1e-6);
nodeExit.select("text")
.style("fill-opacity", 1e-6);
// Update the links...
var link = vis.selectAll("path.link")
.data(tree.links(nodes), function(d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {
x: source.x0,
y: source.y0
};
return connector({
source: o,
target: o
});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", connector);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = calcLeft(d.source || source);
if (d.source.isRight) o.y -= halfWidth - (d.target.y - d.source.y);
else o.y += halfWidth - (d.target.y - d.source.y);
return connector({
source: o,
target: o
});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
var p = calcLeft(d);
d.x0 = p.x;
d.y0 = p.y;
});
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(source);
}
}
.node circle {
cursor: pointer;
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node text {
font: 10px sans-serif;
}
path.link {
fill: none;
stroke: #ccc;
stroke-width: 1.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
我想與大家分享一些東西的思想http://plnkr.co/edit/Ixnq1vkzxNx379deFF1T?p=preview可能是你可以通過它即興.. – Cyril
感謝您的幫助,即使我這麼長時間擺弄它。有沒有辦法使用兩個單獨的'd.y'值來繪製節點和邊緣。所以我可以使用默認的'd.y = d.depth * 180 + halfWidth;'爲節點和'd.y = width - (d.depth * 180 + halfWidth);'爲邊緣? –
其實我試圖用對角線連接器做到這一點,它不工作。 –