我使用强制布局算法绘制图形。但我希望用户能够禁用强制布局算法并能够移动节点。我遵循示例here(P用于固定)作为构建我的代码的基础。
但是,我希望用户能够理解基于力的算法之美,因此只有在用户按下按钮后才能启用拖动和固定"使拖拽"。
以下是我正在使用的代码......
<!DOCTYPE html>
<html lang="en">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<head>
<meta charset="UTF-8">
<title>Spatial Social Network</title>
<script src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
<h1>The network</h1>
<script>
var width = 500,
height = 500;
var color = d3.scale.category20();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.size([width, height]);
/*Drag and pin*/
var node_drag = d3.behavior.drag()
.on("dragstart", dragstart)
.on("drag", dragmove)
.on("dragend", dragend);
function dragstart(d, i) {
alert("I am here");
force.stop() // stops the force auto positioning before you start dragging
}
function dragmove(d, i) {
d.px += d3.event.dx;
d.py += d3.event.dy;
d.x += d3.event.dx;
d.y += d3.event.dy;
}
function dragend(d, i) {
d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
force.resume();
}
function releasenode(d) {
d.fixed = false; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
//force.resume();
}
/*Drag and pin*/
svg.append('text')
.attr("x", 2)
.attr("y", 20)
.text("Force Layout")
.attr("font-family", "sans-serif")
.attr("font-size", "20px")
.attr("fill", "red");
d3.json("jsonGraph.json", function(error, graph) {
if (error) throw error;
//console.log(graph.nodes);
force
.nodes(graph.nodes)
.links(graph.links)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.class); })
.call(force.drag);
node.append("title")
.text(function(d) { return d.id; });
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
});
function MakeDraggable()
{
alert("here");
d3.json("jsonGraph.json", function(error, graph) {
if (error) throw error;
force
.nodes(null)
.links(null)
.start();
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link");
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
.attr("class", "node")
.attr("r", 5)
.style("fill", function(d) { return color(d.class); })
//.call(force.drag);
.call(node_drag)
.on('dblclick', releasenode);
//force.stop();
});
}
</script>
<input type="button" name="MakeDraggable" value="Make Draggable!" onClick="MakeDraggable()"></input>
</body>
</html>
不幸的是,即使在按下按钮后,行为似乎也没有任何改变&#34; Make Draggable!&#34;。
这是我用来阅读图表的json文件:
{
"directed": false,
"graph": {
"name": "Fun Graph"
},
"nodes": [
{
"class": "A",
"id": "A"
},
{
"class": "B",
"id": "C"
},
{
"class": "B",
"id": "B"
},
{
"class": "B",
"id": "E"
},
{
"class": "B",
"id": "D"
},
{
"class": "A",
"id": "G"
},
{
"class": "B",
"id": "F"
},
{
"class": "A",
"id": "I"
},
{
"class": "B",
"id": "H"
},
{
"class": "A",
"id": "K"
},
{
"class": "B",
"id": "J"
},
{
"class": "B",
"id": "M"
},
{
"class": "A",
"id": "L"
},
{
"class": "A",
"id": "O"
},
{
"class": "A",
"id": "N"
}
],
"links": [
{
"source": 0,
"target": 8
},
{
"source": 0,
"target": 9
},
{
"source": 0,
"target": 2
},
{
"source": 0,
"target": 11
},
{
"source": 0,
"target": 4
},
{
"source": 1,
"target": 7
},
{
"source": 1,
"target": 11
},
{
"source": 2,
"target": 11
},
{
"source": 2,
"target": 12
},
{
"source": 3,
"target": 4
},
{
"source": 3,
"target": 5
},
{
"source": 3,
"target": 6
},
{
"source": 4,
"target": 7
},
{
"source": 4,
"target": 11
},
{
"source": 4,
"target": 12
},
{
"source": 5,
"target": 7
},
{
"source": 5,
"target": 8
},
{
"source": 6,
"target": 11
},
{
"source": 6,
"target": 12
},
{
"source": 7,
"target": 13
},
{
"source": 7,
"target": 8
},
{
"source": 9,
"target": 14
},
{
"source": 10,
"target": 11
},
{
"source": 10,
"target": 14
},
{
"source": 12,
"target": 13
}
],
"multigraph": false
}
我是D3的新手,不知道我哪里出错了。
[1]: http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/
答案 0 :(得分:2)
单击按钮,您无需重新创建/重新加载完整的力布局:
function MakeDraggable()
{
alert("here");
d3.json("jsonGraph.json", function(error, graph) {
if (error) throw error;
force
.nodes(null)
.links(null)
.start();
这可以通过以下方式完成:
function MakeDraggable() {
svg.selectAll(".node").call(node_drag);//attach the drag behavior
}
工作演示here
希望这有帮助!