Javascript D3js强制布局销毁和重置
基于两个D3示例:Force layout()和clustered Force layout(),我成功构建了一个带有几个独立重力点的Force布局,以控制节点之间链接顶部的节点位置Javascript D3js强制布局销毁和重置,javascript,performance,svg,d3.js,force-layout,Javascript,Performance,Svg,D3.js,Force Layout,基于两个D3示例:Force layout()和clustered Force layout(),我成功构建了一个带有几个独立重力点的Force布局,以控制节点之间链接顶部的节点位置 // Set up map function map_init(){ force = d3.layout.force() .nodes(nodes) .links(links) .size([width, height]) .on("tick
// Set up map
function map_init(){
force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.on("tick", tick);
svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
link = $map.selectAll(".link");
node = $map.selectAll(".node");
d3.json("graph.json", function(error, graph) {
// set up nodes
for( i = 0; i < graph.nodes.length; i++ ){
nodes.push( graph.nodes[i] );
}
// position nodes to three different gravity centres based on theme
for( i = 0; i < nodes.length; i++ ){
if ( nodes[i].theme == "theme1" ){
nodes[i].cx = 100;
nodes[i].cy = 100;
} else if ( nodes[i].theme == "theme2" ){
nodes[i].cx = 300;
nodes[i].cy = 300;
} else if ( nodes[i].theme == "theme3" ){
nodes[i].cx = 500;
nodes[i].cy = 500;
}
}
// link nodes of the same theme
theme1_nodes = nodes.filter(function(d){ return (d.theme == "theme1"); });
theme2_nodes = nodes.filter(function(d){ return (d.theme == "theme2"); });
theme3_nodes = nodes.filter(function(d){ return (d.theme == "theme3"); });
for (i = 0; i < theme1_nodes.length-1; i++){
links.push({ source: theme1_nodes[i], target: theme1_nodes[i+1] });
}
for (i = 0; i < theme2_nodes.length-1; i++){
links.push({ source: theme2_nodes[i], target: theme2_nodes[i+1] });
}
for (i = 0; i < theme3_nodes.length-1; i++){
links.push({ source: theme3_nodes[i], target: theme3_nodes[i+1] });
}
start();
});
}
// Start
function start() {
link = link.data(force.links(), function(d) { return d.source.id + "-" + d.target.id; });
link.enter()
.insert("svg:line")
.attr("class", "link");
link.exit()
.remove();
node = node.data(force.nodes(), function(d) { return d.id; });
var nodeEnter = node.enter()
.append("svg:g")
.attr("class", "node");
.on("click", map_nodeClick);
node.exit().remove();
// Enter node information
nodeEnter.each(function(d) {
theTitle = d3.select(this).append("svg:text")
.attr("font-family", "Helvetica")
.attr("class", "title")
.text( d.title );
});
// More content to go into each node
// .
// .
// .
force.start();
}
// Tick
function tick(e) {
node
.each(gravity(.2 * e.alpha))
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
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; });
}
// Gravity
function gravity(alpha) {
return function(d) {
d.y += (d.cy - d.y) * alpha;
d.x += (d.cx - d.x) * alpha;
};
}
// Set up when page first loads
map_init();
此网页显示在可供一组人访问的设备上。早上只加载一次,在iPad Safari上运行了12个小时。理想情况下,节点之间的链接会根据用户输入动态变化(待实现)。除了警队的布局外,网页上还有其他信息。需要在不重新加载页面的情况下重新启动/重置强制布局的选项
节点
和链接
指定给了force布局。更改这些名称所指向的内容(即,[]
)不会更改force布局中的引用。也就是说,数据对象仍然存在并被引用。有两种方法可以删除它们。您可以在位修改节点
和链接
(例如使用.slice()
),或在强制布局中显式重置它们
节点=[];
链接=[];
力节点(节点);
强制链接(links)代码>
nodeCircles = {};
node.remove();
link.remove();
svg.clear();
nodes = [];
links = [];
只需将其放入一个方法中,然后重新创建force和svg。非常好。很抱歉,我对“…就地(例如使用.slice())…”有点困惑。”。这应该是
splice()
?您可以同时使用这两个选项,具体取决于您想要做什么。
nodeCircles = {};
node.remove();
link.remove();
svg.clear();
nodes = [];
links = [];