d3 на пределы контейнера [дубликат]

Указатель NULL - это тот, который указывает на никуда. Когда вы разыскиваете указатель p, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p является нулевым указателем, местоположение, хранящееся в p, является nowhere, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception.

В общем, это потому, что что-то не было правильно инициализировано.

35
задан VividD 25 January 2014 в 23:23
поделиться

3 ответа

В моем разговоре о силовых макетах есть пример ограничивающего прямоугольника . Интеграция позиции Verlet позволяет определять геометрические ограничения (такие как ограничивающие поля и обнаружение столкновения ) внутри прослушивателя событий «tick»; просто переместите узлы в соответствии с ограничением, и симуляция будет соответствующим образом адаптирована.

Тем не менее, гравитация определенно является более гибким способом решения этой проблемы, поскольку она позволяет пользователям перетаскивать график за пределы ограничивающего поле временно, а затем график восстановится. В зависимости от размера графика и размера отображаемой области вы должны поэкспериментировать с различными относительными сильными сторонами силы тяжести и заряда (отталкивания), чтобы получить график.

60
ответ дан mbostock 18 August 2018 в 19:21
поделиться
  • 1
    Ключ будет добавлен 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

Пользовательская сила также является возможным решением. Мне нравится этот подход больше, поскольку не только отображаемые узлы перемещаются, но и весь симулятор работает с ограничивающей силой.

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));
    }
}
0
ответ дан Bruno Zell 18 August 2018 в 19:21
поделиться

Прокомментированный код работает на узле, который из вашего определения является элементом 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)); });
0
ответ дан Marc 18 August 2018 в 19:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: