d3.js circle plotting does not working properly while trying to load after first time

后端 未结 1 1255
梦如初夏
梦如初夏 2020-12-07 05:52

This is my d3.js piece of code :



        
相关标签:
1条回答
  • 2020-12-07 06:16

    The problem is you are never updating existing "electrons" when you go from 7 to 10. In your code

    var electron_nodes = vis.selectAll('circle.electron')
    .data(electrons)
    .enter().append("circle")
    .attr("class", "electron")
    .attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; })
    .attr("r", 7)
    .on("mouseover", function(d) { 
       // how to drag the electron around the circle?
    });
    

    everything after enter() only applies to new elements added in.

    It's a common confusion; I answered another question like this earlier today, so I'm going to try to explain it really clearly here (and then everyone can just link to this explanation in future!).

    Chaining methods is a great part of D3, but it can only do so much. Everyone wants to chain everything together, but you have to keep track of when your chain separates out into an enter() or exit() selection, and go back to the main selection for updating.

    The general update routine will normally have four "chains" (each ended with a ;):

    • A Select Chain, that selects the elements and updates the data and saves the selection in a variable, for example you could call it var elements

    • An Enter Chain, starting with elements.enter(). (or whatever variable name you used to save the Select Chain), appending the new elements and setting any attributes or styles that are going to be constant (i.e., won't change on update)

    • An Exit Chain, starting with elements.exit()., with transitions (if using) and remove()

    • An Update Chain, starting just with your saved selection variable, followed by all the methods to set the attributes or styles that need to be updated; this will also set these attributes for the first time on the elements you just created with .enter()

    Yes, you can do things differently, but only if you clearly understand what is happening and why you are changing from this pattern.

    This approach also avoids the repetition in your code, where you re-select your electrons and re-apply the data to get at the exit() selection.

    So for your program, the application of the 4-chain update method would look like this:

    //chain 1: select
    var electron_nodes = vis.selectAll('circle.electron')
          .data(electrons); 
    
    //chain 2: enter
    electron_nodes.enter().append("circle")
      .attr("class", "electron")
      .on("mouseover", function(d) { 
       // Although this function uses data at the time the event happens, 
       // the actual definition of the function never changes,
       // so you only need to attach it once when you create the node.
      })
      .attr("r", 7); 
    
    //chain 3: exit
    electron_nodes.exit().remove(); 
    
    //chain 4: update
    electron_nodes.attr("cx", function(d) { return d.x; })
      .attr("cy", function(d) { return d.y; });
    

    Sorry it took this long for someone to answer your question; it's a rather complicated program, and probably scared people off with all the math functions. For future, you don't need to include your AJAX method (assuming you've checked that it's returning the correct values), but it would help to include an example of the data that the AJAX request returns. And of course, a working example on JSFiddle or Tributary is even better!

    Best,
    --ABR

    0 讨论(0)
提交回复
热议问题