spiermar / d3-flame-graph

A D3.js plugin that produces flame graphs from hierarchical data.
Apache License 2.0
890 stars 119 forks source link

allow to provide custom getValue() and getDelta() functions #114

Open wonder-mice opened 6 years ago

wonder-mice commented 6 years ago

I have a huge data set that I embed in html as json object that follows d3-flamegraph specification. I also add several custom fields to it, such as syscall count, vmfault count, etc. I would like to have an easy way to choose what subset of data to display in a flame graph, preferably without regenerating the whole data structure (e.g. now I'll need to traverse the whole tree to place what I want into the value field).

Describe the solution you'd like Some way to provide custom implementations of getValue() and getDelta() functions. This also will allow to make data more compact. E.g., for comparison view, I can have A and B values in the data (since I want to show them in a tooltip anyway), so I don't need to store delta and can compute it easily in getDelta() function.

wonder-mice commented 6 years ago

I assume I can to something like:

flamegraph.getValue = function(d) { d.A; }
flamegraph.getDelta = function(d) { d.B - d.A; }

but that seems not to work. Looks like some parts of the code access .v|.value fields directly, because when I do:

flamegraph.getValue = function(d) { 20; }
flamegraph.getDelta = function(d) { 20; }

Nodes width is still computed based on .v/.value. Maybe I'm doing something wrong though...

wonder-mice commented 6 years ago

OMG, I'm a JavaScript hacker :) This seems to make it work: https://github.com/wonder-mice/d3-flame-graph/commit/60c3415e162710ae9f0b949d5820b0f539b8707f

wonder-mice commented 6 years ago

https://github.com/spiermar/d3-flame-graph/pull/115

wonder-mice commented 6 years ago

I would like to rename getValue and friends to reflect on what they operate on. Some of them work with data nodes (like getValue), while other work with d3 nodes (like getDelta). Is there any established terminology to distinguish them?

spiermar commented 6 years ago

Not that I'm aware of, but open to suggestions.

wonder-mice commented 6 years ago

Looks like found a "bug" - getChildren is used both with d3 nodes and with data nodes.

I suggest to name d3 nodes "nodes", since they are named that way all over d3 source code. Data nodes I would suggest to call 'items". Thus getItemValue, getNodeDelta, etc.

wonder-mice commented 6 years ago

Should default labelHandler show "self" value of a node or exact value provided in data object? It looks like currently it uses node.value which is always node's self value, since it's populated in update() function when calling root.sum(). It doesn't look like it's expected from default labelHandler - I would expect it to show what I provided in data.

wonder-mice commented 6 years ago

I guess I misread the node.sum() function in d3. Looks like node.value is total node value, including its children. However, passed function must return node's self value, which we compute by subtracting child nodes, which they add back in node.sum...

wonder-mice commented 6 years ago

Ah, I see, we need this trickery for if (d.fade || d.hide) to adjust node.value for zoom mode.

wonder-mice commented 6 years ago

When clicking on node to zoom in, this changes value in tooltip for all nodes on the path to clicked node: http://martinspier.io/d3-flame-graph/

I think tooltip label shouldn't use node.value, node.value it's just defines node'a width on the chart and can be unrelated to item's data (e.g. nodes can be played out in log scale).

spiermar commented 6 years ago

Looks like found a "bug" - getChildren is used both with d3 nodes and with data nodes.

I suggest to name d3 nodes "nodes", since they are named that way all over d3 source code. Data nodes I would suggest to call 'items". Thus getItemValue, getNodeDelta, etc.

Saw that now.

spiermar commented 6 years ago

When clicking on node to zoom in, this changes value in tooltip for all nodes on the path to clicked node: http://martinspier.io/d3-flame-graph/

I think tooltip label shouldn't use node.value, node.value it's just defines node'a width on the chart and can be unrelated to item's data (e.g. nodes can be played out in log scale).

If you have custom function like the proposed changes. Currently, value would be the same. Can you update the PR with the different functions?

wonder-mice commented 6 years ago

Currently, value would be the same

No, value is computed by node.sum() and will change by zooming.

spiermar commented 6 years ago

Currently, value would be the same

No, value is computed by node.sum() and will change by zooming.

When zooming, yes, but that was the intended effect. Having said that, it always bugged me, because I lose the notion of relative size when zooming. Might be a good time to change it. Let me check with Brendan what his thoughts are.

wonder-mice commented 6 years ago

I think node.value must have no relation to item's value, other than it should establish desired proportions of nodes in chart. Then it'll be easier to implement log scales and other effects. It'll also allow for some optimizations when computing these values.

spiermar commented 6 years ago

I think node.value must have no relation to item's value, other than it should establish desired proportions of nodes in chart. Then it'll be easier to implement log scales and other effects. It'll also allow for some optimizations when computing these values.

I think its important to differentiate between them, either by different functions or something else, but it's important to keep both for different use cases.

wonder-mice commented 6 years ago

What is the use case for node.value other than node's width?

spiermar commented 6 years ago

What is the use case for node.value other than node's width?

Exactly when I need to know the node's width.

spiermar commented 6 years ago

@wonder-mice prefer to treat those changes as a separate PR?

wonder-mice commented 6 years ago

Don't accept any PR from me for now. I need to rework the patch set, found other issues.

spiermar commented 6 years ago

Don't accept any PR from me for now. I need to rework the patch set, found other issues.

Ok, I'll wait for the new PR.

FYI, I'll be traveling next week, so there might be some delay on my response after Sat evening.

wonder-mice commented 6 years ago

Check this out: https://github.com/spiermar/d3-flame-graph/pull/120

It has some differences visible from outside though: