Skip to content

Commit e142895

Browse files
committed
feat(bar): add support for valueFormat
1 parent 82262a2 commit e142895

File tree

9 files changed

+39
-21
lines changed

9 files changed

+39
-21
lines changed

packages/bar/src/Bar.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
useMotionConfig,
2222
usePropertyAccessor,
2323
useTheme,
24+
useValueFormatter,
2425
} from '@nivo/core'
2526
import { Fragment, ReactNode, createElement, useCallback, useMemo, useState } from 'react'
2627
import { generateGroupedBars, generateStackedBars, getLegendData } from './compute'
@@ -82,8 +83,9 @@ const InnerBar = <RawDatum extends BarDatum>({
8283
legendLabel,
8384
tooltipLabel = svgDefaultProps.tooltipLabel,
8485

86+
valueFormat,
87+
8588
isInteractive = svgDefaultProps.isInteractive,
86-
tooltipFormat,
8789
tooltip = svgDefaultProps.tooltip,
8890
onClick,
8991
onMouseEnter,
@@ -110,6 +112,7 @@ const InnerBar = <RawDatum extends BarDatum>({
110112
partialMargin
111113
)
112114

115+
const formatValue = useValueFormatter(valueFormat)
113116
const getBorderColor = useInheritedColor<ComputedBarDatum<RawDatum>>(borderColor, theme)
114117
const getColor = useOrdinalColorScale(colors, colorBy)
115118
const getIndex = usePropertyAccessor(indexBy)
@@ -134,6 +137,7 @@ const InnerBar = <RawDatum extends BarDatum>({
134137
valueScale,
135138
indexScale,
136139
hiddenIds,
140+
formatValue,
137141
})
138142

139143
const legendData = useMemo(
@@ -198,7 +202,6 @@ const InnerBar = <RawDatum extends BarDatum>({
198202
onMouseEnter,
199203
onMouseLeave,
200204
getTooltipLabel,
201-
tooltipFormat,
202205
tooltip,
203206
}),
204207
[
@@ -213,7 +216,6 @@ const InnerBar = <RawDatum extends BarDatum>({
213216
onMouseEnter,
214217
onMouseLeave,
215218
tooltip,
216-
tooltipFormat,
217219
]
218220
)
219221

packages/bar/src/BarItem.tsx

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export const BarItem = <RawDatum extends BarDatum>({
2525

2626
getTooltipLabel,
2727
tooltip,
28-
tooltipFormat,
2928
}: BarItemProps<RawDatum>) => {
3029
const theme = useTheme()
3130
const { showTooltipFromEvent, hideTooltip } = useTooltip()
@@ -40,20 +39,17 @@ export const BarItem = <RawDatum extends BarDatum>({
4039
const handleTooltip = useCallback(
4140
(event: React.MouseEvent<SVGRectElement>) =>
4241
showTooltipFromEvent(
43-
createElement(tooltip, { ...data, color, getTooltipLabel, tooltipFormat }),
42+
createElement(tooltip, { ...data, color, getTooltipLabel }),
4443
event
4544
),
46-
[color, data, getTooltipLabel, showTooltipFromEvent, tooltip, tooltipFormat]
45+
[color, data, getTooltipLabel, showTooltipFromEvent, tooltip]
4746
)
4847
const handleMouseEnter = useCallback(
4948
(event: React.MouseEvent<SVGRectElement>) => {
5049
onMouseEnter?.(data, event)
51-
showTooltipFromEvent(
52-
createElement(tooltip, { ...data, color, getTooltipLabel, tooltipFormat }),
53-
event
54-
)
50+
showTooltipFromEvent(createElement(tooltip, { ...data, color, getTooltipLabel }), event)
5551
},
56-
[color, data, getTooltipLabel, onMouseEnter, showTooltipFromEvent, tooltip, tooltipFormat]
52+
[color, data, getTooltipLabel, onMouseEnter, showTooltipFromEvent, tooltip]
5753
)
5854
const handleMouseLeave = useCallback(
5955
(event: React.MouseEvent<SVGRectElement>) => {

packages/bar/src/BarTooltip.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@ import { BasicTooltip } from '@nivo/tooltip'
44
export const BarTooltip = <RawDatum,>({
55
color,
66
getTooltipLabel,
7-
tooltipFormat,
87
...data
98
}: BarTooltipProps<RawDatum>) => {
109
return (
1110
<BasicTooltip
1211
id={getTooltipLabel(data)}
13-
value={data.value}
12+
value={data.formattedValue}
1413
enableChip={true}
1514
color={color}
16-
format={tooltipFormat}
1715
/>
1816
)
1917
}

packages/bar/src/compute/grouped.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { computeScale } from '@nivo/scales'
66

77
type Params<RawDatum, XScaleInput, YScaleInput> = {
88
data: RawDatum[]
9+
formatValue: (value: number) => string
910
getColor: OrdinalColorScale<ComputedDatum<RawDatum>>
1011
getIndex: (datum: RawDatum) => string
1112
innerPadding: number
@@ -30,6 +31,7 @@ const zeroIfNotFinite = (value: number) => (isFinite(value) ? value : 0)
3031
const generateVerticalGroupedBars = <RawDatum extends Record<string, unknown>>(
3132
{
3233
data,
34+
formatValue,
3335
getIndex,
3436
keys,
3537
getColor,
@@ -57,6 +59,7 @@ const generateVerticalGroupedBars = <RawDatum extends Record<string, unknown>>(
5759
const barData = {
5860
id: key,
5961
value: rawValue === null ? rawValue : value,
62+
formattedValue: formatValue(value),
6063
index,
6164
indexValue,
6265
data: cleanedData[index],
@@ -84,6 +87,7 @@ const generateVerticalGroupedBars = <RawDatum extends Record<string, unknown>>(
8487
const generateHorizontalGroupedBars = <RawDatum extends Record<string, unknown>>(
8588
{
8689
data,
90+
formatValue,
8791
getIndex,
8892
keys,
8993
getColor,
@@ -111,6 +115,7 @@ const generateHorizontalGroupedBars = <RawDatum extends Record<string, unknown>>
111115
const barData = {
112116
id: key,
113117
value: rawValue === null ? rawValue : value,
118+
formattedValue: formatValue(value),
114119
index,
115120
indexValue,
116121
data: cleanedData[index],
@@ -163,6 +168,7 @@ export const generateGroupedBars = <RawDatum extends BarDatum>({
163168
| 'valueScale'
164169
| 'width'
165170
> & {
171+
formatValue: (value: number) => string
166172
getColor: OrdinalColorScale<ComputedDatum<RawDatum>>
167173
getIndex: (datum: RawDatum) => string
168174
hiddenIds: string[]

packages/bar/src/compute/stacked.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { coerceValue, filterNullValues, getIndexScale, normalizeData } from './c
77
type StackDatum<RawDatum> = SeriesPoint<RawDatum>
88

99
type Params<RawDatum, XScaleInput, YScaleInput> = {
10+
formatValue: (value: number) => string
1011
getColor: OrdinalColorScale<ComputedDatum<RawDatum>>
1112
getIndex: (datum: RawDatum) => string
1213
innerPadding: number
@@ -26,6 +27,7 @@ const filterZerosIfLog = (array: number[], type: string) =>
2627
*/
2728
const generateVerticalStackedBars = <RawDatum extends Record<string, unknown>>(
2829
{
30+
formatValue,
2931
getIndex,
3032
getColor,
3133
innerPadding,
@@ -51,6 +53,7 @@ const generateVerticalStackedBars = <RawDatum extends Record<string, unknown>>(
5153
const barData = {
5254
id: stackedDataItem.key,
5355
value: rawValue === null ? rawValue : value,
56+
formattedValue: formatValue(value),
5457
index: i,
5558
indexValue: index,
5659
data: filterNullValues(d.data),
@@ -77,6 +80,7 @@ const generateVerticalStackedBars = <RawDatum extends Record<string, unknown>>(
7780
*/
7881
const generateHorizontalStackedBars = <RawDatum extends Record<string, unknown>>(
7982
{
83+
formatValue,
8084
getIndex,
8185
getColor,
8286
innerPadding,
@@ -102,6 +106,7 @@ const generateHorizontalStackedBars = <RawDatum extends Record<string, unknown>>
102106
const barData = {
103107
id: stackedDataItem.key,
104108
value: rawValue === null ? rawValue : value,
109+
formattedValue: formatValue(value),
105110
index: i,
106111
indexValue: index,
107112
data: filterNullValues(d.data),
@@ -154,6 +159,7 @@ export const generateStackedBars = <RawDatum extends BarDatum>({
154159
| 'valueScale'
155160
| 'width'
156161
> & {
162+
formatValue: (value: number) => string
157163
getColor: OrdinalColorScale<ComputedDatum<RawDatum>>
158164
getIndex: (datum: RawDatum) => string
159165
hiddenIds: string[]

packages/bar/src/props.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const defaultProps = {
3030
barComponent: BarItem,
3131

3232
enableLabel: true,
33-
label: 'value',
33+
label: 'formattedValue',
3434
labelSkipWidth: 0,
3535
labelSkipHeight: 0,
3636
labelLinkColor: 'theme',

packages/bar/src/types.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export type BarDatumWithColor = BarDatum & {
3131
export type ComputedDatum<RawDatum> = {
3232
id: string | number
3333
value: number | null
34+
formattedValue: string
3435
index: number
3536
indexValue: string | number
3637
data: Exclude<RawDatum, null | undefined | false | '' | 0>
@@ -100,7 +101,6 @@ export interface BarCustomLayerProps<RawDatum>
100101
| 'labelSkipHeight'
101102
| 'labelSkipWidth'
102103
| 'tooltip'
103-
| 'tooltipFormat'
104104
>,
105105
BarHandlers<RawDatum, SVGRectElement> {
106106
bars: ComputedBarDatum<RawDatum>[]
@@ -119,7 +119,7 @@ export type BarLayer<RawDatum> = BarLayerId | BarCustomLayer<RawDatum>
119119
export interface BarItemProps<RawDatum>
120120
extends Pick<
121121
BarCommonProps<RawDatum>,
122-
'borderRadius' | 'borderWidth' | 'isInteractive' | 'tooltip' | 'tooltipFormat'
122+
'borderRadius' | 'borderWidth' | 'isInteractive' | 'tooltip'
123123
>,
124124
ComputedBarDatum<RawDatum>,
125125
BarHandlers<RawDatum, SVGRectElement> {
@@ -146,7 +146,6 @@ export interface BarItemProps<RawDatum>
146146
export interface BarTooltipProps<RawDatum> extends ComputedDatum<RawDatum> {
147147
color: string
148148
getTooltipLabel: (datum: ComputedDatum<RawDatum>) => string | number
149-
tooltipFormat: BarCommonProps<RawDatum>['tooltipFormat']
150149
value: number
151150
}
152151

@@ -199,7 +198,8 @@ export type BarCommonProps<RawDatum> = {
199198
isInteractive: boolean
200199

201200
tooltip: React.FC<BarTooltipProps<RawDatum>>
202-
tooltipFormat?: ValueFormat<string | number | Date>
201+
202+
valueFormat?: ValueFormat<number>
203203

204204
legendLabel?: PropertyAccessor<LegendLabelDatum<RawDatum>, string>
205205
tooltipLabel: PropertyAccessor<ComputedDatum<RawDatum>, string>

packages/bar/stories/bar.stories.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const divergingCommonProps = {
8989
maxValue: 100,
9090
enableGridX: true,
9191
enableGridY: false,
92-
label: d => Math.abs(d.value),
92+
valueFormat: value => Math.abs(value),
9393
labelTextColor: 'inherit:darker(1.2)',
9494
axisTop: {
9595
tickSize: 0,
@@ -136,7 +136,7 @@ stories.add('diverging stacked', () => (
136136
keys={['gained <= 100$', 'gained > 100$', 'lost <= 100$', 'lost > 100$']}
137137
padding={0.4}
138138
colors={['#97e3d5', '#61cdbb', '#f47560', '#e25c3b']}
139-
labelFormat={v => `${v}%`}
139+
valueFormat={v => `${v}%`}
140140
/>
141141
))
142142

@@ -438,3 +438,7 @@ stories.add('custom legend labels', () => (
438438
]}
439439
/>
440440
))
441+
442+
stories.add('with formatted value', () => (
443+
<Bar {...commonProps} valueFormat={value => `${value}`.split('').join('.')} />
444+
))

packages/bar/tests/Bar.test.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ it(`should generate grouped bars correctly when keys are mismatched`, () => {
265265
index: 0,
266266
indexValue: 'one',
267267
value: 10,
268+
formattedValue: '10',
268269
})
269270
expect(bars.at(0).prop('x')).toEqual(24)
270271
expect(bars.at(0).prop('y')).toEqual(0)
@@ -277,6 +278,7 @@ it(`should generate grouped bars correctly when keys are mismatched`, () => {
277278
index: 1,
278279
indexValue: 'two',
279280
value: 9,
281+
formattedValue: '9',
280282
})
281283
expect(bars.at(1).prop('x')).toEqual(333.3333333333333)
282284
expect(bars.at(1).prop('y')).toEqual(30)
@@ -289,6 +291,7 @@ it(`should generate grouped bars correctly when keys are mismatched`, () => {
289291
index: 0,
290292
indexValue: 'one',
291293
value: 3,
294+
formattedValue: '3',
292295
})
293296
expect(bars.at(2).prop('x')).toEqual(166.66666666666666)
294297
expect(bars.at(2).prop('y')).toEqual(210)
@@ -320,6 +323,7 @@ it(`should generate stacked bars correctly when keys are mismatched`, () => {
320323
index: 0,
321324
indexValue: 'one',
322325
value: 10,
326+
formattedValue: '10',
323327
})
324328
expect(bars.at(0).prop('x')).toEqual(24)
325329
expect(bars.at(0).prop('y')).toEqual(69)
@@ -332,6 +336,7 @@ it(`should generate stacked bars correctly when keys are mismatched`, () => {
332336
index: 1,
333337
indexValue: 'two',
334338
value: 9,
339+
formattedValue: '9',
335340
})
336341
expect(bars.at(1).prop('x')).toEqual(262)
337342
expect(bars.at(1).prop('y')).toEqual(92)
@@ -344,6 +349,7 @@ it(`should generate stacked bars correctly when keys are mismatched`, () => {
344349
index: 0,
345350
indexValue: 'one',
346351
value: 3,
352+
formattedValue: '3',
347353
})
348354
expect(bars.at(2).prop('x')).toEqual(24)
349355
expect(bars.at(2).prop('y')).toEqual(0)

0 commit comments

Comments
 (0)