Skip to content

Commit 8108860

Browse files
committed
feat(polar-bar): add support for arc labels
1 parent b1bb5ea commit 8108860

File tree

23 files changed

+258
-91
lines changed

23 files changed

+258
-91
lines changed

packages/arcs/src/arc_labels/ArcLabelsLayer.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ interface ArcLabelsLayerProps<Datum extends DatumWithArcAndColor> {
1717
label: PropertyAccessor<Datum, string>
1818
radiusOffset: ArcLabelsProps<Datum>['arcLabelsRadiusOffset']
1919
skipAngle: ArcLabelsProps<Datum>['arcLabelsSkipAngle']
20+
skipRadius: ArcLabelsProps<Datum>['arcLabelsSkipRadius']
2021
textColor: ArcLabelsProps<Datum>['arcLabelsTextColor']
2122
transitionMode: ArcTransitionMode
2223
component?: ArcLabelsProps<Datum>['arcLabelsComponent']
@@ -29,6 +30,7 @@ export const ArcLabelsLayer = <Datum extends DatumWithArcAndColor>({
2930
label: labelAccessor,
3031
radiusOffset,
3132
skipAngle,
33+
skipRadius,
3234
textColor,
3335
component = ArcLabel,
3436
}: ArcLabelsLayerProps<Datum>) => {
@@ -39,12 +41,12 @@ export const ArcLabelsLayer = <Datum extends DatumWithArcAndColor>({
3941
const filteredData = useMemo(
4042
() =>
4143
data.filter(datum => {
42-
return (
43-
Math.abs(radiansToDegrees(datum.arc.endAngle - datum.arc.startAngle)) >=
44-
skipAngle
45-
)
44+
const angle = Math.abs(radiansToDegrees(datum.arc.endAngle - datum.arc.startAngle))
45+
const radius = Math.abs(datum.arc.outerRadius - datum.arc.innerRadius)
46+
47+
return angle >= skipAngle && radius >= skipRadius
4648
}),
47-
[data, skipAngle]
49+
[data, skipAngle, skipRadius]
4850
)
4951

5052
const { transition, interpolate } = useArcCentersTransition<Datum>(

packages/arcs/src/arc_labels/props.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface ArcLabelsProps<Datum extends DatumWithArcAndColor> {
77
arcLabel: PropertyAccessor<Datum, string>
88
arcLabelsRadiusOffset: number
99
arcLabelsSkipAngle: number
10+
arcLabelsSkipRadius: number
1011
arcLabelsTextColor: InheritedColorConfig<Datum>
1112
arcLabelsComponent: ArcLabelComponent<Datum>
1213
}

packages/generators/src/index.ts

+21
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,27 @@ export const generateCountriesData = (
144144
return d
145145
})
146146

147+
export const generateMonthlyData = (
148+
keys: string[],
149+
{ size = 12, min = 0, max = 200, withColors = true, short = false } = {}
150+
) => {
151+
const set = short ? sets.monthsShort : sets.months
152+
153+
return set.slice(0, size).map(month => {
154+
const d: Record<string, unknown> = {
155+
month,
156+
}
157+
keys.forEach(key => {
158+
d[key] = random(min, max)
159+
if (withColors) {
160+
d[`${key}Color`] = randColor()
161+
}
162+
})
163+
164+
return d
165+
})
166+
}
167+
147168
const libTreeItems = [
148169
[
149170
'viz',

packages/generators/src/sets/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './countryCodes'
22
export * from './names'
33
export * from './programmingLanguages'
4+
export * from './time'

packages/generators/src/sets/time.ts

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
export const months = [
2+
'January',
3+
'February',
4+
'March',
5+
'April',
6+
'May',
7+
'June',
8+
'July',
9+
'August',
10+
'September',
11+
'October',
12+
'November',
13+
'December',
14+
]
15+
16+
export const monthsShort = [
17+
'Jan',
18+
'Feb',
19+
'Mar',
20+
'Apr',
21+
'May',
22+
'Jun',
23+
'Jul',
24+
'Aug',
25+
'Sep',
26+
'Oct',
27+
'Nov',
28+
'Dec',
29+
]
30+
31+
export const weekdays = [
32+
'Sunday',
33+
'Monday',
34+
'Tuesday',
35+
'Wednesday',
36+
'Thursday',
37+
'Friday',
38+
'Saturday',
39+
]
40+
41+
export const weekdaysShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']

packages/pie/src/Pie.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ const InnerPie = <RawDatum extends MayHaveLabel>({
4646
enableArcLabels = defaultProps.enableArcLabels,
4747
arcLabel = defaultProps.arcLabel,
4848
arcLabelsSkipAngle = defaultProps.arcLabelsSkipAngle,
49+
arcLabelsSkipRadius = defaultProps.arcLabelsSkipRadius,
4950
arcLabelsTextColor = defaultProps.arcLabelsTextColor,
5051
arcLabelsRadiusOffset = defaultProps.arcLabelsRadiusOffset,
5152
arcLabelsComponent,
@@ -187,6 +188,7 @@ const InnerPie = <RawDatum extends MayHaveLabel>({
187188
label={arcLabel}
188189
radiusOffset={arcLabelsRadiusOffset}
189190
skipAngle={arcLabelsSkipAngle}
191+
skipRadius={arcLabelsSkipRadius}
190192
textColor={arcLabelsTextColor}
191193
transitionMode={transitionMode}
192194
component={arcLabelsComponent}

packages/pie/src/props.ts

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const defaultProps = {
3030
enableArcLabels: true,
3131
arcLabel: 'formattedValue',
3232
arcLabelsSkipAngle: 0,
33+
arcLabelsSkipRadius: 0,
3334
arcLabelsRadiusOffset: 0.5,
3435
arcLabelsTextColor: { theme: 'labels.text.fill' },
3536

packages/polar-bar/src/PolarBar.tsx

+30-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import { createElement, Fragment, ReactNode } from 'react'
2-
import {
3-
useDimensions,
4-
Container,
5-
SvgWrapper,
6-
} from '@nivo/core'
2+
import { useDimensions, Container, SvgWrapper } from '@nivo/core'
3+
import { BoxLegendSvg } from '@nivo/legends'
4+
import { ArcLabelsLayer } from '@nivo/arcs'
75
import { PolarGrid, RadialAxis, CircularAxis } from '@nivo/polar-axes'
8-
import { PolarBarSvgProps, PolarBarDatum, PolarBarLayerId } from './types'
9-
import { svgDefaultProps } from './props'
6+
import { PolarBarSvgProps, PolarBarDatum, PolarBarLayerId, PolarBarComputedDatum } from './types'
7+
import { svgDefaultProps } from './defaults'
108
import { usePolarBar } from './hooks'
119
import { PolarBarArcs } from './PolarBarArcs'
12-
import { BoxLegendSvg } from '@nivo/legends'
1310

1411
const InnerPolarBar = <RawDatum extends PolarBarDatum>({
1512
data,
@@ -32,6 +29,14 @@ const InnerPolarBar = <RawDatum extends PolarBarDatum>({
3229
borderWidth = svgDefaultProps.borderWidth,
3330
borderColor = svgDefaultProps.borderColor,
3431

32+
enableArcLabels = svgDefaultProps.enableArcLabels,
33+
arcLabel = svgDefaultProps.arcLabel,
34+
arcLabelsSkipAngle = svgDefaultProps.arcLabelsSkipAngle,
35+
arcLabelsSkipRadius = svgDefaultProps.arcLabelsSkipRadius,
36+
arcLabelsTextColor = svgDefaultProps.arcLabelsTextColor,
37+
arcLabelsRadiusOffset = svgDefaultProps.arcLabelsRadiusOffset,
38+
arcLabelsComponent,
39+
3540
enableRadialGrid = svgDefaultProps.enableRadialGrid,
3641
enableCircularGrid = svgDefaultProps.enableCircularGrid,
3742
radialAxisStart = svgDefaultProps.radialAxisStart,
@@ -177,6 +182,23 @@ const InnerPolarBar = <RawDatum extends PolarBarDatum>({
177182
)
178183
}
179184

185+
if (enableArcLabels && layers.includes('labels')) {
186+
layerById.labels = (
187+
<ArcLabelsLayer<PolarBarComputedDatum>
188+
key="labels"
189+
center={center}
190+
data={arcs}
191+
label={arcLabel}
192+
radiusOffset={arcLabelsRadiusOffset}
193+
skipAngle={arcLabelsSkipAngle}
194+
skipRadius={arcLabelsSkipRadius}
195+
textColor={arcLabelsTextColor}
196+
transitionMode={transitionMode}
197+
component={arcLabelsComponent}
198+
/>
199+
)
200+
}
201+
180202
if (layers.includes('legends') && legends.length > 0) {
181203
layerById.legends = (
182204
<Fragment key="legends">

packages/polar-bar/src/props.ts renamed to packages/polar-bar/src/defaults.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const defaultProps: Omit<
66
PolarBarCommonProps<any>,
77
| 'margin'
88
| 'theme'
9+
| 'arcLabelsComponent'
910
| 'onClick'
1011
| 'onMouseEnter'
1112
| 'onMouseMove'
@@ -27,11 +28,16 @@ export const defaultProps: Omit<
2728
layers: ['grid', 'arcs', 'axes', 'labels', 'legends'],
2829

2930
colors: { scheme: 'nivo' },
30-
// defs: [],
31-
// fill: [],
3231
borderWidth: 0,
3332
borderColor: { theme: 'background' },
3433

34+
enableArcLabels: true,
35+
arcLabel: 'formattedValue',
36+
arcLabelsSkipAngle: 0,
37+
arcLabelsSkipRadius: 0,
38+
arcLabelsRadiusOffset: 0.5,
39+
arcLabelsTextColor: { theme: 'labels.text.fill' },
40+
3541
enableRadialGrid: true,
3642
enableCircularGrid: true,
3743
radialAxisStart: {},

packages/polar-bar/src/hooks.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
PolarBarComputedDatum,
1212
PolarBarCustomLayerProps,
1313
} from './types'
14-
import { defaultProps } from './props'
14+
import { defaultProps } from './defaults'
1515

1616
export const usePolarBar = <RawDatum extends PolarBarDatum>({
1717
data,

packages/polar-bar/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './PolarBar'
22
export * from './ResponsivePolarBar'
3-
export * from './props'
3+
export * from './defaults'
44
export * from './types'

packages/polar-bar/src/types.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AriaAttributes, FunctionComponent, MouseEvent } from 'react'
22
import { Box, Theme, Dimensions, PropertyAccessor, MotionProps, ValueFormat } from '@nivo/core'
3-
import { Arc, ArcGenerator, ArcTransitionMode } from '@nivo/arcs'
3+
import { Arc, ArcGenerator, ArcLabelsProps, ArcTransitionMode } from '@nivo/arcs'
44
import { CircularAxisConfig, RadialAxisConfig } from '@nivo/polar-axes'
55
import { OrdinalColorScaleConfig, InheritedColorConfig } from '@nivo/colors'
66
import { ScaleLinear, ScaleBand } from '@nivo/scales'
@@ -66,6 +66,8 @@ export type PolarBarCommonProps<RawDatum extends PolarBarDatum> = {
6666
borderWidth: number
6767
borderColor: InheritedColorConfig<PolarBarComputedDatum>
6868

69+
enableArcLabels: boolean
70+
6971
enableRadialGrid: boolean
7072
enableCircularGrid: boolean
7173
radialAxisStart: RadialAxisConfig | null
@@ -89,7 +91,7 @@ export type PolarBarCommonProps<RawDatum extends PolarBarDatum> = {
8991
ariaLabel: AriaAttributes['aria-label']
9092
ariaLabelledBy: AriaAttributes['aria-labelledby']
9193
ariaDescribedBy: AriaAttributes['aria-describedby']
92-
}
94+
} & ArcLabelsProps<PolarBarComputedDatum>
9395

9496
export type PolarBarSvgProps<RawDatum extends PolarBarDatum> = PolarBarDataProps<RawDatum> &
9597
Dimensions &

packages/sunburst/src/Sunburst.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const InnerSunburst = <RawDatum,>({
4141
arcLabel = defaultProps.arcLabel,
4242
arcLabelsRadiusOffset = defaultProps.arcLabelsRadiusOffset,
4343
arcLabelsSkipAngle = defaultProps.arcLabelsSkipAngle,
44+
arcLabelsSkipRadius = defaultProps.arcLabelsSkipRadius,
4445
arcLabelsTextColor = defaultProps.arcLabelsTextColor,
4546
arcLabelsComponent,
4647
defs = defaultProps.defs,
@@ -119,6 +120,7 @@ const InnerSunburst = <RawDatum,>({
119120
label={arcLabel}
120121
radiusOffset={arcLabelsRadiusOffset}
121122
skipAngle={arcLabelsSkipAngle}
123+
skipRadius={arcLabelsSkipRadius}
122124
textColor={arcLabelsTextColor}
123125
transitionMode={transitionMode}
124126
component={arcLabelsComponent}

packages/sunburst/src/props.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const defaultProps = {
1818
arcLabel: 'formattedValue',
1919
arcLabelsRadiusOffset: 0.5,
2020
arcLabelsSkipAngle: 0,
21+
arcLabelsSkipRadius: 0,
2122
arcLabelsTextColor: { theme: 'labels.text.fill' },
2223
animate: true,
2324
motionConfig: 'gentle',
9.13 KB
Loading

website/src/data/components/pie/props.ts

+16
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,22 @@ const props: ChartProperty[] = [
284284
step: 1,
285285
},
286286
},
287+
{
288+
key: 'arcLabelsSkipRadius',
289+
help: `Skip label if corresponding arc's radius is lower than provided value.`,
290+
flavors: allFlavors,
291+
type: 'number',
292+
required: false,
293+
defaultValue: defaultProps.arcLabelsSkipRadius,
294+
group: 'Arc labels',
295+
control: {
296+
type: 'range',
297+
unit: 'px',
298+
min: 0,
299+
max: 60,
300+
step: 1,
301+
},
302+
},
287303
{
288304
key: 'arcLabelsTextColor',
289305
help: 'Defines how to compute arc label text color.',
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,8 @@
1-
import { generateCountriesData } from '@nivo/generators'
1+
import { generateMonthlyData } from '@nivo/generators'
22

3-
const dishes = [
4-
'hot dog',
5-
'burger',
6-
'sandwich',
7-
'kebab',
8-
'fries',
9-
'donut',
10-
'junk',
11-
'sushi',
12-
'ramen',
13-
'curry',
14-
'udon',
15-
'bagel',
16-
'yakitori',
17-
'takoyaki',
18-
'tacos',
19-
'miso soup',
20-
'tortilla',
21-
'tapas',
22-
'chipirones',
23-
'gazpacho',
24-
'soba',
25-
'bavette',
26-
'steak',
27-
'pizza',
28-
'spaghetti',
29-
'ravioli',
30-
'salad',
31-
'pad thai',
32-
'bun',
33-
'waffle',
34-
'crepe',
35-
'churros',
36-
'paella',
37-
'empanadas',
38-
'bruschetta',
39-
'onion soup',
40-
'cassoulet',
41-
'bouillabaisse',
42-
'unagi',
43-
'tempura',
44-
'tonkatsu',
45-
'shabu-shabu',
46-
'twinkies',
47-
'jerky',
48-
'fajitas',
49-
'jambalaya',
50-
'meatloaf',
51-
`mac n' cheese`,
52-
'baked beans',
53-
'popcorn',
54-
'buffalo wings',
55-
'BBQ ribs',
56-
'apple pie',
57-
'nachos',
58-
'risotto',
59-
'tiramisu',
60-
]
3+
const keys = ['Rent', 'Groceries', 'Transport', 'Savings', 'Misc']
614

625
export const generateLightDataSet = () => ({
63-
data: generateCountriesData(dishes.slice(0, 6), { size: 7, max: 200, withColors: false }),
64-
keys: dishes.slice(0, 5),
65-
})
66-
67-
export const generateHeavyDataSet = () => ({
68-
data: generateCountriesData(dishes, { size: 21, max: 200, withColors: false }),
69-
keys: dishes,
6+
data: generateMonthlyData(keys, { withColors: false, short: true }),
7+
keys,
708
})

0 commit comments

Comments
 (0)