1
1
import dayjs from "dayjs" ;
2
2
import isoWeek from "dayjs/plugin/isoWeek" ;
3
3
import * as echarts from "echarts" ;
4
+ import { useDarkMode } from "lib/DarkModeContext" ;
5
+ import darkThemeHud from "lib/chartTheme" ;
4
6
import { useEffect , useRef , useState } from "react" ;
5
7
6
8
dayjs . extend ( isoWeek ) ;
@@ -28,6 +30,7 @@ export function QueueTimeEchartElement({
28
30
const chartRef = useRef ( null ) ; // Create a ref for the chart container
29
31
const chartInstanceRef = useRef < echarts . EChartsType | null > ( null ) ;
30
32
const [ rawData , setRawData ] = useState < any > ( null ) ;
33
+ const { darkMode } = useDarkMode ( ) ;
31
34
32
35
const queue_axis_value = generateExponential ( ) ;
33
36
@@ -41,14 +44,23 @@ export function QueueTimeEchartElement({
41
44
setRawData ( data ) ;
42
45
} , [ data , granularity ] ) ;
43
46
47
+ // Initialize chart instance and handle resize events
44
48
useEffect ( ( ) => {
45
49
if ( ! chartRef . current ) return ;
46
50
47
- // Prevent duplicate init
48
- echarts . dispose ( chartRef . current ) ;
49
- const instance = echarts . init ( chartRef . current ) ;
51
+ // Dispose of any existing chart instance
52
+ if ( chartInstanceRef . current ) {
53
+ chartInstanceRef . current . dispose ( ) ;
54
+ }
55
+
56
+ // Create new chart with appropriate theme
57
+ const instance = echarts . init (
58
+ chartRef . current ,
59
+ darkMode ? darkThemeHud : undefined
60
+ ) ;
50
61
chartInstanceRef . current = instance ;
51
62
63
+ // Set up resize handlers
52
64
const handleResize = ( ) => {
53
65
instance . resize ( ) ;
54
66
} ;
@@ -59,77 +71,30 @@ export function QueueTimeEchartElement({
59
71
} ) ;
60
72
resizeObserver . observe ( chartRef . current ) ;
61
73
74
+ // If we have data already, update the chart
75
+ if ( rawData && rawData . length > 0 ) {
76
+ updateChart ( instance , rawData , chartType , granularity , queue_axis_value ) ;
77
+ }
78
+
62
79
return ( ) => {
63
80
resizeObserver . disconnect ( ) ;
64
81
window . removeEventListener ( "resize" , handleResize ) ;
65
82
instance . dispose ( ) ;
66
83
} ;
67
- } , [ ] ) ;
84
+ } , [ darkMode ] ) ;
68
85
86
+ // Update chart options when data or chart type changes
69
87
useEffect ( ( ) => {
70
88
if ( ! rawData || rawData . length === 0 || ! chartInstanceRef . current ) return ;
71
- const instance = chartInstanceRef . current ;
72
-
73
- if ( rawData . length == 0 ) {
74
- return ;
75
- }
76
89
77
- const startTime = getTruncTime ( dayjs ( rawData [ 0 ] . time ) , granularity ) ;
78
- const endTime = getTruncTime (
79
- dayjs ( rawData [ rawData . length - 1 ] . time ) ,
80
- granularity
81
- ) ;
82
- const chartData = generateFilledTimeSeries (
83
- startTime ,
84
- endTime ,
90
+ updateChart (
91
+ chartInstanceRef . current ,
85
92
rawData ,
86
- granularity
93
+ chartType ,
94
+ granularity ,
95
+ queue_axis_value
87
96
) ;
88
- const timeDates = generateTimePoints ( startTime , endTime , granularity ) ;
89
-
90
- let chartRenderOptions = { } ;
91
- switch ( chartType ) {
92
- case "heatmap" :
93
- chartRenderOptions = getHeatMapOptions (
94
- chartData ,
95
- queue_axis_value ,
96
- timeDates
97
- ) ;
98
- break ;
99
- case "histogram_bar_vertical" :
100
- const aggre_hist = sumArrayValues ( rawData ) ;
101
- chartRenderOptions = getBarOptions ( aggre_hist , queue_axis_value ) ;
102
- break ;
103
- case "histogram_bar_horizontal" :
104
- const aggre_hist_bar = sumArrayValues ( rawData ) ;
105
- chartRenderOptions = getBarChartHorizontal (
106
- aggre_hist_bar ,
107
- queue_axis_value
108
- ) ;
109
- break ;
110
- case "count_job_line" :
111
- const jobCountData = generateFilledTimeSeriesLine (
112
- startTime ,
113
- endTime ,
114
- rawData ,
115
- granularity ,
116
- "total_count"
117
- ) ;
118
- chartRenderOptions = getLineChart ( jobCountData , timeDates ) ;
119
- break ;
120
- case "max_queue_time_line" :
121
- const maxQueueTimeData = generateFilledTimeSeriesLine (
122
- startTime ,
123
- endTime ,
124
- rawData ,
125
- granularity ,
126
- "max_queue_time"
127
- ) ;
128
- chartRenderOptions = getLineChart ( maxQueueTimeData , timeDates ) ;
129
- break ;
130
- }
131
- instance . setOption ( chartRenderOptions , true ) ;
132
- } , [ rawData , chartType ] ) ;
97
+ } , [ rawData , chartType , granularity ] ) ;
133
98
134
99
const height = queue_axis_value . length * 10 ;
135
100
return (
@@ -144,6 +109,73 @@ export function QueueTimeEchartElement({
144
109
) ;
145
110
}
146
111
112
+ // Extracted chart update logic to avoid code duplication
113
+ function updateChart (
114
+ instance : echarts . EChartsType ,
115
+ rawData : any [ ] ,
116
+ chartType : string ,
117
+ granularity : string ,
118
+ queue_axis_value : string [ ]
119
+ ) {
120
+ if ( rawData . length === 0 ) return ;
121
+
122
+ const startTime = getTruncTime ( dayjs ( rawData [ 0 ] . time ) , granularity ) ;
123
+ const endTime = getTruncTime (
124
+ dayjs ( rawData [ rawData . length - 1 ] . time ) ,
125
+ granularity
126
+ ) ;
127
+ const chartData = generateFilledTimeSeries (
128
+ startTime ,
129
+ endTime ,
130
+ rawData ,
131
+ granularity
132
+ ) ;
133
+ const timeDates = generateTimePoints ( startTime , endTime , granularity ) ;
134
+
135
+ let chartRenderOptions = { } ;
136
+ switch ( chartType ) {
137
+ case "heatmap" :
138
+ chartRenderOptions = getHeatMapOptions (
139
+ chartData ,
140
+ queue_axis_value ,
141
+ timeDates
142
+ ) ;
143
+ break ;
144
+ case "histogram_bar_vertical" :
145
+ const aggre_hist = sumArrayValues ( rawData ) ;
146
+ chartRenderOptions = getBarOptions ( aggre_hist , queue_axis_value ) ;
147
+ break ;
148
+ case "histogram_bar_horizontal" :
149
+ const aggre_hist_bar = sumArrayValues ( rawData ) ;
150
+ chartRenderOptions = getBarChartHorizontal (
151
+ aggre_hist_bar ,
152
+ queue_axis_value
153
+ ) ;
154
+ break ;
155
+ case "count_job_line" :
156
+ const jobCountData = generateFilledTimeSeriesLine (
157
+ startTime ,
158
+ endTime ,
159
+ rawData ,
160
+ granularity ,
161
+ "total_count"
162
+ ) ;
163
+ chartRenderOptions = getLineChart ( jobCountData , timeDates ) ;
164
+ break ;
165
+ case "max_queue_time_line" :
166
+ const maxQueueTimeData = generateFilledTimeSeriesLine (
167
+ startTime ,
168
+ endTime ,
169
+ rawData ,
170
+ granularity ,
171
+ "max_queue_time"
172
+ ) ;
173
+ chartRenderOptions = getLineChart ( maxQueueTimeData , timeDates ) ;
174
+ break ;
175
+ }
176
+ instance . setOption ( chartRenderOptions , true ) ;
177
+ }
178
+
147
179
const getLineChart = ( data : any [ ] , xAxisLabels : string [ ] ) => {
148
180
return {
149
181
tooltip : {
0 commit comments