1
- import {
2
- BarCanvasLayer ,
3
- BarCanvasProps ,
4
- BarDatum ,
5
- ComputedBarDatum ,
6
- ComputedBarDatumWithValue ,
7
- } from './types'
1
+ import { BarCanvasLayer , BarCanvasProps , BarDatum , ComputedBarDatum } from './types'
8
2
import {
9
3
Container ,
10
4
Margin ,
11
5
getRelativeCursor ,
12
6
isCursorInRect ,
13
7
useDimensions ,
14
- usePropertyAccessor ,
15
8
useTheme ,
16
- useValueFormatter ,
17
9
} from '@nivo/core'
18
10
import {
19
11
ForwardedRef ,
@@ -25,16 +17,15 @@ import {
25
17
useRef ,
26
18
} from 'react'
27
19
import { canvasDefaultProps } from './props'
28
- import { generateGroupedBars , generateStackedBars , getLegendData } from './compute'
29
20
import {
30
21
renderAnnotationsToCanvas ,
31
22
useAnnotations ,
32
23
useComputedAnnotations ,
33
24
} from '@nivo/annotations'
34
25
import { renderAxesToCanvas , renderGridLinesToCanvas } from '@nivo/axes'
35
26
import { renderLegendToCanvas } from '@nivo/legends'
36
- import { useInheritedColor , useOrdinalColorScale } from '@nivo/colors'
37
27
import { useTooltip } from '@nivo/tooltip'
28
+ import { useBar } from './hooks'
38
29
39
30
declare module 'react' {
40
31
// eslint-disable-next-line @typescript-eslint/ban-types
@@ -64,24 +55,24 @@ const isNumber = (value: unknown): value is number => typeof value === 'number'
64
55
65
56
const InnerBarCanvas = < RawDatum extends BarDatum > ( {
66
57
data,
67
- indexBy = canvasDefaultProps . indexBy ,
68
- keys = canvasDefaultProps . keys ,
58
+ indexBy,
59
+ keys,
69
60
70
61
margin : partialMargin ,
71
62
width,
72
63
height,
73
64
74
- groupMode = canvasDefaultProps . groupMode ,
75
- layout = canvasDefaultProps . layout ,
76
- reverse = canvasDefaultProps . reverse ,
77
- minValue = canvasDefaultProps . minValue ,
78
- maxValue = canvasDefaultProps . maxValue ,
65
+ groupMode,
66
+ layout,
67
+ reverse,
68
+ minValue,
69
+ maxValue,
79
70
80
- valueScale = canvasDefaultProps . valueScale ,
81
- indexScale = canvasDefaultProps . indexScale ,
71
+ valueScale,
72
+ indexScale,
82
73
83
- padding = canvasDefaultProps . padding ,
84
- innerPadding = canvasDefaultProps . innerPadding ,
74
+ padding,
75
+ innerPadding,
85
76
86
77
axisTop,
87
78
axisRight,
@@ -146,22 +137,22 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
146
137
}
147
138
} ,
148
139
149
- enableLabel = canvasDefaultProps . enableLabel ,
150
- label = canvasDefaultProps . label ,
151
- labelSkipWidth = canvasDefaultProps . labelSkipWidth ,
152
- labelSkipHeight = canvasDefaultProps . labelSkipHeight ,
153
- labelTextColor = canvasDefaultProps . labelTextColor ,
140
+ enableLabel,
141
+ label,
142
+ labelSkipWidth,
143
+ labelSkipHeight,
144
+ labelTextColor,
154
145
155
- colorBy = canvasDefaultProps . colorBy ,
156
- colors = canvasDefaultProps . colors ,
146
+ colorBy,
147
+ colors,
157
148
borderRadius = canvasDefaultProps . borderRadius ,
158
149
borderWidth = canvasDefaultProps . borderWidth ,
159
- borderColor = canvasDefaultProps . borderColor ,
150
+ borderColor,
160
151
161
152
annotations = canvasDefaultProps . annotations ,
162
153
163
154
legendLabel,
164
- tooltipLabel = canvasDefaultProps . tooltipLabel ,
155
+ tooltipLabel,
165
156
166
157
valueFormat,
167
158
@@ -171,7 +162,7 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
171
162
onMouseEnter,
172
163
onMouseLeave,
173
164
174
- legends = canvasDefaultProps . legends ,
165
+ legends,
175
166
176
167
pixelRatio = canvasDefaultProps . pixelRatio ,
177
168
@@ -186,76 +177,53 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
186
177
partialMargin
187
178
)
188
179
189
- const { showTooltipFromEvent, hideTooltip } = useTooltip ( )
190
-
191
- const formatValue = useValueFormatter ( valueFormat )
192
- const getBorderColor = useInheritedColor < ComputedBarDatumWithValue < RawDatum > > (
180
+ const {
181
+ bars,
182
+ barsWithValue,
183
+ xScale,
184
+ yScale,
185
+ getLabel,
186
+ getTooltipLabel,
187
+ getBorderColor,
188
+ getLabelColor,
189
+ shouldRenderBarLabel,
190
+ legendsWithData,
191
+ } = useBar < RawDatum > ( {
192
+ indexBy,
193
+ label,
194
+ tooltipLabel,
195
+ valueFormat,
196
+ colors,
197
+ colorBy,
193
198
borderColor,
194
- theme
195
- )
196
- const getColor = useOrdinalColorScale ( colors , colorBy )
197
- const getIndex = usePropertyAccessor ( indexBy )
198
- const getLabel = usePropertyAccessor ( label )
199
- const getLabelColor = useInheritedColor < ComputedBarDatumWithValue < RawDatum > > (
200
199
labelTextColor,
201
- theme
202
- )
203
- const getTooltipLabel = usePropertyAccessor ( tooltipLabel )
204
-
205
- const options = {
200
+ groupMode,
206
201
layout,
207
202
reverse,
208
203
data,
209
- getIndex,
210
204
keys,
211
205
minValue,
212
206
maxValue,
207
+ margin,
213
208
width : innerWidth ,
214
209
height : innerHeight ,
215
- getColor,
216
210
padding,
217
211
innerPadding,
218
212
valueScale,
219
213
indexScale,
220
- formatValue,
221
- getTooltipLabel,
222
- }
223
-
224
- const result =
225
- groupMode === 'grouped' ? generateGroupedBars ( options ) : generateStackedBars ( options )
226
-
227
- const legendData = useMemo (
228
- ( ) =>
229
- keys . map ( key => {
230
- const bar = result . bars . find ( bar => bar . data . id === key )
231
-
232
- return { ...bar , data : { id : key , ...bar ?. data , hidden : false } }
233
- } ) ,
234
- [ keys , result . bars ]
235
- )
236
-
237
- const barsWithValue = useMemo (
238
- ( ) =>
239
- result . bars . filter (
240
- ( bar ) : bar is ComputedBarDatumWithValue < RawDatum > => bar . data . value !== null
241
- ) ,
242
- [ result . bars ]
243
- )
214
+ enableLabel,
215
+ labelSkipWidth,
216
+ labelSkipHeight,
217
+ legends,
218
+ legendLabel,
219
+ } )
244
220
245
- const shouldRenderLabel = useCallback (
246
- ( { width, height } : { height : number ; width : number } ) => {
247
- if ( ! enableLabel ) return false
248
- if ( labelSkipWidth > 0 && width < labelSkipWidth ) return false
249
- if ( labelSkipHeight > 0 && height < labelSkipHeight ) return false
250
- return true
251
- } ,
252
- [ enableLabel , labelSkipHeight , labelSkipWidth ]
253
- )
221
+ const { showTooltipFromEvent, hideTooltip } = useTooltip ( )
254
222
255
223
// Using any because return type isn't correct
256
224
const boundAnnotations : any = useComputedAnnotations ( {
257
225
annotations : useAnnotations ( {
258
- data : result . bars ,
226
+ data : bars ,
259
227
annotations,
260
228
getPosition : node => ( {
261
229
x : node . x ,
@@ -288,7 +256,9 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
288
256
innerHeight,
289
257
width,
290
258
height,
291
- ...result ,
259
+ bars,
260
+ xScale,
261
+ yScale,
292
262
} ) ,
293
263
[
294
264
borderRadius ,
@@ -305,7 +275,9 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
305
275
onClick ,
306
276
onMouseEnter ,
307
277
onMouseLeave ,
308
- result ,
278
+ bars ,
279
+ xScale ,
280
+ yScale ,
309
281
tooltip ,
310
282
width ,
311
283
]
@@ -336,7 +308,7 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
336
308
renderGridLinesToCanvas < string | number > ( ctx , {
337
309
width,
338
310
height,
339
- scale : result . xScale as any ,
311
+ scale : xScale as any ,
340
312
axis : 'x' ,
341
313
values : gridXValues ,
342
314
} )
@@ -346,16 +318,16 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
346
318
renderGridLinesToCanvas < string | number > ( ctx , {
347
319
width,
348
320
height,
349
- scale : result . yScale as any ,
321
+ scale : yScale as any ,
350
322
axis : 'y' ,
351
323
values : gridYValues ,
352
324
} )
353
325
}
354
326
}
355
327
} else if ( layer === 'axes' ) {
356
328
renderAxesToCanvas ( ctx , {
357
- xScale : result . xScale as any ,
358
- yScale : result . yScale as any ,
329
+ xScale : xScale as any ,
330
+ yScale : yScale as any ,
359
331
width : innerWidth ,
360
332
height : innerHeight ,
361
333
top : axisTop ,
@@ -373,21 +345,11 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
373
345
borderWidth,
374
346
label : getLabel ( bar . data ) ,
375
347
labelColor : getLabelColor ( bar ) as string ,
376
- shouldRenderLabel : shouldRenderLabel ( bar ) ,
348
+ shouldRenderLabel : shouldRenderBarLabel ( bar ) ,
377
349
} )
378
350
} )
379
351
} else if ( layer === 'legends' ) {
380
- legends . forEach ( legend => {
381
- const data = getLegendData ( {
382
- bars : legendData ,
383
- direction : legend . direction ,
384
- from : legend . dataFrom ,
385
- groupMode,
386
- layout,
387
- legendLabel,
388
- reverse,
389
- } )
390
-
352
+ legendsWithData . forEach ( ( [ legend , data ] ) => {
391
353
renderLegendToCanvas ( ctx , {
392
354
...legend ,
393
355
data,
@@ -427,30 +389,28 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
427
389
layerContext ,
428
390
layers ,
429
391
layout ,
430
- legendData ,
431
- legendLabel ,
432
- legends ,
392
+ legendsWithData ,
433
393
margin . left ,
434
394
margin . top ,
435
395
outerHeight ,
436
396
outerWidth ,
437
397
pixelRatio ,
438
398
renderBar ,
439
- result . xScale ,
440
- result . yScale ,
399
+ xScale ,
400
+ yScale ,
441
401
reverse ,
442
- shouldRenderLabel ,
402
+ shouldRenderBarLabel ,
443
403
theme ,
444
404
width ,
445
405
] )
446
406
447
407
const handleMouseHover = useCallback (
448
408
( event : React . MouseEvent < HTMLCanvasElement > ) => {
449
- if ( ! result . bars ) return
409
+ if ( ! bars ) return
450
410
if ( ! canvasEl . current ) return
451
411
452
412
const [ x , y ] = getRelativeCursor ( canvasEl . current , event )
453
- const bar = findBarUnderCursor ( result . bars , margin , x , y )
413
+ const bar = findBarUnderCursor ( bars , margin , x , y )
454
414
455
415
if ( bar !== undefined ) {
456
416
showTooltipFromEvent (
@@ -470,39 +430,39 @@ const InnerBarCanvas = <RawDatum extends BarDatum>({
470
430
hideTooltip ( )
471
431
}
472
432
} ,
473
- [ hideTooltip , margin , onMouseEnter , result . bars , showTooltipFromEvent , tooltip ]
433
+ [ hideTooltip , margin , onMouseEnter , bars , showTooltipFromEvent , tooltip ]
474
434
)
475
435
476
436
const handleMouseLeave = useCallback (
477
437
( event : React . MouseEvent < HTMLCanvasElement > ) => {
478
- if ( ! result . bars ) return
438
+ if ( ! bars ) return
479
439
if ( ! canvasEl . current ) return
480
440
481
441
hideTooltip ( )
482
442
483
443
const [ x , y ] = getRelativeCursor ( canvasEl . current , event )
484
- const bar = findBarUnderCursor ( result . bars , margin , x , y )
444
+ const bar = findBarUnderCursor ( bars , margin , x , y )
485
445
486
446
if ( bar ) {
487
447
onMouseLeave ?.( bar . data , event )
488
448
}
489
449
} ,
490
- [ hideTooltip , margin , onMouseLeave , result . bars ]
450
+ [ hideTooltip , margin , onMouseLeave , bars ]
491
451
)
492
452
493
453
const handleClick = useCallback (
494
454
( event : React . MouseEvent < HTMLCanvasElement > ) => {
495
- if ( ! result . bars ) return
455
+ if ( ! bars ) return
496
456
if ( ! canvasEl . current ) return
497
457
498
458
const [ x , y ] = getRelativeCursor ( canvasEl . current , event )
499
- const bar = findBarUnderCursor ( result . bars , margin , x , y )
459
+ const bar = findBarUnderCursor ( bars , margin , x , y )
500
460
501
461
if ( bar !== undefined ) {
502
462
onClick ?.( { ...bar . data , color : bar . color } , event )
503
463
}
504
464
} ,
505
- [ margin , onClick , result . bars ]
465
+ [ margin , onClick , bars ]
506
466
)
507
467
508
468
return (
0 commit comments