基於兩個D3示例:強制佈局(http://bl.ocks.org/mbostock/1095795)和集羣強制佈局(http://bl.ocks.org/mbostock/1748247),我設法建立了具有幾個獨立重力的力佈局,以控制節點位於頂部的節點之間的鏈接。D3js強制佈局破壞並重置
// 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();
爲了重置/隨時重啓力佈局無需重新加載頁面,我勢必以下功能復位按鈕:
// Remove force layout and data
function map_remove(){
node.remove();
link.remove();
svg.remove();
nodes = [];
links = [];
}
// Reset button
$('a#reset').click(function(e){
e.preventDefault();
map_remove();
map_init();
});
該網頁顯示由組訪問的設備上人。只在早上加載一次,然後在iPad Safari上運行12個小時。理想情況下,節點之間的鏈接根據用戶輸入(要實施)動態變化。除了強制佈局外,網頁上還有其他信息。需要重新啓動/重置強制佈局而不重新加載頁面的選項。
- 是否有內置的方法來破壞D3強制佈局及其數據?
- 目前這工作正常,因爲沒有額外的DOM元素被創建,並沒有從檢查員發現錯誤。但是我不確定如何檢查所有D3對象是否已被清空/清空,因此沒有重複數據被存儲/累積?
- 由於某些原因,目前每次重置都會將節點拉近和靠近地圖中心。我錯過了map_remove()函數中的一些東西嗎?
- 完全重新啓動D3強制佈局可以在任何時候提高瀏覽器的性能嗎?即清理內存以繪製SVG?
對不起,我對於「...到位(例如.slice())...」有點困惑。 是應該'splice()'? – Carr
您可以同時使用這兩者,具體取決於您想要做什麼。 –