perf: chart

This commit is contained in:
hamster1963 2024-10-14 17:29:55 +08:00
parent f54fb11041
commit 36b929a9d2

View File

@ -30,6 +30,7 @@ import { useRouter } from "next/navigation";
import * as React from "react";
import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts";
import useSWR from "swr";
import { useMemo, useCallback } from 'react';
interface ResultItem {
created_at: number;
@ -138,7 +139,7 @@ export function NetworkChartClient({ server_id }: { server_id: number }) {
);
}
export function NetworkChart({
export const NetworkChart = React.memo(function NetworkChart({
chartDataKey,
chartConfig,
chartData,
@ -159,18 +160,59 @@ export function NetworkChart({
const [activeChart, setActiveChart] = React.useState(defaultChart);
const handleButtonClick = (chart: string) => {
if (chart === activeChart) {
setActiveChart(defaultChart);
} else {
setActiveChart(chart);
}
};
const handleButtonClick = useCallback((chart: string) => {
setActiveChart(prev => prev === chart ? defaultChart : chart);
}, [defaultChart]);
const getColorByIndex = (chart: string) => {
const getColorByIndex = useCallback((chart: string) => {
const index = chartDataKey.indexOf(chart);
return `hsl(var(--chart-${(index % 10) + 1}))`;
};
}, [chartDataKey]);
const chartButtons = useMemo(() => (
chartDataKey.map((key) => (
<button
key={key}
data-active={activeChart === key}
className={`relative z-30 flex flex-1 flex-col justify-center gap-1 border-b px-6 py-4 text-left data-[active=true]:bg-muted/50 sm:border-l sm:border-t-0 sm:px-6`}
onClick={() => handleButtonClick(key)}
>
<span className="whitespace-nowrap text-xs text-muted-foreground">
{key}
</span>
<span className="text-md font-bold leading-none sm:text-lg">
{chartData[key][chartData[key].length - 1].avg_delay.toFixed(2)}ms
</span>
</button>
))
), [chartDataKey, activeChart, chartData, handleButtonClick]);
const chartLines = useMemo(() => {
if (activeChart !== defaultChart) {
return (
<Line
isAnimationActive={false}
strokeWidth={1}
type="linear"
dot={false}
dataKey="avg_delay"
stroke={getColorByIndex(activeChart)}
/>
);
}
return chartDataKey.map((key) => (
<Line
key={key}
isAnimationActive={false}
strokeWidth={1}
type="linear"
dot={false}
dataKey={key}
stroke={getColorByIndex(key)}
connectNulls={true}
/>
));
}, [activeChart, defaultChart, chartDataKey, getColorByIndex]);
return (
<Card>
@ -190,26 +232,7 @@ export function NetworkChart({
</CardDescription>
</div>
<div className="flex flex-wrap">
{chartDataKey.map((key) => {
return (
<button
key={key}
data-active={activeChart === key}
className={`relative z-30 flex flex-1 flex-col justify-center gap-1 border-b px-6 py-4 text-left data-[active=true]:bg-muted/50 sm:border-l sm:border-t-0 sm:px-6`}
onClick={() => handleButtonClick(key)}
>
<span className="whitespace-nowrap text-xs text-muted-foreground">
{key}
</span>
<span className="text-md font-bold leading-none sm:text-lg">
{chartData[key][chartData[key].length - 1].avg_delay.toFixed(
2,
)}
ms
</span>
</button>
);
})}
{chartButtons}
</div>
</CardHeader>
<CardContent className="px-2 sm:p-6">
@ -219,15 +242,8 @@ export function NetworkChart({
>
<LineChart
accessibilityLayer
data={
activeChart === defaultChart
? formattedData
: chartData[activeChart]
}
margin={{
left: 12,
right: 12,
}}
data={activeChart === defaultChart ? formattedData : chartData[activeChart]}
margin={{ left: 12, right: 12 }}
>
<CartesianGrid vertical={false} />
<XAxis
@ -262,32 +278,10 @@ export function NetworkChart({
{activeChart === defaultChart && (
<ChartLegend content={<ChartLegendContent />} />
)}
{activeChart !== defaultChart && (
<Line
isAnimationActive={false}
strokeWidth={1}
type="linear"
dot={false}
dataKey="avg_delay"
stroke={getColorByIndex(activeChart)}
/>
)}
{activeChart === defaultChart &&
chartDataKey.map((key) => (
<Line
key={key}
isAnimationActive={false}
strokeWidth={1}
type="linear"
dot={false}
dataKey={key}
stroke={getColorByIndex(key)}
connectNulls={true}
/>
))}
{chartLines}
</LineChart>
</ChartContainer>
</CardContent>
</Card>
);
}
});