我試圖將節點逐個添加到d3力仿真(在版本4中!),但有些仿真似乎並沒有在仿真後被仿真演變。d3 v4力量作用於動態添加的節點
目前模擬分配一個節點,那麼一個功能,ADDNODE被調用兩次增加兩個節點。每個都被添加到模擬中,有一個圓和一條線被渲染,並且有一個光標事件被逐個添加。
(技術上與第一和第二節點在同一時間內完成,如在第一僅設置當ADDNODE被稱爲第二)
然後,被點擊的節點時,一個新的節點,連接到光標下的那個,應該被創建。然後這個節點應該像其他任何模擬一樣在仿真的力量下進化。
然而,而一個或兩個節點似乎要創建精細,後來節點似乎並不模擬下有所發展。具體來說,應該在節點之間保持一定空間的多體力似乎不起作用。
我的直覺是,被在不合適的時間模擬的勾選功能添加的節點(早期問題解決了通過添加一些simulation.stop和simulation.restart命令正在添加新節點的任何時間),但在理論上,每當添加新的物體時,應該暫停模擬。
這是在d3 v4中動態添加節點的正確實現,還是強制突出顯示破壞方法的問題? This以前的答案幫助我意識到我需要合併新的條目,但部隊似乎在那裏工作得很好。
var w = 250;
var h = 250;
var svg = d3.select("body").append("svg");
svg.attr('width', w)
.attr('height', h);
// ensures links sit beneath nodes
svg.append("g").attr("id", "lnks")
svg.append("g").attr("id", "nds")
function new_node(id) {
this.id = id;
this.x = w/2;
this.y = h/2;
}
function new_link(source, target) {
this.source = source;
this.target = target;
}
var nodes = [];
var links = [];
var node;
var circles;
var link;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().distance(80).id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody().strength(-1000))
.force("xPos", d3.forceX(w/2))
.force("yPos", d3.forceY(h/2))
.on('tick', ticked);
simulation.stop();
var newNode = new new_node(0);
nodes.push(newNode);
for (var i = 1; i < 3; i++) {
if (i == 3) continue;
addNode(0, i)
}
function addNode(rootId, newId) {
var newNode = new new_node(newId);
nodes.push(newNode);
var newLink = new new_link(rootId, newId);
links.push(newLink);
//adds newest link and draws it
link = svg.select("#lnks").selectAll(".link")
.data(links)
var linkEnter = link
.enter().append("line")
.attr("class", "link");
link = linkEnter.merge(link);
//adds newest node
node = svg.select("#nds").selectAll(".node")
.data(nodes)
var nodeEnter = node
.enter().append("g")
.attr("class", "node");
//draws circle on newest node
var circlesEnter = nodeEnter.append('circle')
node = nodeEnter.merge(node);
circles = d3.selectAll('circle');
simulation.stop();
simulation.nodes(nodes);
simulation.force("link")
.links(links);
restartSim();
}
//starts up the simulation and sets up the way the leaves react to interaction
function restartSim() {
simulation.restart();
circles.on('click', function(d, i) {
addNode(i, nodes.length)
})
}
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("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
.link {
stroke: #bbb;
}
.node circle {
pointer-events: all;
fill: black;
stroke-width: 0px;
r: 20px
}
h1 {
color: white;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
代碼也放在這裏codepen: http://codepen.io/zpenoyre/pen/kkxBRW?editors=0010
那偉大工程,三江源。有沒有一種簡單的方法來理解alpha在這裏做什麼? 「再加熱」對我來說看起來並不是很直觀,[d3 API](https://github.com/d3/d3-force/blob/master/README.md#simulation_alpha)對我來說沒有多大意義就此主題而言。 – Zephyr
真棒,我沒有意識到模擬有效,但仔細觀察,我很清楚地看到它。有意義的是,您希望減少模擬計算,但每次更改設置時都需要重新啓動它。謝謝! – Zephyr
@Zephyr從你的第二個評論中,你可能會得到它。但是在'simulation.alphaTarget'提交中,您或其他任何人都可以獲得很好的附加信息:(https://github.com/d3/d3-force/commit/8a2c8590bb879c70eb2e10264b41d0200c887be9)「這樣可以設置」desired「alpha模擬,並使模擬平滑地內插到期望的值,默認情況下,目標值爲零,以便模擬冷卻,但通過將其設置爲 非零值,例如在拖動交互期間,你也可以用它來模擬熱量。「 – ibgib