0

I'm new to d3 and trying to implement a force simulation updating itself with real-time data. To make it easy, with each d3.interval I assign a random value to "bitrate" key of each node. My aim is to access the previous data value before binding the new data, thus set the rules of transition based on relation between them. I tried the brilliant method that AmeliaBr has explained in this post: Compare/Diff new data with previous data on d3.js update. It makes so much sence but when I try it and print the d.bitrate and this.__oldData__.bitrate values, they are always equal to each other. Weird thing, when I check them from the dev-tools they have different values. I also tried guerilla moves such as accessing __oldData__ by (d3.select(this)._group)[0][0], but it returns undefined :/ I think I'm soo confused and stuck that I can't see where I skip. Here is the screenshot from devtool and below is my code. Thanks!

function updateData(){

link = link.data(links, function(d) {return d.id})
         .enter()
         .append("line")
         .merge(link);

     link.transition(3000)
         .attr("stroke",function(d) {
            if ( d.target.bitrate > d.source.bitrate){
            return "green"}
          })

label = label.data(nodes)
           .enter()
           .append("text")
           .merge(label);

       label.transition(1000)
           .text(function(d){ return d.name; })


 node = node.data(nodes,function(d){return d.id})
            .enter()
            .append("circle")
            .merge(node);

        node.on("mouseover",mouseover)
            .on("mouseout",mouseout)
            .call(d3.drag().on("start",dragstarted)
                           .on("drag",dragged)
                           .on("end",dragended)
             )
            .transition(1000)
                           .attr("r",40)
                           .attr("stroke-width",function(d,i){
                              if (this.__oldData__){
                                console.log(this.__data__.bitrate);
                                console.log(this.__oldData__.bitrate);
                           }
                         })



   simulation.nodes(nodes);
   simulation.force("link").links(links);
   simulation.alpha(1).restart();
 }

d3.interval(function(){

nodes.map(function(n){n.bitrate = Math.round( Math.random() * 10000 )})

node = node.property("__oldData__", function(d){return d; });
updateData();

},2000)
Community
  • 1
  • 1
Ozgur
  • 1
  • 1
  • You are actually never updating your `nodes` data in the interval callback, i.e. your `nodes.map(function() { })` is not going to give the expected result. `.map()` will return a **new** array, which is not what you are after; furthermore, the function is missing the `return` statement needed for this purpose, and you are not assigning the returned array. You should be using `nodes.forEach(function(n) { })` instead to iterate over all items in the `nodes` array. The devtools screenshot might be another artefact, but you should definitely fix this first and report back, if the problem persists. – altocumulus Dec 27 '16 at 12:15
  • 1
    Possible duplicate of [Compare/Diff new data with previous data on d3.js update](http://stackoverflow.com/questions/23409250/compare-diff-new-data-with-previous-data-on-d3-js-update) – altocumulus Dec 27 '16 at 14:21
  • @altocumulus It's true that I don't return any value from .map() and don't overwrite "nodes" array, but still it works as I expected. While it loops through the array, the bitrate value (n.bitrate) is changing. So even though I change it to .forEach() result will be the same. About the devtools, I learned that it's not an artefact but a behaviour that developers chose to keep in that way (http://stackoverflow.com/questions/8249136/why-does-javascript-object-show-different-values-in-console-in-chrome-firefox). – Ozgur Jan 31 '17 at 13:16

0 Answers0