Skip to content

Commit 4435885

Browse files
committed
chore(bar): refactor layerById to be more like pie
1 parent 75f0dad commit 4435885

File tree

3 files changed

+149
-58
lines changed

3 files changed

+149
-58
lines changed

packages/bar/src/Bar.tsx

Lines changed: 114 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ import { BarAnnotations } from './BarAnnotations'
33
import {
44
BarDatum,
55
BarLayer,
6+
BarLayerId,
67
BarSvgProps,
78
ComputedBarDatum,
89
ComputedBarDatumWithValue,
10+
LegendData,
911
} from './types'
10-
import { BoxLegendSvg } from '@nivo/legends'
12+
import { BarLegends } from './BarLegends'
1113
import {
1214
// @ts-ignore
1315
CartesianMarkers,
1416
Container,
1517
SvgWrapper,
1618
// @ts-ignore
1719
bindDefs,
18-
// defaultMargin,
1920
useDimensions,
2021
useMotionConfig,
2122
usePropertyAccessor,
2223
useTheme,
2324
} from '@nivo/core'
24-
import { Fragment, createElement, useCallback, useMemo, useState } from 'react'
25+
import { Fragment, ReactNode, createElement, useCallback, useMemo, useState } from 'react'
2526
import { generateGroupedBars, generateStackedBars, getLegendData } from './compute'
2627
import { svgDefaultProps } from './props'
2728
import { useInheritedColor, useOrdinalColorScale } from '@nivo/colors'
@@ -173,11 +174,6 @@ const InnerBar = <RawDatum extends BarDatum>({
173174
[enableLabel, labelSkipHeight, labelSkipWidth]
174175
)
175176

176-
const boundDefs = bindDefs(defs, result.bars, fill, {
177-
dataKey: 'data',
178-
targetKey: 'data.fill',
179-
})
180-
181177
const commonProps = {
182178
borderRadius,
183179
borderWidth,
@@ -193,19 +189,28 @@ const InnerBar = <RawDatum extends BarDatum>({
193189
tooltip,
194190
}
195191

196-
const layerById = {
197-
grid: (
198-
<Grid
199-
key="grid"
200-
width={innerWidth}
201-
height={innerHeight}
202-
xScale={enableGridX ? (result.xScale as any) : null}
203-
yScale={enableGridY ? (result.yScale as any) : null}
204-
xValues={gridXValues}
205-
yValues={gridYValues}
206-
/>
207-
),
208-
axes: (
192+
const boundDefs = bindDefs(defs, result.bars, fill, {
193+
dataKey: 'data',
194+
targetKey: 'data.fill',
195+
})
196+
197+
const layerById: Record<BarLayerId, ReactNode> = {
198+
annotations: null,
199+
axes: null,
200+
bars: null,
201+
grid: null,
202+
legends: null,
203+
markers: null,
204+
}
205+
206+
if (layers.includes('annotations')) {
207+
layerById.annotations = (
208+
<BarAnnotations key="annotations" bars={result.bars} annotations={annotations} />
209+
)
210+
}
211+
212+
if (layers.includes('axes')) {
213+
layerById.axes = (
209214
<Axes
210215
key="axes"
211216
xScale={result.xScale as any}
@@ -217,8 +222,11 @@ const InnerBar = <RawDatum extends BarDatum>({
217222
bottom={axisBottom}
218223
left={axisLeft}
219224
/>
220-
),
221-
bars: (
225+
)
226+
}
227+
228+
if (layers.includes('bars')) {
229+
layerById.bars = (
222230
<>
223231
{transition((style, bar) =>
224232
createElement(barComponent, {
@@ -232,8 +240,51 @@ const InnerBar = <RawDatum extends BarDatum>({
232240
})
233241
)}
234242
</>
235-
),
236-
markers: (
243+
)
244+
}
245+
246+
if (layers.includes('grid')) {
247+
layerById.grid = (
248+
<Grid
249+
key="grid"
250+
width={innerWidth}
251+
height={innerHeight}
252+
xScale={enableGridX ? (result.xScale as any) : null}
253+
yScale={enableGridY ? (result.yScale as any) : null}
254+
xValues={gridXValues}
255+
yValues={gridYValues}
256+
/>
257+
)
258+
}
259+
260+
if (layers.includes('legends')) {
261+
const legendData = ([] as LegendData[]).concat(
262+
...legends.map(legend =>
263+
getLegendData({
264+
from: legend.dataFrom,
265+
bars: result.legendData,
266+
layout,
267+
direction: legend.direction,
268+
groupMode,
269+
reverse,
270+
})
271+
)
272+
)
273+
274+
layerById.legends = (
275+
<BarLegends
276+
key="legends"
277+
width={innerWidth}
278+
height={innerHeight}
279+
data={legendData}
280+
legends={legends}
281+
toggleSerie={toggleSerie}
282+
/>
283+
)
284+
}
285+
286+
if (layers.includes('markers')) {
287+
layerById.markers = (
237288
<CartesianMarkers
238289
key="markers"
239290
markers={markers}
@@ -243,35 +294,43 @@ const InnerBar = <RawDatum extends BarDatum>({
243294
yScale={result.yScale}
244295
theme={theme}
245296
/>
246-
),
247-
legends: legends.map((legend, i) => {
248-
const legendData = getLegendData({
249-
from: legend.dataFrom,
250-
bars: result.legendData,
251-
layout,
252-
direction: legend.direction,
253-
groupMode,
254-
reverse,
255-
})
256-
257-
if (legendData === undefined) return null
258-
259-
return (
260-
<BoxLegendSvg
261-
key={i}
262-
{...legend}
263-
containerWidth={innerWidth}
264-
containerHeight={innerHeight}
265-
data={legendData}
266-
toggleSerie={legend.toggleSerie ? toggleSerie : undefined}
267-
/>
268-
)
269-
}),
270-
annotations: (
271-
<BarAnnotations key="annotations" bars={result.bars} annotations={annotations} />
272-
),
297+
)
273298
}
274299

300+
// We use `any` here until we can figure out the best way to type xScale/yScale
301+
const layerContext: any = useMemo(
302+
() => ({
303+
borderRadius,
304+
borderWidth,
305+
enableLabel,
306+
isInteractive,
307+
labelSkipWidth,
308+
labelSkipHeight,
309+
onClick,
310+
onMouseEnter,
311+
onMouseLeave,
312+
getTooltipLabel,
313+
tooltipFormat,
314+
tooltip,
315+
...result,
316+
}),
317+
[
318+
borderRadius,
319+
borderWidth,
320+
enableLabel,
321+
getTooltipLabel,
322+
isInteractive,
323+
labelSkipHeight,
324+
labelSkipWidth,
325+
onClick,
326+
onMouseEnter,
327+
onMouseLeave,
328+
result,
329+
tooltip,
330+
tooltipFormat,
331+
]
332+
)
333+
275334
return (
276335
<SvgWrapper
277336
width={outerWidth}
@@ -282,11 +341,10 @@ const InnerBar = <RawDatum extends BarDatum>({
282341
>
283342
{layers.map((layer, i) => {
284343
if (typeof layer === 'function') {
285-
return (
286-
<Fragment key={i}>{layer({ ...commonProps, ...result } as any)}</Fragment>
287-
)
344+
return <Fragment key={i}>{createElement(layer, layerContext)}</Fragment>
288345
}
289-
return layerById[layer]
346+
347+
return layerById?.[layer] ?? null
290348
})}
291349
</SvgWrapper>
292350
)

packages/bar/src/BarLegends.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { BoxLegendSvg } from '@nivo/legends'
2+
import { BarCommonProps, LegendData } from './types'
3+
4+
interface BarLegendsProps<RawDatum> {
5+
width: number
6+
height: number
7+
legends: BarCommonProps<RawDatum>['legends']
8+
data: LegendData[]
9+
toggleSerie: (id: string | number) => void
10+
}
11+
12+
export const BarLegends = <RawDatum,>({
13+
width,
14+
height,
15+
legends,
16+
data,
17+
toggleSerie,
18+
}: BarLegendsProps<RawDatum>) => {
19+
return (
20+
<>
21+
{legends.map((legend, i) => (
22+
<BoxLegendSvg
23+
key={i}
24+
{...legend}
25+
containerWidth={width}
26+
containerHeight={height}
27+
data={legend.data ?? data}
28+
toggleSerie={legend.toggleSerie ? toggleSerie : undefined}
29+
/>
30+
))}
31+
</>
32+
)
33+
}

packages/bar/src/compute/legends.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const getLegendDataForKeys = <RawDatum>(
1515
// label: bar.data.label || bar.data.id,
1616
label: bar.data.id,
1717
hidden: bar.data.hidden,
18-
color: bar.color,
18+
color: bar.color ?? '#000',
1919
})),
2020
({ id }) => id
2121
)
@@ -41,7 +41,7 @@ export const getLegendDataForIndexes = <RawDatum>(bars: BarsWithHidden<RawDatum>
4141
// label: bar.data.label || bar.data.indexValue,
4242
label: bar.data.indexValue ?? '',
4343
hidden: bar.data.hidden,
44-
color: bar.color,
44+
color: bar.color ?? '#000',
4545
})),
4646
({ id }) => id
4747
)

0 commit comments

Comments
 (0)