javascript 不使用强制布局的节点和链接的简单图形
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28102089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple graph of nodes and links without using force layout
提问by brno792
How can I make a basic connected graph (two nodes and a link connecting them for example) that doesn't use a force()
layout? I just want to be able to drag a node and have the link adjust to stay connected as a node is being dragged. I dont want any of the charge or positioning capabilities of force()
. Essentially I want every node to be "sticky". Nodes will only move when being dragged.
如何制作不使用force()
布局的基本连接图(例如,两个节点和连接它们的链接)?我只是希望能够拖动节点并在拖动节点时调整链接以保持连接。我不想要任何充电或定位功能force()
。基本上我希望每个节点都是“粘性的”。节点只会在被拖动时移动。
But is there a simple way to do this? Every example I have seen is built around a force directed graph.
但是有没有一种简单的方法可以做到这一点?我见过的每个例子都是围绕力有向图构建的。
I've looked at this example, http://bl.ocks.org/mbostock/3750558, but it starts with a force directed graph then makes the nodes sticky. This approach seems backwards for what I want.
我看过这个例子,http://bl.ocks.org/mbostock/3750558,但它从一个力有向图开始,然后使节点变得粘滞。这种方法似乎与我想要的相反。
Is there a basic example somewhere?
某处有一个基本的例子吗?
回答by Gilsha
I have made a small code snippet. Hope this helpful.
我做了一个小代码片段。希望这有帮助。
var data = {
nodes: [{
name: "A",
x: 200,
y: 150
}, {
name: "B",
x: 140,
y: 300
}, {
name: "C",
x: 300,
y: 300
}, {
name: "D",
x: 300,
y: 180
}],
links: [{
source: 0,
target: 1
}, {
source: 1,
target: 2
}, {
source: 2,
target: 3
}, ]
};
var c10 = d3.scale.category10();
var svg = d3.select("body")
.append("svg")
.attr("width", 1200)
.attr("height", 800);
var drag = d3.behavior.drag()
.on("drag", function(d, i) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this).attr("cx", d.x).attr("cy", d.y);
links.each(function(l, li) {
if (l.source == i) {
d3.select(this).attr("x1", d.x).attr("y1", d.y);
} else if (l.target == i) {
d3.select(this).attr("x2", d.x).attr("y2", d.y);
}
});
});
var links = svg.selectAll("link")
.data(data.links)
.enter()
.append("line")
.attr("class", "link")
.attr("x1", function(l) {
var sourceNode = data.nodes.filter(function(d, i) {
return i == l.source
})[0];
d3.select(this).attr("y1", sourceNode.y);
return sourceNode.x
})
.attr("x2", function(l) {
var targetNode = data.nodes.filter(function(d, i) {
return i == l.target
})[0];
d3.select(this).attr("y2", targetNode.y);
return targetNode.x
})
.attr("fill", "none")
.attr("stroke", "white");
var nodes = svg.selectAll("node")
.data(data.nodes)
.enter()
.append("circle")
.attr("class", "node")
.attr("cx", function(d) {
return d.x
})
.attr("cy", function(d) {
return d.y
})
.attr("r", 15)
.attr("fill", function(d, i) {
return c10(i);
})
.call(drag);
svg {
background-color: grey;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
回答by zero_length_whitespace
Gilsha has a great answer, but note that newer versions of d3 no longer use the behavior module.
Gilsha 有一个很好的答案,但请注意,较新版本的 d3 不再使用行为模块。
Instead of this:
取而代之的是:
var drag = d3.behavior.drag()
.on("drag", function(d, i) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this).attr("cx", d.x).attr("cy", d.y);
links.each(function(l, li) {
if (l.source == i) {
d3.select(this).attr("x1", d.x).attr("y1", d.y);
} else if (l.target == i) {
d3.select(this).attr("x2", d.x).attr("y2", d.y);
}
});
});
Simply change d3.behavior.drag() to d3.drag()
只需将 d3.behavior.drag() 更改为 d3.drag()
var drag = d3.drag()
.on("drag", function(d, i) {
d.x += d3.event.dx
d.y += d3.event.dy
d3.select(this).attr("cx", d.x).attr("cy", d.y);
links.each(function(l, li) {
if (l.source == i) {
d3.select(this).attr("x1", d.x).attr("y1", d.y);
} else if (l.target == i) {
d3.select(this).attr("x2", d.x).attr("y2", d.y);
}
});
});