我想在下面的D3图中添加一些功能,以便在延迟1秒(即一次一个)之后添加每个链接及其相应的节点。有没有办法做到这一点?
数据来自一次加载的外部JSON文件(此处未显示)。在这里,我们假设JSON文件不会随着时间的推移而改变,所以如果我们在开始时解析一次JSON文件就足够了。
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
stroke: #ccc;
}
.node text {
pointer-events: none;
font: 10px sans-serif;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
//Constants for the SVG
var width = 2480,
height = 2880;
//Set up the colour scale
var color = d3.scale.category10();
//Set up the force layout
var force = d3.layout.force()
.charge(-100)
.linkDistance(300)
.size([width, height]);
//Append a SVG to the body of the html page. Assign this SVG as an object to svg
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
//Read the data from the mis element
d3.json("data.json", function(error, graph) {
force
.nodes(graph.nodes)
.links(graph.links)
.start();
//Create all the line svgs but without locations yet
var link = svg.selectAll(".link")
.data(graph.links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function (d) {
return Math.sqrt(d.value);
});
//Do the same with the circles for the nodes - no
//Changed
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag);
node.append("circle")
.attr("r", 8)
.style("fill", function (d) {
return color(d.group);
})
node.append("text")
.attr("dx", 10)
.attr("dy", ".35em")
.text(function(d) { return d.name });
//End changed
//Now we are giving the SVGs co-ordinates - the force layout is generating the co-ordinates which this code is using to update the attributes of the SVG elements
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;
});
//Changed
d3.selectAll("circle").attr("cx", function (d) {
return d.x;
})
.attr("cy", function (d) {
return d.y;
});
d3.selectAll("text").attr("x", function (d) {
return d.x;
})
.attr("y", function (d) {
return d.y;
});
//End Changed
});
});
</script>
答案 0 :(得分:4)
使用setTimeOut
方法。
graph.links.forEach(function(d, i) {
setTimeout(function() {
var nodes = graph.nodes.filter(function(n,i){
return d.source.index==i || d.target.index==i
});
nodes.forEach(function(node){
var nodeG = container.append("g")
.datum(node)
.attr("class", "node")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.call(drag);
nodeG.append("circle")
.attr("r", function(d) {
return d.weight * 2 + 12;
})
.style("fill", function(d) {
return color(1 / d.rating);
});
});
container.append("line")
.datum(d)
.attr("class", "link")
.style("stroke-width", function(d) {
return Math.sqrt(d.value);
});
force.resume(); //Restarts the force simulation.
}, 1000 * i);
});
另外不要忘记更新刻度函数,如下所示。
force.on("tick", function() {
container.selectAll(".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; });
container.selectAll(".node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
});