Я пытаюсь добавить узлы один за другим к симуляции симуляции 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
Это прекрасно работает, большое спасибо. Есть ли простой способ понять, что здесь делает альфа? «Повторный нагрев» не кажется мне очень интуитивным, а [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)« Это позволяет вам установить «желаемую» альфу для моделирование и моделирование плавно интерполируют в направлении желаемого значения. По умолчанию целевое значение равно нулю, так что имитация охлаждается. Однако, установив его на ненулевое значение, например, во время взаимодействия с перетаскиванием , вы также можете использовать его, чтобы иметь симуляция моделирования ». – ibgib