Skip to content

Commit 0b5ec4a

Browse files
committed
feat(sunburst): add innerRadius and renderRootNode props
1 parent 3a9d866 commit 0b5ec4a

File tree

10 files changed

+26001
-34357
lines changed

10 files changed

+26001
-34357
lines changed

packages/sunburst/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,16 @@
3535
"@nivo/tooltip": "workspace:*",
3636
"@types/d3-hierarchy": "^1.1.8",
3737
"d3-hierarchy": "^1.1.8",
38+
"d3-scale": "^4.0.2",
3839
"lodash": "^4.17.21"
3940
},
4041
"peerDependencies": {
4142
"react": ">= 16.14.0 < 19.0.0"
4243
},
4344
"publishConfig": {
4445
"access": "public"
46+
},
47+
"devDependencies": {
48+
"@types/d3-scale": "^4.0.8"
4549
}
4650
}

packages/sunburst/src/Sunburst.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const InnerSunburst = <RawDatum,>({
2525
data,
2626
id = defaultProps.id,
2727
value = defaultProps.value,
28+
innerRadius = defaultProps.innerRadius,
29+
renderRootNode = defaultProps.renderRootNode,
2830
valueFormat,
2931
cornerRadius = defaultProps.cornerRadius,
3032
layers = defaultProps.layers as SunburstLayer<RawDatum>[],
@@ -73,6 +75,8 @@ const InnerSunburst = <RawDatum,>({
7375
valueFormat,
7476
radius,
7577
cornerRadius,
78+
innerRadius,
79+
renderRootNode,
7680
colors,
7781
colorBy,
7882
inheritColorFromParent,

packages/sunburst/src/hooks.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { useMemo } from 'react'
22
import { partition as d3Partition, hierarchy as d3Hierarchy } from 'd3-hierarchy'
3+
import { scaleRadial as d3ScaleRadial } from 'd3-scale'
34
import cloneDeep from 'lodash/cloneDeep'
45
import sortBy from 'lodash/sortBy'
56
import { usePropertyAccessor, useTheme, useValueFormatter } from '@nivo/core'
@@ -21,6 +22,8 @@ export const useSunburst = <RawDatum>({
2122
valueFormat,
2223
radius,
2324
cornerRadius = defaultProps.cornerRadius,
25+
innerRadius = defaultProps.innerRadius,
26+
renderRootNode = defaultProps.renderRootNode,
2427
colors = defaultProps.colors,
2528
colorBy = defaultProps.colorBy,
2629
inheritColorFromParent = defaultProps.inheritColorFromParent,
@@ -32,6 +35,8 @@ export const useSunburst = <RawDatum>({
3235
valueFormat?: DataProps<RawDatum>['valueFormat']
3336
radius: number
3437
cornerRadius?: SunburstCommonProps<RawDatum>['cornerRadius']
38+
innerRadius?: SunburstCommonProps<RawDatum>['innerRadius']
39+
renderRootNode?: SunburstCommonProps<RawDatum>['renderRootNode']
3540
colors?: SunburstCommonProps<RawDatum>['colors']
3641
colorBy?: SunburstCommonProps<RawDatum>['colorBy']
3742
inheritColorFromParent?: SunburstCommonProps<RawDatum>['inheritColorFromParent']
@@ -57,8 +62,10 @@ export const useSunburst = <RawDatum>({
5762
const hierarchy = d3Hierarchy(clonedData).sum(getValue)
5863

5964
const partition = d3Partition<RawDatum>().size([2 * Math.PI, radius * radius])
60-
// exclude root node
61-
const descendants = partition(hierarchy).descendants().slice(1)
65+
// exclude root node if renderRootNode is false
66+
const descendants = renderRootNode
67+
? partition(hierarchy).descendants()
68+
: partition(hierarchy).descendants().slice(1)
6269

6370
const total = hierarchy.value ?? 0
6471

@@ -68,6 +75,12 @@ export const useSunburst = <RawDatum>({
6875
// are going to be computed first
6976
const sortedNodes = sortBy(descendants, 'depth')
7077

78+
const innerRadiusOffset = radius * Math.min(innerRadius, 1)
79+
80+
const maxDepth = Math.max(...sortedNodes.map(n => n.depth))
81+
82+
const scale = d3ScaleRadial().domain([0, maxDepth]).range([innerRadiusOffset, radius])
83+
7184
return sortedNodes.reduce<ComputedDatum<RawDatum>[]>((acc, descendant) => {
7285
const id = getId(descendant.data)
7386
// d3 hierarchy node value is optional by default as it depends on
@@ -82,8 +95,12 @@ export const useSunburst = <RawDatum>({
8295
const arc: Arc = {
8396
startAngle: descendant.x0,
8497
endAngle: descendant.x1,
85-
innerRadius: Math.sqrt(descendant.y0),
86-
outerRadius: Math.sqrt(descendant.y1),
98+
innerRadius:
99+
renderRootNode && descendant.depth === 0 ? 0 : scale(descendant.depth - 1),
100+
outerRadius:
101+
renderRootNode && descendant.depth === 0
102+
? innerRadius
103+
: scale(descendant.depth),
87104
}
88105

89106
let parent: ComputedDatum<RawDatum> | undefined

packages/sunburst/src/props.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ export const defaultProps = {
77
id: 'id',
88
value: 'value',
99
cornerRadius: 0,
10+
innerRadius: 0.4,
11+
renderRootNode: false,
1012
layers: ['arcs', 'arcLabels'] as SunburstLayerId[],
1113
colors: { scheme: 'nivo' } as unknown as OrdinalColorScaleConfig,
1214
colorBy: 'id' as const,

packages/sunburst/src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ export type SunburstCommonProps<RawDatum> = {
5656
height: number
5757
margin?: Box
5858
cornerRadius: number
59+
innerRadius: number
60+
renderRootNode: boolean
5961
theme: Theme
6062
colors: OrdinalColorScaleConfig<Omit<ComputedDatum<RawDatum>, 'color' | 'fill'>>
6163
colorBy: 'id' | 'depth'

0 commit comments

Comments
 (0)