novus / nvd3

A reusable charting library written in d3.js
http://nvd3.org/
Other
7.22k stars 2.14k forks source link

Support for key functions? #1356

Open mindjuice opened 9 years ago

mindjuice commented 9 years ago

I can't seem to find any an existing way to set a key function for object constancy (http://bost.ocks.org/mike/constancy/)

Is this supported?

I'm drawing a lineWithFocusChart.

adnasa commented 8 years ago

I don't follow what you really need to accomplish, so you will have to forgive my reply. But at least I'd like to share what i've learned the past 30 minutes and hopefully it gives you some guidance on how to solve your request.

Does the following solve your problem? (experimented a little with examples/lineWithFocusChart

        d3.select('#chart svg')
            .data([testData()], function(data) {
                // return the unique identifier here
            }).call(chart);

the biggest difference with selection.data and selection.datum is how they compute the selection with the bound data sent in. in the nvd3 models, the data you send is required to be an array and each item within that array has to have a values property to crunch the numbers for those lines you want to draw.

After digging around the code I realised that if you need to go beyond what I've described above, perhaps you need to dig a little deeper in nv.models.lineChart. I'd start on line 154.

There is definitely room to hook in a key function right there to determine the identifier for each value in your data. :sob:

mindjuice commented 8 years ago

Thanks, and sorry for being lazy. I should have found that myself.

Without object constancy, the graph animations are weird when I truncate data from the front of the array (reach max number of samples that I want to keep). Instead of just scrolling the data points over right-to-left, it animates each data point to a new vertical position, which looks really strange. This occurs because D3 uses the array index by default as the object key.

Looking at line 154, yeah, clearly it doesn't pass in a key function there.

I'll implement this next week when I task switch back to this project, and I'll put together a PR.

adnasa commented 8 years ago

so I can presume now that starting to hook a key function on L154 could put you into the right direction, yes? have fun! :smile:

liquidpele commented 8 years ago

Oh, neat, haven't played with key functions before. Looks like something that could be baked in pretty easily though... if you do it please send us a PR!

adnasa commented 8 years ago

:+1:

mindjuice commented 8 years ago

So this isn't going quite how I expected.

Turns out that on these lines: https://github.com/novus/nvd3/blob/master/src/models/line.js#L95-L96

it already looks for akey property for each time series, which is fine, but doesn't help with the problem I have.

Then on these lines: https://github.com/novus/nvd3/blob/master/src/models/line.js#L144-L145

it passes in the array of values for a given time series entry and then just below uses that data to create an svg path.

Unfortunately, you can't set keys for individual points in an svg path, which is sort of what I was thinking of (i.e., associate each point with its timestamp so that animation works properly).

I thought of another way to accomplish this, and it could all be done in nvd3 with a bit of cooperation from the app when passing in the data.

I'm sure there are a lot of details to get this right, and I'm going to let this percolate for a day or two before I try implementing anything.

If anyone has any other ideas, or sees a problem with this I'm all ears!