changed data, same key

232 views
Skip to first unread message

Matthew Pocock

unread,
Mar 13, 2014, 10:01:07 AM3/13/14
to d3...@googlegroups.com
Hi,

I've been playing with d3 for about a week now, and it certainly makes my life easier. I'm doing both textual and visual data rendering. My data is quite volatile, with different parts of complex datasets updating asynchronously.

One thing I've stumbled over several times is data were I have an array of values with a custom key function and some of this data is being updated periodically by a json call. Sometimes this fits the d3 paradigm of new data being added or old data being removed, but sometimes data is updated, as distinct from just persisting. That is, it maintains the same key but the values change.

So far, with d3's join model, I can't find a way to distinguish between existing keys with unchanged values and existing keys with new values. This has lead me to some fairly ugly hacks to apply styling to the updated values only.

Is there some way to achieve this within d3? If not, and I'm probably overstepping here, the obvious extension to me would be to

a: add isUpdateValue as an additional optional argument to data e.g.

selection.data(theValues, keyFunction, isUpdatedValue)

For any value were there's an old data value with an existing key, the old value and the new value would be passed to isUpdateValue. This would return 'true' if this represents an update, 'false' if it is the same old data.

b: add a .update() selector

This could be used after .enter() and would contain exactly those elements were isUpdatedValue was called and returned true.

With this, we could do things like:

.update().selectAll(".value")
  .style("color", "red").transition(1000).style("color", "black");

This would only apply to the updated values, not to all pre-existing values.

Sorry to come barrelling in blind and making big feature requests. Perhaps this functionality is already covered and I've just not stumbled over it yet.

Thanks,
Matthew

Nick Guenther

unread,
Mar 14, 2014, 1:27:55 AM3/14/14
to d3...@googlegroups.com

Nick Guenther
4A Stats/CS
University of Waterloo
Wow. You've nailed a problem I suspected but couldn't quite articulate us having. d3 is great and simple with static datasets and time series, but I don't yet know how to deal with things like dynamic map data. I assumed d3 had a solution for us and we just haven't had the time to learn it. When you figure it out, please share.

If it doesn't exist, your second idea is the right way to go, IMO.

Amelia Bellamy-Royds

unread,
Mar 15, 2014, 2:22:28 PM3/15/14
to d3...@googlegroups.com
The problem with making this a default behaviour is that it would require that you store the old data in order to compare it with the new, and that would have a performance impact in many cases where it wouldn't be used.  However, you could easily implement it yourself:

selection = selection.property(" __oldData__", function(d){ return d; } ); //store the old data as a property of the node
                    .data(newData);  //over-write the default data property with new data

selection.enter() /*etc*/;  //

selection.filter( function(d) {
                 //test whether the relevant properties of d match the equivalent property of the oldData
                //also test whether the old data exists, to catch the entering elements!
                 return ( (!this.__oldData__ ) || (d.value != this.__oldData__.value) );
            })
            .style("color", "red").transition().duration(1000)
                                        .style("color", "black");

selection.property("__oldData__", null); //delete the old data once it's no longer needed

You can of course use any name for the old data property, it's just convention to throw a lot of "_" characters around it to avoid messing up any of the browser's native DOM properties.

--ABR

Matthew Pocock

unread,
Mar 15, 2014, 5:51:27 PM3/15/14
to d3...@googlegroups.com

Thanks. I will try that. Would it be possible to do this old data copying only if a 'check for same data' function was passed to .data?

Sent from my android - may contain predictive text entertainment.

--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages