-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
feat(sunburst): add innerRadius and renderRootNode props #2696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,8 @@ const InnerSunburst = <RawDatum,>({ | |
| data, | ||
| id = defaultProps.id, | ||
| value = defaultProps.value, | ||
| innerRadius = defaultProps.innerRadius, | ||
| renderRootNode = defaultProps.renderRootNode, | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there was a bug, innerRadius was used instead of innerRadiusOffset Fixed now, but, please, let me know if you implied a different approach / mode edits
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a bit better, but I think using an arc doesn't work very well tbh.
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we go for this approach, we should test the position of the text in the root node, and also make sure that a ring of 360 deg still behave as before. |
||
| valueFormat, | ||
| cornerRadius = defaultProps.cornerRadius, | ||
| layers = defaultProps.layers as SunburstLayer<RawDatum>[], | ||
|
|
@@ -74,6 +76,8 @@ const InnerSunburst = <RawDatum,>({ | |
| valueFormat, | ||
| radius, | ||
| cornerRadius, | ||
| innerRadius, | ||
| renderRootNode, | ||
| colors, | ||
| colorBy, | ||
| inheritColorFromParent, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| import { useMemo } from 'react' | ||
| import { partition as d3Partition, hierarchy as d3Hierarchy } from 'd3-hierarchy' | ||
| import { scaleRadial as d3ScaleRadial } from 'd3-scale' | ||
| import cloneDeep from 'lodash/cloneDeep.js' | ||
| import sortBy from 'lodash/sortBy.js' | ||
| import { usePropertyAccessor, useValueFormatter } from '@nivo/core' | ||
|
|
@@ -22,6 +23,8 @@ export const useSunburst = <RawDatum>({ | |
| valueFormat, | ||
| radius, | ||
| cornerRadius = defaultProps.cornerRadius, | ||
| innerRadius = defaultProps.innerRadius, | ||
| renderRootNode = defaultProps.renderRootNode, | ||
| colors = defaultProps.colors, | ||
| colorBy = defaultProps.colorBy, | ||
| inheritColorFromParent = defaultProps.inheritColorFromParent, | ||
|
|
@@ -33,6 +36,8 @@ export const useSunburst = <RawDatum>({ | |
| valueFormat?: DataProps<RawDatum>['valueFormat'] | ||
| radius: number | ||
| cornerRadius?: SunburstCommonProps<RawDatum>['cornerRadius'] | ||
| innerRadius?: SunburstCommonProps<RawDatum>['innerRadius'] | ||
plouc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| renderRootNode?: SunburstCommonProps<RawDatum>['renderRootNode'] | ||
| colors?: SunburstCommonProps<RawDatum>['colors'] | ||
| colorBy?: SunburstCommonProps<RawDatum>['colorBy'] | ||
| inheritColorFromParent?: SunburstCommonProps<RawDatum>['inheritColorFromParent'] | ||
|
|
@@ -58,8 +63,10 @@ export const useSunburst = <RawDatum>({ | |
| const hierarchy = d3Hierarchy(clonedData).sum(getValue) | ||
|
|
||
| const partition = d3Partition<RawDatum>().size([2 * Math.PI, radius * radius]) | ||
| // exclude root node | ||
| const descendants = partition(hierarchy).descendants().slice(1) | ||
| // exclude root node if renderRootNode is false | ||
| const descendants = renderRootNode | ||
| ? partition(hierarchy).descendants() | ||
| : partition(hierarchy).descendants().slice(1) | ||
|
|
||
| const total = hierarchy.value ?? 0 | ||
|
|
||
|
|
@@ -69,6 +76,12 @@ export const useSunburst = <RawDatum>({ | |
| // are going to be computed first | ||
| const sortedNodes = sortBy(descendants, 'depth') | ||
|
|
||
| const innerRadiusOffset = radius * Math.min(innerRadius, 1) | ||
|
|
||
| const maxDepth = Math.max(...sortedNodes.map(n => n.depth)) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As nodes are already sorted, we can simply get the depth of the last one, should be faster for larger datasets. We just need to handle the case where there are no nodes. |
||
|
|
||
| const radiusScale = d3ScaleRadial().domain([0, maxDepth]).range([innerRadiusOffset, radius]) | ||
|
|
||
| return sortedNodes.reduce<ComputedDatum<RawDatum>[]>((acc, descendant) => { | ||
| const id = getId(descendant.data) | ||
| // d3 hierarchy node value is optional by default as it depends on | ||
|
|
@@ -79,12 +92,13 @@ export const useSunburst = <RawDatum>({ | |
| const value = descendant.value! | ||
| const percentage = (100 * value) / total | ||
| const path = descendant.ancestors().map(ancestor => getId(ancestor.data)) | ||
| const isRootNode = renderRootNode && descendant.depth === 0 | ||
|
|
||
| const arc: Arc = { | ||
| startAngle: descendant.x0, | ||
| endAngle: descendant.x1, | ||
| innerRadius: Math.sqrt(descendant.y0), | ||
| outerRadius: Math.sqrt(descendant.y1), | ||
| innerRadius: isRootNode ? 0 : radiusScale(descendant.depth - 1), | ||
| outerRadius: isRootNode ? innerRadiusOffset : radiusScale(descendant.depth), | ||
| } | ||
|
|
||
| let parent: ComputedDatum<RawDatum> | undefined | ||
|
|
@@ -119,6 +133,8 @@ export const useSunburst = <RawDatum>({ | |
| }, [ | ||
| data, | ||
| radius, | ||
| innerRadius, | ||
| renderRootNode, | ||
| getValue, | ||
| getId, | ||
| valueFormat, | ||
|
|
||

Uh oh!
There was an error while loading. Please reload this page.