Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
В моем разговоре о силовых макетах есть пример ограничивающего прямоугольника . Интеграция позиции Verlet позволяет определять геометрические ограничения (такие как ограничивающие поля и обнаружение столкновения ) внутри прослушивателя событий «tick»; просто переместите узлы в соответствии с ограничением, и симуляция будет соответствующим образом адаптирована.
Тем не менее, гравитация определенно является более гибким способом решения этой проблемы, поскольку она позволяет пользователям перетаскивать график за пределы ограничивающего поле временно, а затем график восстановится. В зависимости от размера графика и размера отображаемой области вы должны поэкспериментировать с различными относительными сильными сторонами силы тяжести и заряда (отталкивания), чтобы получить график.
Пользовательская сила также является возможным решением. Мне нравится этот подход больше, поскольку не только отображаемые узлы перемещаются, но и весь симулятор работает с ограничивающей силой.
let simulation = d3.forceSimulation(nodes)
...
.force("bounds", boxingForce);
// Custom force to put all nodes in a box
function boxingForce() {
const radius = 500;
for (let node of nodes) {
// Of the positions exceed the box, set them to the boundary position.
// You may want to include your nodes width to not overlap with the box.
node.x = Math.max(-radius, Math.min(radius, node.x));
node.y = Math.max(-radius, Math.min(radius, node.y));
}
}
Прокомментированный код работает на узле, который из вашего определения является элементом svg g (rouping) и не использует атрибуты cx / cy. Выберите элемент окружности внутри узла, чтобы оживить эти атрибуты:
node.select("circle") // select the circle element in that node
.attr("cx", function(d) { return d.x = Math.max(r, Math.min(w - r, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(r, Math.min(h - r, d.y)); });
node.attr("cx", function(d) { return d.x = Math.max(r, Math.min(width - r, d.x)); }) .attr("cy", function(d) { return d.y = Math.max(r, Math.min(height - r, d.y)); });
Если вы используетеpath
вместоline
, вам нужно будет добавить граничную проверку для `attr ('d', function () {...});` ``. – Limin 29 May 2013 в 22:56