-1
我是D3 js的新手。我想用d3繪製一個樹形結構。但是,我希望節點之間的路徑不像通常的對角線和投影方法那樣靈活。我需要的節點之間的連接是這樣的:在d3樹路徑中創建靈活鏈接
如何在D3這樣做呢?
這是我現在使用對角線的代碼。
<html>
<head>
<title> Box office </title>
</head>
<body>
<style>
.node {
\t \t cursor: pointer;
\t }
\t .node circle {
\t fill: #fff;
\t stroke: steelblue;
\t stroke-width: 3px;
\t }
\t .node text {
\t font: 12px sans-serif;
\t }
\t .link {
\t fill: none;
\t stroke: #ccc;
\t stroke-width: 2px;
\t }
</style>
<!-- load the d3.js library --> \t
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id = "boxoffice"></div>
<script type="text/javascript">
var sampleData = [
{
"ChangeFlowsFromParent": "false",
"ChangeFlowsToParent": "false",
"StreamType": "Mainline",
"streamName": "ArgOS_2_0",
"Parent": "none",
"Compliance": "Released",
"children": [
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_0_DHAL",
"Parent": "ArgOS_2_0",
"Compliance": "Released"
},
\t {
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_0_Dev",
"Parent": "ArgOS_2_0",
"Compliance": "Released",
"children": [
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Release",
"streamName": "r_ArgOS_0230",
"Parent": "ArgOS_2_0_Dev",
"Compliance": "Released"
},
\t \t {
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Release",
"streamName": "branch1",
"Parent": "ArgOS_2_0_Dev",
"Compliance": "Released",
\t \t \t "children": [
\t \t \t {
\t \t \t \t "ChangeFlowsFromParent": "true",
\t \t \t \t "ChangeFlowsToParent": "true",
\t \t \t \t "StreamType": "Release",
\t \t \t \t "streamName": "branch100",
\t \t \t \t "Parent": "branch1",
\t \t \t \t "Compliance": "Released"
\t \t \t },
\t \t \t {
\t \t \t \t "ChangeFlowsFromParent": "true",
\t \t \t \t "ChangeFlowsToParent": "true",
\t \t \t \t "StreamType": "Release",
\t \t \t \t "streamName": "branch200",
\t \t \t \t "Parent": "branch1",
\t \t \t \t "Compliance": "Released",
\t \t \t \t "children": [
\t \t \t \t {
\t \t \t \t \t "ChangeFlowsFromParent": "true",
\t \t \t \t \t "ChangeFlowsToParent": "true",
\t \t \t \t \t "StreamType": "Release",
\t \t \t \t \t "streamName": "honey",
\t \t \t \t \t "Parent": "branch200",
\t \t \t \t \t "Compliance": "Released"
\t \t \t \t }
\t \t \t \t ]
\t \t \t }
\t \t \t ]
}
]
},
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_0_IPC-Tracer",
"Parent": "ArgOS_2_0",
"Compliance": "Released",
\t \t \t "children": [
\t \t \t {
\t \t \t \t "ChangeFlowsFromParent": "true",
\t \t \t \t "ChangeFlowsToParent": "true",
\t \t \t \t "StreamType": "Release",
\t \t \t \t "streamName": "ArgOS_2_0_IPC_child 1",
\t \t \t \t "Parent": "ArgOS_2_0_IPC",
\t \t \t \t "Compliance": "Released"
\t \t \t },
\t \t \t {
\t \t \t \t "ChangeFlowsFromParent": "true",
\t \t \t \t "ChangeFlowsToParent": "true",
\t \t \t \t "StreamType": "Release",
\t \t \t \t "streamName": "ArgOS_2_0_IPC_child 2",
\t \t \t \t "Parent": "ArgOS_2_0_IPC",
\t \t \t \t "Compliance": "Released"
\t \t \t }
\t \t \t ]
},
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_0_NSW_Temp",
"Parent": "ArgOS_2_0",
"Compliance": "Released"
},
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_0_Test",
"Parent": "ArgOS_2_0",
"Compliance": "Released"
},
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "ArgOS_2_CBD",
"Parent": "ArgOS_2_0",
"Compliance": "Released"
},
{
"ChangeFlowsFromParent": "true",
"ChangeFlowsToParent": "true",
"StreamType": "Development",
"streamName": "test_mergewp",
"Parent": "ArgOS_2_0",
"Compliance": "Released"
}
]
}
]
var margin = {top:100, bottom: 100, left:100, right:100},
width = 1800 - margin.left-margin.right, //total width minus side margins
height = 1500 - margin.top - margin.bottom; //total height minus vertical margins
var tree = d3.layout.tree().size([width, height]);
tree.nodeSize([40,100]);
var diagonal = d3.svg.diagonal()
\t .projection(function(d) { return [d.x, -d.y]; });
\t
var svgContainer = d3.select("#boxoffice").append("svg").attr("width", width).attr("height", height).append("g").attr("transform", "translate(" + (width/2) + "," + (height - 500) + ")");
var root = sampleData[0];
root.x0 = width/2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style("height", "500px");
function update(sourceNode){
var nodes = tree.nodes(sourceNode).reverse(),
links = tree.links(nodes);
nodes.forEach(function(d){d.y = d.depth * 180});
var node = svgContainer.selectAll("g.node").attr("class", "node").data(nodes, function(d, i){return d.id || (d.id = ++i); });
var nodeEnter = node.enter().append("g")
\t \t \t \t \t \t \t .attr("transform", function(d) {
\t \t \t \t \t \t \t
\t \t \t \t \t \t \t <!-- if(d.StreamType == "Mainline") -->
\t \t \t \t \t \t \t \t <!-- return "translate(-100,-100)"; -->
\t \t \t \t \t \t \t <!-- else -->
\t \t \t \t \t \t \t \t return "translate(" + sourceNode.y0 + "," + sourceNode.x0 + ")";
\t \t \t \t \t \t \t \t \t \t \t \t \t \t
\t \t \t \t \t \t \t });
nodeEnter.append("circle")
\t \t .attr("r", 15)
\t \t .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
\t \t
\t \t nodeEnter.append("text")
\t .attr("x", function(d) { return d.children || d._children ? -13 : 13; })
\t .attr("dy", ".35em")
\t .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
\t .text(function(d) { return d.streamName; })
\t .style("fill-opacity", 1e-6);
\t
\t \t \t
var nodeUpdate = node.transition()
\t .duration(100)
\t .attr("transform", function(d) {
\t
\t if(d.StreamType == "Mainline")
\t {
\t \t \t var lastElement = nodes[0];
\t \t \t
\t \t return "translate(" + (lastElement.y + 100) + "," + (lastElement.x -130) + ")"; //adding the root element
\t \t }
\t else
\t \t \t return "translate(" + d.y + "," + (d.x-(margin.top + margin.bottom)) + ")";
\t });
nodeUpdate.select("circle")
\t .attr("r", 10)
\t .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
nodeUpdate.select("text")
\t .style("fill-opacity", 1);
var link = svgContainer.selectAll("path.link")
\t .data(links, function(d) { return d.target.id; });
\t
link.enter().insert("path", "g")
.attr("class", "link")
.attr("d", function(d) {
\t var o = {x: sourceNode.x0, y: sourceNode.y0};
\t return diagonal({source: o, target: o});
});
// Transition links to their new position.
link.transition()
\t .duration(10)
\t .attr("d", diagonal);
\t \t
\t
nodes.forEach(function(d) {
\t d.x0 = d.x;
\t d.y0 = d.y;
});
\t
}
function positionLink(d) {
return "M" + d[0].x + "," + d[0].y
+ "S" + d[1].x + "," + d[1].y
+ " " + d[2].x + "," + d[2].y;
}
</script>
</body>
</html>
本規範的鏈接都是凌亂。我可以整理對角線路徑鏈接,但我希望我的鏈接具有動態性和靈活性。我怎樣才能做到這一點?
靈活,我的意思是鏈接需要像圖片中的線條(沒有對角線,沒有投影,沒有直線 - 到處都是我想要的曲線)。我嘗試使用d3.linkHorizontal() - 我得到腳本錯誤,說d3.linkHorizontal()不是一個函數。互聯網上也沒有太多的幫助。 – Ponni
linkHorizontal附帶更新版本的d3 v4(https://github.com/d3/d3/releases/tag/v4.9.0) –
如果我參考版本4,它說d3沒有定義。 – Ponni