How to entirely remove a d3 forceSimulation and its drag handers












1















I want to allow users to view their network using either a d3 forceSimulation or a CoLa layout, which means when a user fires an event, I need to change out which of those layout algorithms is updating the x and y attributes of my nodes and edges.



In particular, this requires that I be able to stop the simulations and prevent them from updating those attributes on the data I give them while the other is "active" -- as well as removing the drag handlers associated with them.



My render function currently has:



    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);
}


One solution might be to mangle these objects, e.g. delete d3_force['something_important']



Something simpler might work, like d3_force.nodes() or somesuch.



I'm not sure how I would do something similar to the drag handlers because I'm less familiar with how those work.



Update 1:



A partial solution suggested for the d3 drag handler (in d3v3) here:



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

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


and then restoring it later:



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









share|improve this question





























    1















    I want to allow users to view their network using either a d3 forceSimulation or a CoLa layout, which means when a user fires an event, I need to change out which of those layout algorithms is updating the x and y attributes of my nodes and edges.



    In particular, this requires that I be able to stop the simulations and prevent them from updating those attributes on the data I give them while the other is "active" -- as well as removing the drag handlers associated with them.



    My render function currently has:



        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);
    }


    One solution might be to mangle these objects, e.g. delete d3_force['something_important']



    Something simpler might work, like d3_force.nodes() or somesuch.



    I'm not sure how I would do something similar to the drag handlers because I'm less familiar with how those work.



    Update 1:



    A partial solution suggested for the d3 drag handler (in d3v3) here:



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

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


    and then restoring it later:



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









    share|improve this question



























      1












      1








      1








      I want to allow users to view their network using either a d3 forceSimulation or a CoLa layout, which means when a user fires an event, I need to change out which of those layout algorithms is updating the x and y attributes of my nodes and edges.



      In particular, this requires that I be able to stop the simulations and prevent them from updating those attributes on the data I give them while the other is "active" -- as well as removing the drag handlers associated with them.



      My render function currently has:



          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);
      }


      One solution might be to mangle these objects, e.g. delete d3_force['something_important']



      Something simpler might work, like d3_force.nodes() or somesuch.



      I'm not sure how I would do something similar to the drag handlers because I'm less familiar with how those work.



      Update 1:



      A partial solution suggested for the d3 drag handler (in d3v3) here:



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

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


      and then restoring it later:



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









      share|improve this question
















      I want to allow users to view their network using either a d3 forceSimulation or a CoLa layout, which means when a user fires an event, I need to change out which of those layout algorithms is updating the x and y attributes of my nodes and edges.



      In particular, this requires that I be able to stop the simulations and prevent them from updating those attributes on the data I give them while the other is "active" -- as well as removing the drag handlers associated with them.



      My render function currently has:



          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);
      }


      One solution might be to mangle these objects, e.g. delete d3_force['something_important']



      Something simpler might work, like d3_force.nodes() or somesuch.



      I'm not sure how I would do something similar to the drag handlers because I'm less familiar with how those work.



      Update 1:



      A partial solution suggested for the d3 drag handler (in d3v3) here:



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

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


      and then restoring it later:



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






      javascript d3.js webcola






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 6 '18 at 16:40







      Alex Lenail

















      asked Nov 21 '18 at 3:00









      Alex LenailAlex Lenail

      3,00752048




      3,00752048
























          1 Answer
          1






          active

          oldest

          votes


















          2





          +50









          You need to do two things:





          1. Stop the simulation if it is still running to prevent it from messing with your nodes coordinates. This can easily be done by calling d3_force.stop(). There is no need to first check if it is running, though, because calling it on an already halted simulation will not hurt either.



            You can later re-activate the simulation by just calling d3_force.restart() probably pumping some energy back in to heat it up: d3_force.alpha(1).restart().




          2. The docs tell us how to get rid of the drag behavior:




            The listeners use the name .drag, so you can subsequently unbind the drag behavior as follows:



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



            In your case this would be node.on(".drag", null). If the user switches the layout back you can again bind the drag behavior to the node selection. For this it might be worth considering to create the drag behavior beforehand and just pass around the reference when rebinding later on.








          share|improve this answer
























          • This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

            – Alex Lenail
            Dec 8 '18 at 16:16













          • @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

            – altocumulus
            Dec 8 '18 at 17:24













          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404682%2fhow-to-entirely-remove-a-d3-forcesimulation-and-its-drag-handers%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2





          +50









          You need to do two things:





          1. Stop the simulation if it is still running to prevent it from messing with your nodes coordinates. This can easily be done by calling d3_force.stop(). There is no need to first check if it is running, though, because calling it on an already halted simulation will not hurt either.



            You can later re-activate the simulation by just calling d3_force.restart() probably pumping some energy back in to heat it up: d3_force.alpha(1).restart().




          2. The docs tell us how to get rid of the drag behavior:




            The listeners use the name .drag, so you can subsequently unbind the drag behavior as follows:



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



            In your case this would be node.on(".drag", null). If the user switches the layout back you can again bind the drag behavior to the node selection. For this it might be worth considering to create the drag behavior beforehand and just pass around the reference when rebinding later on.








          share|improve this answer
























          • This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

            – Alex Lenail
            Dec 8 '18 at 16:16













          • @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

            – altocumulus
            Dec 8 '18 at 17:24


















          2





          +50









          You need to do two things:





          1. Stop the simulation if it is still running to prevent it from messing with your nodes coordinates. This can easily be done by calling d3_force.stop(). There is no need to first check if it is running, though, because calling it on an already halted simulation will not hurt either.



            You can later re-activate the simulation by just calling d3_force.restart() probably pumping some energy back in to heat it up: d3_force.alpha(1).restart().




          2. The docs tell us how to get rid of the drag behavior:




            The listeners use the name .drag, so you can subsequently unbind the drag behavior as follows:



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



            In your case this would be node.on(".drag", null). If the user switches the layout back you can again bind the drag behavior to the node selection. For this it might be worth considering to create the drag behavior beforehand and just pass around the reference when rebinding later on.








          share|improve this answer
























          • This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

            – Alex Lenail
            Dec 8 '18 at 16:16













          • @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

            – altocumulus
            Dec 8 '18 at 17:24
















          2





          +50







          2





          +50



          2




          +50





          You need to do two things:





          1. Stop the simulation if it is still running to prevent it from messing with your nodes coordinates. This can easily be done by calling d3_force.stop(). There is no need to first check if it is running, though, because calling it on an already halted simulation will not hurt either.



            You can later re-activate the simulation by just calling d3_force.restart() probably pumping some energy back in to heat it up: d3_force.alpha(1).restart().




          2. The docs tell us how to get rid of the drag behavior:




            The listeners use the name .drag, so you can subsequently unbind the drag behavior as follows:



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



            In your case this would be node.on(".drag", null). If the user switches the layout back you can again bind the drag behavior to the node selection. For this it might be worth considering to create the drag behavior beforehand and just pass around the reference when rebinding later on.








          share|improve this answer













          You need to do two things:





          1. Stop the simulation if it is still running to prevent it from messing with your nodes coordinates. This can easily be done by calling d3_force.stop(). There is no need to first check if it is running, though, because calling it on an already halted simulation will not hurt either.



            You can later re-activate the simulation by just calling d3_force.restart() probably pumping some energy back in to heat it up: d3_force.alpha(1).restart().




          2. The docs tell us how to get rid of the drag behavior:




            The listeners use the name .drag, so you can subsequently unbind the drag behavior as follows:



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



            In your case this would be node.on(".drag", null). If the user switches the layout back you can again bind the drag behavior to the node selection. For this it might be worth considering to create the drag behavior beforehand and just pass around the reference when rebinding later on.









          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 7 '18 at 10:18









          altocumulusaltocumulus

          14k104655




          14k104655













          • This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

            – Alex Lenail
            Dec 8 '18 at 16:16













          • @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

            – altocumulus
            Dec 8 '18 at 17:24





















          • This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

            – Alex Lenail
            Dec 8 '18 at 16:16













          • @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

            – altocumulus
            Dec 8 '18 at 17:24



















          This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

          – Alex Lenail
          Dec 8 '18 at 16:16







          This is a great answer! But a partial one. I'm not sure I did a good enough job of specifying above, but I need to figure out how to alternate between these two libraries -- d3 and cola. Your answer shows how to turn off d3 drag handlers and layout so that I can switch to cola, but I still need to figure out how to turn off cola drag handlers and layout to switch to d3. Since cola is rarer and doesn't have great docs, I don't expect you to give me an answer -- but could you point me in the right direction? Where should I go looking for where CoLa binds its drag handlers (analogous to ".drag")?

          – Alex Lenail
          Dec 8 '18 at 16:16















          @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

          – altocumulus
          Dec 8 '18 at 17:24







          @AlexLenail IMO, that‘s rather broad. I understood what you are looking for but, as the question is, I read it as if you were asking for D3 alone. I suggest you keep it to the point and put the Cola part into a new question while providing a link to the other post in both questions. As I am not into Cola myself I‘m afraid that’s the most I can do for you.

          – altocumulus
          Dec 8 '18 at 17:24






















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404682%2fhow-to-entirely-remove-a-d3-forcesimulation-and-its-drag-handers%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          Xamarin.form Move up view when keyboard appear

          Post-Redirect-Get with Spring WebFlux and Thymeleaf

          Anylogic : not able to use stopDelay()