1
1
import { useMemo , useCallback , useState } from 'react'
2
- import { scaleLinear } from 'd3-scale'
3
2
import { useTheme , usePropertyAccessor , useValueFormatter } from '@nivo/core'
4
3
import { useInheritedColor , getContinuousColorScale } from '@nivo/colors'
5
4
import { AnnotationMatcher , useAnnotations } from '@nivo/annotations'
@@ -12,7 +11,12 @@ import {
12
11
SizeVariationConfig ,
13
12
} from './types'
14
13
import { commonDefaultProps } from './defaults'
15
- import { computeCells } from './compute'
14
+ import {
15
+ computeCells ,
16
+ computeSizeScale ,
17
+ getCellAnnotationPosition ,
18
+ getCellAnnotationDimensions ,
19
+ } from './compute'
16
20
17
21
export const useComputeCells = < Datum extends HeatMapDatum , ExtraProps extends object > ( {
18
22
data,
@@ -22,15 +26,15 @@ export const useComputeCells = <Datum extends HeatMapDatum, ExtraProps extends o
22
26
xOuterPadding,
23
27
yInnerPadding,
24
28
yOuterPadding,
29
+ forceSquare,
25
30
} : {
26
31
data : HeatMapDataProps < Datum , ExtraProps > [ 'data' ]
27
32
width : number
28
33
height : number
29
- xInnerPadding : HeatMapCommonProps < Datum > [ 'xInnerPadding' ]
30
- xOuterPadding : HeatMapCommonProps < Datum > [ 'xOuterPadding' ]
31
- yInnerPadding : HeatMapCommonProps < Datum > [ 'yInnerPadding' ]
32
- yOuterPadding : HeatMapCommonProps < Datum > [ 'yOuterPadding' ]
33
- } ) =>
34
+ } & Pick <
35
+ HeatMapCommonProps < Datum > ,
36
+ 'xOuterPadding' | 'xInnerPadding' | 'yOuterPadding' | 'yInnerPadding' | 'forceSquare'
37
+ > ) =>
34
38
useMemo (
35
39
( ) =>
36
40
computeCells < Datum , ExtraProps > ( {
@@ -41,8 +45,18 @@ export const useComputeCells = <Datum extends HeatMapDatum, ExtraProps extends o
41
45
xOuterPadding,
42
46
yInnerPadding,
43
47
yOuterPadding,
48
+ forceSquare,
44
49
} ) ,
45
- [ data , width , height , xInnerPadding , xOuterPadding , yInnerPadding , yOuterPadding ]
50
+ [
51
+ data ,
52
+ width ,
53
+ height ,
54
+ xInnerPadding ,
55
+ xOuterPadding ,
56
+ yInnerPadding ,
57
+ yOuterPadding ,
58
+ forceSquare ,
59
+ ]
46
60
)
47
61
48
62
const isHoverTargetByType = {
@@ -81,74 +95,45 @@ const useSizeScale = (
81
95
min : number ,
82
96
max : number
83
97
) : ( ( value : number | null ) => number ) =>
84
- useMemo ( ( ) => {
85
- if ( ! size ) return ( ) => 1
98
+ useMemo ( ( ) => computeSizeScale ( size , min , max ) , [ size , min , max ] )
86
99
87
- const scale = scaleLinear ( )
88
- . domain ( size . values ? size . values : [ min , max ] )
89
- . range ( size . sizes )
90
-
91
- return ( value : number | null ) => {
92
- if ( value === null ) return 1
93
- return scale ( value )
94
- }
95
- } , [ size , min , max ] )
96
-
97
- export const useHeatMap = <
98
- Datum extends HeatMapDatum = DefaultHeatMapDatum ,
99
- ExtraProps extends object = Record < string , never >
100
- > ( {
101
- data,
100
+ const useCellsStyle = < Datum extends HeatMapDatum = DefaultHeatMapDatum > ( {
101
+ cells,
102
+ minValue,
103
+ maxValue,
104
+ sizeVariation,
105
+ colors,
106
+ emptyColor,
107
+ opacity,
108
+ activeOpacity,
109
+ inactiveOpacity,
110
+ borderColor,
111
+ label,
112
+ labelTextColor,
102
113
valueFormat,
103
- width,
104
- height,
105
- // forceSquare = commonDefaultProps.forceSquare,
106
- xOuterPadding = commonDefaultProps . xOuterPadding ,
107
- xInnerPadding = commonDefaultProps . xInnerPadding ,
108
- yOuterPadding = commonDefaultProps . yOuterPadding ,
109
- yInnerPadding = commonDefaultProps . yInnerPadding ,
110
- sizeVariation = commonDefaultProps . sizeVariation ,
111
- colors = commonDefaultProps . colors as HeatMapCommonProps < Datum > [ 'colors' ] ,
112
- emptyColor = commonDefaultProps . emptyColor ,
113
- opacity = commonDefaultProps . opacity ,
114
- activeOpacity = commonDefaultProps . activeOpacity ,
115
- inactiveOpacity = commonDefaultProps . inactiveOpacity ,
116
- borderColor = commonDefaultProps . borderColor as HeatMapCommonProps < Datum > [ 'borderColor' ] ,
117
- label = commonDefaultProps . label as HeatMapCommonProps < Datum > [ 'label' ] ,
118
- labelTextColor = commonDefaultProps . labelTextColor as HeatMapCommonProps < Datum > [ 'labelTextColor' ] ,
119
- hoverTarget = commonDefaultProps . hoverTarget ,
114
+ activeIds,
120
115
} : {
121
- data : HeatMapDataProps < Datum , ExtraProps > [ 'data' ]
116
+ cells : Omit <
117
+ ComputedCell < Datum > ,
118
+ 'formattedValue' | 'color' | 'opacity' | 'borderColor' | 'label' | 'labelTextColor'
119
+ > [ ]
120
+ minValue : number
121
+ maxValue : number
122
122
valueFormat ?: HeatMapCommonProps < Datum > [ 'valueFormat' ]
123
- width : number
124
- height : number
125
- forceSquare ?: HeatMapCommonProps < Datum > [ 'forceSquare' ]
126
- xOuterPadding ?: HeatMapCommonProps < Datum > [ 'xOuterPadding' ]
127
- xInnerPadding ?: HeatMapCommonProps < Datum > [ 'xInnerPadding' ]
128
- yOuterPadding ?: HeatMapCommonProps < Datum > [ 'yOuterPadding' ]
129
- yInnerPadding ?: HeatMapCommonProps < Datum > [ 'yInnerPadding' ]
130
- sizeVariation ?: HeatMapCommonProps < Datum > [ 'sizeVariation' ]
131
- colors ?: HeatMapCommonProps < Datum > [ 'colors' ]
132
- emptyColor ?: HeatMapCommonProps < Datum > [ 'emptyColor' ]
133
- opacity ?: HeatMapCommonProps < Datum > [ 'opacity' ]
134
- activeOpacity ?: HeatMapCommonProps < Datum > [ 'activeOpacity' ]
135
- inactiveOpacity ?: HeatMapCommonProps < Datum > [ 'inactiveOpacity' ]
136
- borderColor ?: HeatMapCommonProps < Datum > [ 'borderColor' ]
137
- label ?: HeatMapCommonProps < Datum > [ 'label' ]
138
- labelTextColor ?: HeatMapCommonProps < Datum > [ 'labelTextColor' ]
139
- hoverTarget ?: HeatMapCommonProps < Datum > [ 'hoverTarget' ]
140
- } ) => {
141
- const [ activeCell , setActiveCell ] = useState < ComputedCell < Datum > | null > ( null )
142
-
143
- const { cells, xScale, yScale, minValue, maxValue } = useComputeCells < Datum , ExtraProps > ( {
144
- data,
145
- width,
146
- height,
147
- xOuterPadding,
148
- xInnerPadding,
149
- yOuterPadding,
150
- yInnerPadding,
151
- } )
123
+ activeIds : string [ ]
124
+ } & Pick <
125
+ HeatMapCommonProps < Datum > ,
126
+ | 'sizeVariation'
127
+ | 'colors'
128
+ | 'emptyColor'
129
+ | 'opacity'
130
+ | 'activeOpacity'
131
+ | 'inactiveOpacity'
132
+ | 'borderColor'
133
+ | 'label'
134
+ | 'labelTextColor'
135
+ > ) => {
136
+ const getSize = useSizeScale ( sizeVariation , minValue , maxValue )
152
137
153
138
const colorScale = useMemo ( ( ) => {
154
139
if ( typeof colors === 'function' ) return null
@@ -159,14 +144,6 @@ export const useHeatMap = <
159
144
} )
160
145
} , [ colors , minValue , maxValue ] )
161
146
162
- const activeIds = useMemo ( ( ) => {
163
- if ( ! activeCell ) return [ ]
164
-
165
- const isHoverTarget = isHoverTargetByType [ hoverTarget ]
166
-
167
- return cells . filter ( cell => isHoverTarget ( cell , activeCell ) ) . map ( cell => cell . id )
168
- } , [ cells , activeCell , hoverTarget ] )
169
-
170
147
const getColor = useCallback (
171
148
( cell : Omit < ComputedCell < Datum > , 'color' | 'opacity' | 'borderColor' > ) => {
172
149
if ( cell . value !== null ) {
@@ -178,14 +155,14 @@ export const useHeatMap = <
178
155
} ,
179
156
[ colors , colorScale , emptyColor ]
180
157
)
181
- const getSize = useSizeScale ( sizeVariation , minValue , maxValue )
182
158
const theme = useTheme ( )
183
159
const getBorderColor = useInheritedColor ( borderColor , theme )
184
160
const getLabelTextColor = useInheritedColor ( labelTextColor , theme )
161
+
185
162
const formatValue = useValueFormatter ( valueFormat )
186
163
const getLabel = usePropertyAccessor ( label )
187
164
188
- const computedCells = useMemo (
165
+ const styledCells = useMemo (
189
166
( ) =>
190
167
cells . map ( cell => {
191
168
let computedOpacity = opacity
@@ -226,53 +203,111 @@ export const useHeatMap = <
226
203
)
227
204
228
205
return {
229
- cells : computedCells ,
230
- xScale,
231
- yScale,
206
+ cells : styledCells ,
232
207
colorScale,
233
- activeCell,
234
- setActiveCell,
235
208
}
209
+ }
236
210
237
- /*
238
- const layoutConfig = useMemo(() => {
239
- const columns = keys.length
240
- const rows = data.length
211
+ export const useHeatMap = <
212
+ Datum extends HeatMapDatum = DefaultHeatMapDatum ,
213
+ ExtraProps extends object = Record < string , never >
214
+ > ( {
215
+ data,
216
+ valueFormat,
217
+ width : _width ,
218
+ height : _height ,
219
+ xOuterPadding = commonDefaultProps . xOuterPadding ,
220
+ xInnerPadding = commonDefaultProps . xInnerPadding ,
221
+ yOuterPadding = commonDefaultProps . yOuterPadding ,
222
+ yInnerPadding = commonDefaultProps . yInnerPadding ,
223
+ forceSquare = commonDefaultProps . forceSquare ,
224
+ sizeVariation = commonDefaultProps . sizeVariation ,
225
+ colors = commonDefaultProps . colors as HeatMapCommonProps < Datum > [ 'colors' ] ,
226
+ emptyColor = commonDefaultProps . emptyColor ,
227
+ opacity = commonDefaultProps . opacity ,
228
+ activeOpacity = commonDefaultProps . activeOpacity ,
229
+ inactiveOpacity = commonDefaultProps . inactiveOpacity ,
230
+ borderColor = commonDefaultProps . borderColor as HeatMapCommonProps < Datum > [ 'borderColor' ] ,
231
+ label = commonDefaultProps . label as HeatMapCommonProps < Datum > [ 'label' ] ,
232
+ labelTextColor = commonDefaultProps . labelTextColor as HeatMapCommonProps < Datum > [ 'labelTextColor' ] ,
233
+ hoverTarget = commonDefaultProps . hoverTarget ,
234
+ } : {
235
+ data : HeatMapDataProps < Datum , ExtraProps > [ 'data' ]
236
+ width : number
237
+ height : number
238
+ } & Partial <
239
+ Pick <
240
+ HeatMapCommonProps < Datum > ,
241
+ | 'valueFormat'
242
+ | 'xOuterPadding'
243
+ | 'xInnerPadding'
244
+ | 'yOuterPadding'
245
+ | 'yInnerPadding'
246
+ | 'forceSquare'
247
+ | 'sizeVariation'
248
+ | 'colors'
249
+ | 'emptyColor'
250
+ | 'opacity'
251
+ | 'activeOpacity'
252
+ | 'inactiveOpacity'
253
+ | 'borderColor'
254
+ | 'label'
255
+ | 'labelTextColor'
256
+ | 'hoverTarget'
257
+ >
258
+ > ) => {
259
+ const [ activeCell , setActiveCell ] = useState < ComputedCell < Datum > | null > ( null )
241
260
242
- let cellWidth = Math.max((width - padding * (columns + 1)) / columns, 0)
243
- let cellHeight = Math.max((height - padding * (rows + 1)) / rows, 0)
261
+ const { width, height, offsetX, offsetY, cells, xScale, yScale, minValue, maxValue } =
262
+ useComputeCells < Datum , ExtraProps > ( {
263
+ data,
264
+ width : _width ,
265
+ height : _height ,
266
+ xOuterPadding,
267
+ xInnerPadding,
268
+ yOuterPadding,
269
+ yInnerPadding,
270
+ forceSquare,
271
+ } )
244
272
245
- let offsetX = 0
246
- let offsetY = 0
247
- if (forceSquare === true) {
248
- const cellSize = Math.min(cellWidth, cellHeight)
249
- cellWidth = cellSize
250
- cellHeight = cellSize
273
+ const activeIds = useMemo ( ( ) => {
274
+ if ( ! activeCell ) return [ ]
251
275
252
- offsetX = (width - ((cellWidth + padding) * columns + padding)) / 2
253
- offsetY = (height - ((cellHeight + padding) * rows + padding)) / 2
254
- }
276
+ const isHoverTarget = isHoverTargetByType [ hoverTarget ]
255
277
256
- return {
257
- cellWidth,
258
- cellHeight,
259
- offsetX,
260
- offsetY,
261
- }
262
- }, [data, keys, width, height, padding, forceSquare])
263
- */
264
- }
278
+ return cells . filter ( cell => isHoverTarget ( cell , activeCell ) ) . map ( cell => cell . id )
279
+ } , [ cells , activeCell , hoverTarget ] )
265
280
266
- const getCellAnnotationPosition = < Datum extends HeatMapDatum > ( cell : ComputedCell < Datum > ) => ( {
267
- x : cell . x ,
268
- y : cell . y ,
269
- } )
281
+ const { cells : computedCells , colorScale } = useCellsStyle < Datum > ( {
282
+ cells,
283
+ minValue,
284
+ maxValue,
285
+ sizeVariation,
286
+ colors,
287
+ emptyColor,
288
+ opacity,
289
+ activeOpacity,
290
+ inactiveOpacity,
291
+ borderColor,
292
+ label,
293
+ labelTextColor,
294
+ valueFormat,
295
+ activeIds,
296
+ } )
270
297
271
- const getCellAnnotationDimensions = < Datum extends HeatMapDatum > ( cell : ComputedCell < Datum > ) => ( {
272
- size : Math . max ( cell . width , cell . height ) ,
273
- width : cell . width ,
274
- height : cell . height ,
275
- } )
298
+ return {
299
+ width,
300
+ height,
301
+ offsetX,
302
+ offsetY,
303
+ cells : computedCells ,
304
+ xScale,
305
+ yScale,
306
+ colorScale,
307
+ activeCell,
308
+ setActiveCell,
309
+ }
310
+ }
276
311
277
312
export const useCellAnnotations = < Datum extends HeatMapDatum > (
278
313
cells : ComputedCell < Datum > [ ] ,
0 commit comments