问题描述
有没有办法在D3强制导向图中禁用动画?
Is there any way of disabling the animation in a D3 force-directed graph?
我正在使用这个例子:
I am working with this example: https://bl.ocks.org/mbostock/4062045
我想要在没有初始动画的情况下渲染图形,即显示其最终位置中的所有节点和链接。
I want to render the graph without the initial animation, that is, showing all the nodes and links in their final positions.
推荐答案
编辑
此方法只隐藏模拟的动画部分。请参阅,在不绘制中间结果的情况下执行模拟,这意味着用户在解决方案缓慢发展的过程中不必等待。
This method simply hides the animation part of the simulation. Please see Gerardo Furtado's answer which performs the simulation without drawing the intermediary results, meaning that the user doesn't have to wait whilst the solution is slowly evolving.
========
'动画'实际上是模拟运行。可以使用模拟运行的时间,但这可能意味着节点陷入局部最小值 - 。
The 'animation' is actually the simulation running. It is possible to play with the time that the simulation runs but this might mean that the nodes get stuck at a local minimum - see the documentation here for more details.
您可以选择添加监听器结束
在模拟结束时触发的事件。我创建了一个片段,其中Graph最初是隐藏的,然后在完成模拟后出现。
You do have the option of adding a listener to the end
event which fires when the simulation has finished. I have created a snippet where the Graph is initially hidden and then appears once it has finished simulating.
另一种方法是渲染图表服务器端(如果这是一个选项),然后提供一个现成的SVG,可以用d3进一步操作。
An alternative would be to render the chart server-side (if this is an option) and then serve a ready-drawn SVG which could be further manipulated with d3.
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2))
.on('end', function() {
svg.classed('hidden', false)
d3.select('#loading').remove()
});
// I wasn't able to get the snippet to load the original data from https://bl.ocks.org/mbostock/raw/4062045/miserables.json so this is a copy hosted on glitch
d3.json("https://cdn.glitch.com/8e57a936-9a34-4e95-a03d-598e5738f44d%2Fmiserables.json", function(error, graph) {
if (error) {
console.log(error)
};
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(graph.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return color(d.group);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(graph.nodes)
.on("tick", ticked);
simulation.force("link")
.links(graph.links);
function ticked() {
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 dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
.hidden {
visibility: hidden
}
img {
display: block;
margin-left: auto;
margin-right: auto;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<img id ="loading" src="http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif" />
<svg width="960" height="600" class="hidden"></svg>
这篇关于如何在强制导向图中禁用动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!