Как полностью удалить d3 forceSimulation и его перетаскивающие устройства - PullRequest
0 голосов
/ 21 ноября 2018

Я хочу, чтобы пользователи могли просматривать свою сеть, используя d3 forceSimulation или CoLa layout , что означает, что когда пользователь запускает событие, мне нужно изменить, какой изэти алгоритмы компоновки обновляют атрибуты 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);

1 Ответ

0 голосов
/ 07 декабря 2018

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

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

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

  2. документы говорят нам, как избавиться от поведения перетаскивания:

    Слушатели используют имя .drag, поэтому вы можете впоследствии отсоединить поведение перетаскивания следующим образом:

     selection.on(".drag", null);
    

    В вашем случае это будет node.on(".drag", null).Если пользователь переключает макет обратно, вы можете снова связать поведение перетаскивания с выбором node.Для этого, возможно, стоит подумать о том, чтобы заранее создать поведение перетаскивания и просто обойти ссылку при последующем связывании.

...