GithubHelp home page GithubHelp logo

Comments (10)

vasturiano avatar vasturiano commented on August 25, 2024

@Vity01 a non-leaf node in the tree needs to take into account the sum of the children's values because this is a hierarchical layout, i.e. a node's radial angle needs to be at least as wide as the sum of its children combined.

What you can do is specify how the value of each node (leaf or non-leaf) is computed, using the size property, like:

myChart.size(d => d.value * 10)

from sunburst-chart.

Vity01 avatar Vity01 commented on August 25, 2024

@vasturiano I am not sure if we understand each other. I don't understand how the settings can bypass the summing of the nodes values.
The default size value is d => d.value.

from sunburst-chart.

vasturiano avatar vasturiano commented on August 25, 2024

@Vity01 are you referring to the angular size of the slices, or the values displayed on the tooltip?
For the angular sizes, you can't modify the summing operation, that's an integral part of the visual layout, and necessary to build the hierarchical layout.
However, you can change the values displayed on tooltip for each of the slices. That's just a matter of changing the tooltipContent method, like:

  mychart.tooltipContent(d => `${d.value} units`)

Let me know if I'm still missing something.

from sunburst-chart.

Vity01 avatar Vity01 commented on August 25, 2024

I am referring both :-). We have pre-computed all values for all nodes so the summing is not necessary from my point of view. I think it can be skipped from what I see in the code :

 const hierData = d3Hierarchy(state.data, accessorFn(state.children)).sum(accessorFn(state.size));

I guess it will work for my case:

 const hierData = d3Hierarchy(state.data, accessorFn(state.children));

PS. Thanks for the fast response!

from sunburst-chart.

vasturiano avatar vasturiano commented on August 25, 2024

@Vity01 the .sum(<fn>) method is required to compute the sunburst/partition layout, as you can see here:
https://github.com/d3/d3-hierarchy#node_sum

Perhaps the confusing part is in the function name, it's called sum but its real purpose is to instruct the layout how to extract values/sizes from each node. Internally, those values are then summed since there is a hierarchy of nodes, but the method simply accesses the value in each node, in your case that should be the value property I assume.

So basically a node with children can never be smaller than the sum of all its children. These are the constraints of this type of layout.
Its dimensions are determined by the sum of its children, plus its own value. So, if you want a non-leaf node to have a size larger than the sum of its children, you can simply assign it a value that is equal to that additional quantity (excluding the children sum), if that makes sense.

from sunburst-chart.

DavidC-75 avatar DavidC-75 commented on August 25, 2024

Just following-up on this old question, because it's of particular interest for me.
Let me try to rephrase the original question.

Say we have a node A with two children A1 and A2.

By default, the value of node A (which determines the size of the arc on the chart) is calculated as A.size + A1.size + A2.size. This is what the sum function does: it cumulates the size of all nodes in a bottom-up fashion. (in this case the assumption is that A.size>=0, A1.size>=0 and A2.size>=0)

However, depending on how the original data is recorded and what it represents, a different behavior is sometimes desirable, where the value of node A is directly indicated by A.size (in this case the assumption is that A.size>=A1.size + A2.size).
Can this behavior be obtained and how ?

PS: the two different behaviors are also explained and illustrated in https://plotly.com/python/sunburst-charts/#branchvalues

from sunburst-chart.

vasturiano avatar vasturiano commented on August 25, 2024

@DavidC-75 thanks for your comment.

I think the most deterministic and less ambiguous way is to interpret the size property of a node as the "self" portion that's not covered by any children. Otherwise you start hitting the edge cases where a node's size might be smaller than the space required for the children.

But, if you're interested in specifying it that way, all you have to do is do the required inverse math of subtracting the children accumulated sizes from the node values (and ensure that it is at least 0), and use that value in the component. That should be a relatively simple translation to do, even though it requires you to traverse the tree bottom-up to calc the aggregated sizes.

from sunburst-chart.

DavidC-75 avatar DavidC-75 commented on August 25, 2024

Thanks for the very, very quick feedback !
Applying some mathematical transformation before generating the plot is what I have been doing so far, and of course that works very nicely 👍
This is merely a form of differentiation. But in d3, the sum function is a form of integration and is just undoing it. When the data is collected under the right format (when the size of a node already includes the contribution from all its descendants), it's even easier if you don't have anything to do at all: you don't differentiate first, and d3 doesn't re-integrate later....
As I mentioned, plotly offers this as a "native" option which is very convenient. However, I appreciate it might not be as straightforward to do with d3 (I could be wrong, but it seems to me that the integration is kind of "hardcoded" in the framework).

from sunburst-chart.

vasturiano avatar vasturiano commented on August 25, 2024

@DavidC-75 yes, this summing method is baked-in to d3Hierarchy and is the only available mean to express node sizes across the hierarchical data structure. And the various layouts (f.e. partition which is used by this Sunburst chart) do expect the input data to follow that structure too.

from sunburst-chart.

DavidC-75 avatar DavidC-75 commented on August 25, 2024

Actually, I've found how to get the desired behavior.

When the size property of a node is the "self" portion and excludes the size of all its descendants, the d3 hierarchy is typically built as:

  const root = d3.hierarchy(data)
      .sum(d => d.size)

Alternatively, when the size property of a node is the "total" and already includes the size of all its descendants, the d3 hierarchy can simply be built instead as:

  const root = d3.hierarchy(data)
      .each(d => d.value = d.data.size)

from sunburst-chart.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.