我需要在力导向图中的节点之间绘制一些链接,但我希望这些链接不影响图的物理性质。还有其他可以影响物理的链接。
在所附的示例中,我想绘制定义为“ links2”的链接,但仅“遵循”该图的其余部分的布局。我希望这些线可以作为模拟的一部分进行动画处理,但不影响最终图形。
我已经手动绘制了最终结果的样子。
我不知道如何单独引用属于力布局的节点。
var nodes = [
{ name: "node0" },
{ name: "node1" },
{ name: "node2" },
{ name: "node3" },
{ name: "node4" },
{ name: "node5" },
{ name: "node6" },
{ name: "node7" },
{ name: "node8" },
{ name: "node9" },
{ name: "node10" },
{ name: "node11" },
{ name: "node12" },
{ name: "node13" },
{ name: "node14" },
{ name: "node15" },
{ name: "node16" },
{ name: "node17" },
{ name: "node18" },
{ name: "node19" }
];
var links = [
{ source: 0, target: 9 },
{ source: 1, target: 9 },
{ source: 2, target: 9 },
{ source: 3, target: 9 },
{ source: 4, target: 9 },
{ source: 5, target: 9 },
{ source: 6, target: 9 },
{ source: 7, target: 9 },
{ source: 8, target: 9 },
{ source: 10, target: 19 },
{ source: 11, target: 19 },
{ source: 12, target: 19 },
{ source: 13, target: 19 },
{ source: 14, target: 19 },
{ source: 15, target: 19 },
{ source: 16, target: 19 },
{ source: 17, target: 19 },
{ source: 18, target: 19 }
];
var links2 = [
{ source: 0, target: 10 },
{ source: 1, target: 11 },
{ source: 2, target: 12 },
{ source: 3, target: 13 }
]
var width = 700;
var height = 300;
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkDistance(50)
.charge(-700)
.on("tick", tick)
.start();
var svg = d3.select("#graph").append("svg")
.attr("width", width)
.attr("height", height);
var colors = d3.scale.category10();
var line = svg.append("g").selectAll("line")
.data(force.links())
.enter().append("line")
.attr('class', 'link')
.attr('stroke', function(d, i) {
return colors(i);
})
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 8)
.attr('class', 'circle')
.attr('fill', function(d, i) {
return colors(i);
})
.call(force.drag);
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 14)
.attr("y", ".31em")
.text(function(d) {
return d.name;
});
function tick() {
line.attr({
x1: function(d) {
return d.source.x;
},
y1: function(d) {
return d.source.y;
},
x2: function(d) {
return d.target.x;
},
y2: function(d) {
return d.target.y;
}
});
circle.attr("transform", transform);
text.attr("transform", transform);
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
.link {
fill: none;
stroke-width: 1.5px;
}
circle {
stroke: black;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
#graph {
position: absolute;
top: 0px;
left: 0px;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<div id="root">
<div style="background-color:lightgrey" id="graph" height="800px" width="800px">
</div>
</div>
</body>
非常感谢任何帮助。
答案 0 :(得分:1)
您的link2通过索引引用节点,因此在对勾中使用该索引在节点数组中进行索引。最好对不同类型的链接和节点使用类。
与强制无关的链接带有破折号。
var nodes = [
{ name: "node0" },
{ name: "node1" },
{ name: "node2" },
{ name: "node3" },
{ name: "node4" },
{ name: "node5" },
{ name: "node6" },
{ name: "node7" },
{ name: "node8" },
{ name: "node9" },
{ name: "node10" },
{ name: "node11" },
{ name: "node12" },
{ name: "node13" },
{ name: "node14" },
{ name: "node15" },
{ name: "node16" },
{ name: "node17" },
{ name: "node18" },
{ name: "node19" }
];
var links = [
{ source: 0, target: 9 },
{ source: 1, target: 9 },
{ source: 2, target: 9 },
{ source: 3, target: 9 },
{ source: 4, target: 9 },
{ source: 5, target: 9 },
{ source: 6, target: 9 },
{ source: 7, target: 9 },
{ source: 8, target: 9 },
{ source: 10, target: 19 },
{ source: 11, target: 19 },
{ source: 12, target: 19 },
{ source: 13, target: 19 },
{ source: 14, target: 19 },
{ source: 15, target: 19 },
{ source: 16, target: 19 },
{ source: 17, target: 19 },
{ source: 18, target: 19 }
];
var links2 = [
{ source: 0, target: 10 },
{ source: 1, target: 11 },
{ source: 2, target: 12 },
{ source: 3, target: 13 }
]
var width = 700;
var height = 300;
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkDistance(50)
.charge(-700)
.on("tick", tick)
.start();
var svg = d3.select("#graph").append("svg")
.attr("width", width)
.attr("height", height);
var colors = d3.scale.category10();
var line = svg.append("g").selectAll(".link")
.data(force.links())
.enter().append("line")
.attr('class', 'link')
.attr('stroke', function(d, i) { return colors(i); });
var line2 = svg.append("g").selectAll(".link2")
.data(links2)
.enter().append("line")
.attr('class', 'link2')
.attr('stroke-dasharray', '5,5')
.attr('stroke', function(d, i) { return colors(i); });
var circle = svg.append("g").selectAll(".circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 8)
.attr('class', 'circle')
.attr('fill', function(d, i) {
return colors(i);
})
.call(force.drag);
var text = svg.append("g").selectAll("text")
.data(force.nodes())
.enter().append("text")
.attr("x", 14)
.attr("y", ".31em")
.text(function(d) {
return d.name;
});
function tick() {
line.attr({
x1: function(d) { return d.source.x; },
y1: function(d) { return d.source.y; },
x2: function(d) { return d.target.x; },
y2: function(d) { return d.target.y; }
});
line2.attr({
x1: function(d) { return nodes[d.source].x; },
y1: function(d) { return nodes[d.source].y; },
x2: function(d) { return nodes[d.target].x; },
y2: function(d) { return nodes[d.target].y; }
});
circle.attr("transform", transform);
text.attr("transform", transform);
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
.link {
fill: none;
stroke-width: 1.5px;
}
circle {
stroke: black;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
pointer-events: none;
}
#graph {
position: absolute;
top: 0px;
left: 0px;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<div id="root">
<div style="background-color:lightgrey" id="graph" height="800px" width="800px">
</div>
</div>
</body>