Skip to content

Commit 0b181d8

Browse files
committed
fix(costume-bar-chart): simplify chart rendering logic and remove unused state management
1 parent b9cee35 commit 0b181d8

File tree

1 file changed

+4
-84
lines changed

1 file changed

+4
-84
lines changed

dashboard/src/components/charts/costume-bar-chart.tsx

Lines changed: 4 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useEffect, useRef, useState, useCallback, useMemo } from 'react'
1+
import { useEffect, useState, useCallback, useMemo } from 'react'
22
import { Bar, BarChart, CartesianGrid, XAxis, YAxis, TooltipProps } from 'recharts'
33
import { DateRange } from 'react-day-picker'
44
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
@@ -107,15 +107,12 @@ function CustomBarTooltip({ active, payload, period }: TooltipProps<number, stri
107107
}
108108

109109
export function CostumeBarChart({ nodeId }: CostumeBarChartProps) {
110-
const [chartKey, setChartKey] = useState(0)
111110
const [selectedAdmin, setSelectedAdmin] = useState<string>('all')
112111
const [selectedTime, setSelectedTime] = useState<TrafficShortcutKey>('1w')
113112
const [showCustomRange, setShowCustomRange] = useState(false)
114113
const [customRange, setCustomRange] = useState<DateRange | undefined>(undefined)
115114
const [windowWidth, setWindowWidth] = useState<number>(() => (typeof window !== 'undefined' ? window.innerWidth : 1024))
116115

117-
const chartContainerRef = useRef<HTMLDivElement>(null)
118-
119116
const { t, i18n } = useTranslation()
120117
const dir = useDirDetection()
121118
const shouldUseNodeUsage = selectedAdmin === 'all'
@@ -221,94 +218,18 @@ export function CostumeBarChart({ nodeId }: CostumeBarChartProps) {
221218
return getXAxisIntervalForShortcut(selectedTime, chartData.length, { minuteForOneHour: true })
222219
}, [showCustomRange, customRange, activePeriod, chartData.length, selectedTime, windowWidth])
223220

224-
const refreshChartInstant = useCallback(() => {
225-
if (chartData.length > 0) {
226-
setChartKey(previous => previous + 1)
227-
}
228-
}, [chartData.length])
229-
230-
const lastRerenderTime = useRef<number>(0)
231-
const rerenderTimeout = useRef<NodeJS.Timeout>()
232-
233-
const refreshChartThrottled = useCallback(() => {
234-
const now = Date.now()
235-
236-
if (now - lastRerenderTime.current < 100) {
237-
if (rerenderTimeout.current) {
238-
clearTimeout(rerenderTimeout.current)
239-
}
240-
rerenderTimeout.current = setTimeout(() => {
241-
refreshChartThrottled()
242-
}, 100)
243-
return
244-
}
245-
246-
if (chartData.length > 0) {
247-
lastRerenderTime.current = now
248-
setChartKey(previous => previous + 1)
249-
}
250-
}, [chartData.length])
251-
252221
useEffect(() => {
253-
let resizeTimeout: NodeJS.Timeout
254-
255222
const handleResize = () => {
256223
setWindowWidth(window.innerWidth)
257-
clearTimeout(resizeTimeout)
258-
resizeTimeout = setTimeout(() => {
259-
refreshChartThrottled()
260-
}, 150)
261224
}
262225

226+
handleResize()
263227
window.addEventListener('resize', handleResize)
264228

265-
const resizeObserver = new ResizeObserver(entries => {
266-
for (const entry of entries) {
267-
if (entry.target === chartContainerRef.current) {
268-
const { width, height } = entry.contentRect
269-
if (width > 0 && height > 0) {
270-
handleResize()
271-
}
272-
}
273-
}
274-
})
275-
276-
if (chartContainerRef.current) {
277-
resizeObserver.observe(chartContainerRef.current)
278-
}
279-
280-
const mutationObserver = new MutationObserver(mutations => {
281-
const hasSidebarChange = mutations.some(mutation => mutation.type === 'attributes' && (mutation.attributeName === 'class' || mutation.attributeName === 'data-state'))
282-
if (hasSidebarChange) {
283-
refreshChartInstant()
284-
}
285-
})
286-
287-
mutationObserver.observe(document.body, {
288-
attributes: true,
289-
attributeFilter: ['class', 'data-sidebar-state', 'data-state'],
290-
childList: false,
291-
subtree: false,
292-
})
293-
294-
const sidebar = document.querySelector('[data-sidebar]') || document.querySelector('aside')
295-
if (sidebar) {
296-
mutationObserver.observe(sidebar, {
297-
attributes: true,
298-
attributeFilter: ['class', 'data-state'],
299-
})
300-
}
301-
302229
return () => {
303-
clearTimeout(resizeTimeout)
304-
if (rerenderTimeout.current) {
305-
clearTimeout(rerenderTimeout.current)
306-
}
307230
window.removeEventListener('resize', handleResize)
308-
resizeObserver.disconnect()
309-
mutationObserver.disconnect()
310231
}
311-
}, [refreshChartThrottled, refreshChartInstant])
232+
}, [])
312233

313234
const handleTimeSelect = useCallback((value: string) => {
314235
setSelectedTime(value as TrafficShortcutKey)
@@ -364,7 +285,7 @@ export function CostumeBarChart({ nodeId }: CostumeBarChartProps) {
364285
</span>
365286
</div>
366287
</CardHeader>
367-
<CardContent ref={chartContainerRef} dir={dir} className="px-4 pt-4 sm:px-6 sm:pt-8">
288+
<CardContent dir={dir} className="px-4 pt-4 sm:px-6 sm:pt-8">
368289
{isLoading ? (
369290
<div className="flex max-h-[300px] min-h-[150px] w-full items-center justify-center sm:max-h-[400px] sm:min-h-[200px]">
370291
<Skeleton className="h-[250px] w-full sm:h-[300px]" />
@@ -374,7 +295,6 @@ export function CostumeBarChart({ nodeId }: CostumeBarChartProps) {
374295
) : (
375296
<div className="mx-auto w-full max-w-7xl">
376297
<ChartContainer
377-
key={chartKey}
378298
dir="ltr"
379299
config={chartConfig}
380300
className="max-h-[300px] min-h-[150px] w-full overflow-x-auto sm:max-h-[400px] sm:min-h-[200px]"

0 commit comments

Comments
 (0)