@@ -13,6 +13,7 @@ import {
13
13
LineController ,
14
14
LineElement ,
15
15
PointElement ,
16
+ TimeScale ,
16
17
Title ,
17
18
Tooltip as ChartJSTooltip ,
18
19
} from 'chart.js'
@@ -21,10 +22,16 @@ import { noop, useDebounce } from '@Common/Helper'
21
22
import { DEVTRON_BASE_MAIN_ID } from '@Shared/constants'
22
23
import { useTheme } from '@Shared/Providers'
23
24
24
- import { LEGENDS_LABEL_CONFIG } from './constants'
25
- import { getAverageLinePlugin , getSeparatorLinePlugin } from './plugins'
26
- import { ChartProps , GetDefaultOptionsParams } from './types'
27
- import { buildChartTooltipFromContext , getChartJSType , getDefaultOptions , transformDataForChart } from './utils'
25
+ import { drawReferenceLine } from './plugins'
26
+ import { ChartProps , GetDefaultOptionsParams , TypeAndDatasetsType } from './types'
27
+ import {
28
+ buildChartTooltipFromContext ,
29
+ distanceBetweenPoints ,
30
+ getChartJSType ,
31
+ getDefaultOptions ,
32
+ getLegendsLabelConfig ,
33
+ transformDataForChart ,
34
+ } from './utils'
28
35
29
36
// Register Chart.js components
30
37
ChartJS . register (
@@ -37,19 +44,48 @@ ChartJS.register(
37
44
PointElement ,
38
45
DoughnutController ,
39
46
ArcElement ,
47
+ TimeScale ,
40
48
Title ,
41
49
ChartJSTooltip ,
42
50
Legend ,
43
51
Filler ,
44
52
)
45
53
46
- /**
47
- * The doughnut chart overrides the default legend label configuration.
48
- * Therefore need to set the custom legend label configuration.
49
- */
50
- ChartJS . overrides . doughnut . plugins . legend . labels = {
51
- ...ChartJS . overrides . doughnut . plugins . legend . labels ,
52
- ...LEGENDS_LABEL_CONFIG ,
54
+ ChartJSTooltip . positioners . barElementCenterPositioner = ( items , eventPosition ) => {
55
+ if ( ! items . length ) {
56
+ return false
57
+ }
58
+
59
+ let { x } = eventPosition
60
+ let { y } = eventPosition
61
+ let minDistance = Number . POSITIVE_INFINITY
62
+ let i : number
63
+ let len : number
64
+ let nearestElement : BarElement
65
+
66
+ for ( i = 0 , len = items . length ; i < len ; ++ i ) {
67
+ const el = items [ i ] . element
68
+ if ( el && el . hasValue ( ) ) {
69
+ const center = ( el as BarElement ) . getCenterPoint ( )
70
+ const d = distanceBetweenPoints ( eventPosition , center )
71
+
72
+ if ( d < minDistance ) {
73
+ minDistance = d
74
+ nearestElement = el as BarElement
75
+ }
76
+ }
77
+ }
78
+
79
+ if ( nearestElement ) {
80
+ const tp = nearestElement . getCenterPoint ( )
81
+ x = tp . x
82
+ y = tp . y
83
+ }
84
+
85
+ return {
86
+ x,
87
+ y,
88
+ }
53
89
}
54
90
55
91
/**
@@ -157,15 +193,15 @@ const Chart = (props: ChartProps) => {
157
193
id,
158
194
xAxisLabels : labels ,
159
195
hideAxis = false ,
160
- onChartClick,
161
- separatorIndex,
162
- averageLineValue,
196
+ referenceLines,
197
+ tooltipConfig,
198
+ type,
199
+ datasets,
163
200
xAxisMax,
201
+ xScaleTitle,
164
202
yAxisMax,
165
- tooltipConfig,
166
- ...typeAndDatasets
203
+ yScaleTitle,
167
204
} = props
168
- const { type, datasets } = typeAndDatasets
169
205
const { getTooltipContent, placement } = tooltipConfig || { placement : 'top' }
170
206
171
207
const canvasRef = useRef < HTMLCanvasElement > ( null )
@@ -212,24 +248,34 @@ const Chart = (props: ChartProps) => {
212
248
setTooltipVisible ( true )
213
249
}
214
250
215
- const debouncedExternalTooltipHandler = useDebounce ( externalTooltipHandler , 16 )
251
+ const debouncedExternalTooltipHandler = useDebounce ( externalTooltipHandler , 50 )
216
252
217
253
useEffect ( ( ) => {
218
254
const ctx = canvasRef . current ?. getContext ( '2d' )
219
255
if ( ! ctx ) {
220
256
return noop
221
257
}
222
258
259
+ if ( type === 'pie' ) {
260
+ /**
261
+ * The doughnut chart overrides the default legend label configuration.
262
+ * Therefore need to set the custom legend label configuration.
263
+ */
264
+ ChartJS . overrides . doughnut . plugins . legend . labels = {
265
+ ...ChartJS . overrides . doughnut . plugins . legend . labels ,
266
+ ...getLegendsLabelConfig ( 'pie' , appTheme ) ,
267
+ }
268
+ }
269
+
223
270
// Get Chart.js type and transform data
224
271
const chartJSType = getChartJSType ( type )
225
- const transformedData = { labels, datasets : transformDataForChart ( { ...typeAndDatasets , appTheme } ) }
272
+ const transformedData = {
273
+ labels,
274
+ datasets : transformDataForChart ( { ...( { type, datasets } as TypeAndDatasetsType ) , appTheme } ) ,
275
+ }
226
276
const defaultOptions = getDefaultOptions ( {
227
- type ,
277
+ chartProps : props ,
228
278
appTheme,
229
- hideAxis,
230
- onChartClick,
231
- xAxisMax,
232
- yAxisMax,
233
279
externalTooltipHandler : debouncedExternalTooltipHandler ,
234
280
} )
235
281
@@ -240,15 +286,14 @@ const Chart = (props: ChartProps) => {
240
286
...defaultOptions ,
241
287
} ,
242
288
plugins : [
243
- ...( averageLineValue ? [ getAverageLinePlugin ( averageLineValue , appTheme ) ] : [ ] ) ,
244
- ...( separatorIndex ? [ getSeparatorLinePlugin ( separatorIndex , type , appTheme ) ] : [ ] ) ,
289
+ ...( referenceLines ?? [ ] ) . map ( ( rl , idx ) => drawReferenceLine ( rl , `reference-line-${ idx } ` , appTheme ) ) ,
245
290
] ,
246
291
} )
247
292
248
293
return ( ) => {
249
294
chartRef . current . destroy ( )
250
295
}
251
- } , [ type , datasets , labels , appTheme , hideAxis , averageLineValue , separatorIndex ] )
296
+ } , [ type , datasets , labels , appTheme , hideAxis , referenceLines , xAxisMax , xScaleTitle , yAxisMax , yScaleTitle ] )
252
297
253
298
return (
254
299
< div className = "h-100 w-100 dc__position-rel" >
@@ -260,8 +305,19 @@ const Chart = (props: ChartProps) => {
260
305
placement = { placement }
261
306
appendTo = { document . getElementById ( DEVTRON_BASE_MAIN_ID ) }
262
307
className = "default-tt dc__mxw-400 dc__word-break"
308
+ moveTransition = "transform 200ms cubic-bezier(.42,.61,.64,.81)"
263
309
>
264
- < span ref = { tooltipRef } style = { { position : 'absolute' , left : 0 , top : 0 , width : 0 , height : 0 } } />
310
+ < span
311
+ ref = { tooltipRef }
312
+ style = { {
313
+ position : 'absolute' ,
314
+ left : 0 ,
315
+ top : 0 ,
316
+ width : 0 ,
317
+ height : 0 ,
318
+ willChange : 'transform' ,
319
+ } }
320
+ />
265
321
</ Tippy >
266
322
</ div >
267
323
)
0 commit comments