Как полностью удалить d3 forceSimulation и его обработчики перетаскивания

Я хочу разрешить пользователям просматривать свою сеть с помощью d3 forceSimulation или макет CoLa, что означает, что когда пользователь инициирует событие, мне нужно чтобы изменить, какой из этих алгоритмов компоновки обновляет атрибуты x и y моих узлов и ребер.

В частности, для этого требуется, чтобы я мог останавливать симуляции и предотвращать обновление ими этих атрибутов данных, которые я им даю, пока другие «активны», а также удалять связанные с ними обработчики перетаскивания.

Моя функция рендеринга в настоящее время имеет:

    if (use_cola) {

        // MUST TURN OFF D3 AND ITS DRAG HANDLERS!

        force = cola_force.nodes(graph.nodes)
                          .links(links)
                          .groups(groups[group_nodes_by])
                          .jaccardLinkLengths(repulsion_strength, 0.7)
                          .avoidOverlaps(true)
                          .start(50, 0, 50);

        node.call(cola_force.drag);
        group.call(cola_force.drag);

        cola_force.on('tick',  ticked);

    } else {  // d3

        // MUST TURN OFF COLA AND ITS DRAG HANDLERS!

        force = d3_force.nodes(graph.nodes)
                        .force("link", d3.forceLink(links))
                        .force("charge", d3.forceManyBody().strength(-repulsion_strength))
                        .force("center", d3.forceCenter(w/2,h/2));

        node.call(d3.drag()
             .on("start", dragstarted)
             .on("drag", dragged)
             .on("end", dragended));  // where those are the conventional functions

        d3_force.on('tick', ticked);
    } 

Одним из решений может быть искажение этих объектов, например. delete d3_force['something_important']

Может работать что-то более простое, например d3_force.nodes([]) или что-то в этом роде.

Я не уверен, как бы я сделал что-то похожее на обработчики перетаскивания, потому что я менее знаком с тем, как они работают.

Обновление 1:

Частичное решение, предложенное для обработчика перетаскивания d3 (в d3v3) здесь:

var dragCallback = d3.select('rect#no-drag').property('__onmousedown.drag')['_'];

d3.select('rect#no-drag').on('mousedown.drag', null);

а затем восстановить его позже:

d3.selectAll('rect#no-drag').on('mousedown.drag', dragCallback);

person Alex Lenail    schedule 21.11.2018    source источник


Ответы (1)


Вам нужно сделать две вещи:

  1. Остановите симуляцию, если она все еще работает, чтобы она не испортила координаты ваших узлов. Это легко сделать, вызвав d3_force.stop(). Однако нет необходимости сначала проверять, работает ли он, потому что вызов его на уже остановленной симуляции также не повредит.

    Позже вы можете повторно активировать симуляцию, просто вызвав d3_force.restart(), возможно, вернув немного энергии обратно в разогреть: d3_force.alpha(1).restart().

  2. #P4# <блочная цитата> #P5#
     selection.on(".drag", null);
    
    #P6#
person altocumulus    schedule 07.12.2018
comment
Это отличный ответ! Но частичный. Я не уверен, что сделал достаточно хорошую работу по указанию выше, но мне нужно выяснить, как чередовать эти две библиотеки — d3 и cola. В вашем ответе показано, как отключить обработчики перетаскивания и макет d3, чтобы я мог переключиться на колу, но мне все еще нужно выяснить, как отключить обработчики перетаскивания колы и макет, чтобы переключиться на d3. Поскольку кола встречается реже и не имеет хороших документов, я не ожидаю, что вы дадите мне ответ, но не могли бы вы указать мне правильное направление? Где я должен искать, где CoLa связывает свои обработчики перетаскивания (аналогично .drag)? - person Alex Lenail; 08.12.2018
comment
@AlexLenail IMO, это довольно широко. Я понял, что вы ищете, но, как вопрос, я прочитал его, как если бы вы просили только D3. Я предлагаю вам придерживаться сути и поместить часть колы в новый вопрос, предоставив ссылку на другой пост в обоих вопросах. Поскольку я сам не любитель колы, боюсь, это все, что я могу для вас сделать. - person altocumulus; 08.12.2018