diff --git a/app/[locale]/(main)/ClientComponents/NetworkChart.tsx b/app/[locale]/(main)/ClientComponents/NetworkChart.tsx index c77d00b..71e4de3 100644 --- a/app/[locale]/(main)/ClientComponents/NetworkChart.tsx +++ b/app/[locale]/(main)/ClientComponents/NetworkChart.tsx @@ -17,7 +17,7 @@ import { ChartTooltipContent, } from "@/components/ui/chart"; import useSWR from "swr"; -import { ServerMonitorChart } from "../../types/nezha-api"; +import { NezhaAPIMonitor, ServerMonitorChart } from "../../types/nezha-api"; import { formatTime, nezhaFetcher } from "@/lib/utils"; import { formatRelativeTime } from "@/lib/utils"; import { BackIcon } from "@/components/Icon"; @@ -26,9 +26,14 @@ import { useLocale } from "next-intl"; import { useTranslations } from "next-intl"; import NetworkChartLoading from "./NetworkChartLoading"; +interface ResultItem { + created_at: number; + [key: string]: number; +} + export function NetworkChartClient({ server_id }: { server_id: number }) { const t = useTranslations("NetworkChartClient"); - const { data, error } = useSWR( + const { data, error } = useSWR( `/api/monitor?server_id=${server_id}`, nezhaFetcher, ); @@ -41,19 +46,64 @@ export function NetworkChartClient({ server_id }: { server_id: number }) { ); if (!data) return ; + function transformData(data: NezhaAPIMonitor[]) { + const monitorData: ServerMonitorChart = {}; + + data.forEach((item) => { + const monitorName = item.monitor_name; + + if (!monitorData[monitorName]) { + monitorData[monitorName] = []; + } + + for (let i = 0; i < item.created_at.length; i++) { + monitorData[monitorName].push({ + created_at: item.created_at[i], + avg_delay: item.avg_delay[i], + }); + } + }); + + return monitorData; + } + + const formatData = (rawData: NezhaAPIMonitor[]) => { + const result: { [time: number]: ResultItem } = {}; + + // 遍历每个监控项 + rawData.forEach((item) => { + const { monitor_name, created_at, avg_delay } = item; + + created_at.forEach((time, index) => { + if (!result[time]) { + result[time] = { created_at: time }; + } + result[time][monitor_name] = parseFloat(avg_delay[index].toFixed(2)); + }); + }); + + return Object.values(result).sort((a, b) => a.created_at - b.created_at); + }; + + const transformedData = transformData(data); + + const formattedData = formatData(data); + const initChartConfig = { avg_delay: { label: t("avg_delay"), }, } satisfies ChartConfig; - const chartDataKey = Object.keys(data); + const chartDataKey = Object.keys(transformedData); return ( ); } @@ -62,22 +112,34 @@ export function NetworkChart({ chartDataKey, chartConfig, chartData, + serverName, + formattedData, }: { chartDataKey: string[]; chartConfig: ChartConfig; chartData: ServerMonitorChart; + serverName: string; + formattedData: ResultItem[]; }) { const t = useTranslations("NetworkChart"); const router = useRouter(); const locale = useLocale(); - const [activeChart, setActiveChart] = React.useState< - keyof typeof chartConfig - >(chartDataKey[0]); + const defaultChart = "All"; + + const [activeChart, setActiveChart] = React.useState(defaultChart); + + const handleButtonClick = (chart: string) => { + if (chart === activeChart) { + setActiveChart(defaultChart); + } else { + setActiveChart(chart); + } + }; const getColorByIndex = (chart: string) => { const index = chartDataKey.indexOf(chart); - return `hsl(var(--chart-${(index % 5) + 1}))`; + return `hsl(var(--chart-${(index % 10) + 1}))`; }; return ( @@ -91,24 +153,23 @@ export function NetworkChart({ className="flex flex-none cursor-pointer items-center gap-0.5 text-xl" > - {chartData[chartDataKey[0]][0].server_name} + {serverName} {chartDataKey.length} {t("ServerMonitorCount")}
- {chartDataKey.map((key, index) => { - const chart = key as keyof typeof chartConfig; + {chartDataKey.map((key) => { return (
{item.value && ( - + {item.value.toLocaleString()} )} diff --git a/lib/serverFetch.tsx b/lib/serverFetch.tsx index 7103c7d..bb20858 100644 --- a/lib/serverFetch.tsx +++ b/lib/serverFetch.tsx @@ -1,11 +1,6 @@ "use server"; -import { - NezhaAPI, - NezhaAPIMonitor, - ServerApi, - ServerMonitorChart, -} from "../app/[locale]/types/nezha-api"; +import { NezhaAPI, ServerApi } from "../app/[locale]/types/nezha-api"; import { MakeOptional } from "../app/[locale]/types/utils"; import { unstable_noStore as noStore } from "next/cache"; import getEnv from "./env-entry"; @@ -71,28 +66,6 @@ export async function GetNezhaData() { } export async function GetServerMonitor({ server_id }: { server_id: number }) { - function transformData(data: NezhaAPIMonitor[]) { - const monitorData: ServerMonitorChart = {}; - - data.forEach((item) => { - const monitorName = item.monitor_name; - - if (!monitorData[monitorName]) { - monitorData[monitorName] = []; - } - - for (let i = 0; i < item.created_at.length; i++) { - monitorData[monitorName].push({ - server_name: item.server_name, - created_at: item.created_at[i], - avg_delay: item.avg_delay[i], - }); - } - }); - - return monitorData; - } - var nezhaBaseUrl = getEnv("NezhaBaseUrl"); if (!nezhaBaseUrl) { console.log("NezhaBaseUrl is not set"); @@ -122,7 +95,7 @@ export async function GetServerMonitor({ server_id }: { server_id: number }) { console.log(resData); return { error: "MonitorData fetch failed" }; } - return transformData(monitorData); + return monitorData; } catch (error) { return error; } diff --git a/package.json b/package.json index c84ec66..2572991 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,11 @@ "country-flag-icons": "^1.5.13", "eslint-plugin-simple-import-sort": "^12.1.1", "flag-icons": "^7.2.3", - "framer-motion": "^11.11.4", + "framer-motion": "^11.11.7", "lucide-react": "^0.451.0", "luxon": "^3.5.0", "next": "^14.2.15", - "next-intl": "^3.20.0", + "next-intl": "^3.21.1", "next-runtime-env": "^3.2.2", "next-themes": "^0.3.0", "react": "^18.3.1", diff --git a/styles/globals.css b/styles/globals.css index 27d637f..f30c773 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -24,11 +24,16 @@ --input: 20 5.9% 90%; --ring: 20 14.3% 4.1%; --radius: 1rem; - --chart-1: 173 58% 39%; - --chart-2: 12 76% 61%; - --chart-3: 197 37% 24%; - --chart-4: 43 74% 66%; - --chart-5: 27 87% 67%; + --chart-1: 220 70% 50%; + --chart-2: 340 75% 55%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 160 60% 45%; + --chart-6: 180 50% 50%; + --chart-7: 216 50% 50%; + --chart-8: 252 50% 50%; + --chart-9: 288 50% 50%; + --chart-10: 324 50% 50%; } .dark { @@ -52,10 +57,15 @@ --input: 12 6.5% 15.1%; --ring: 24 5.7% 82.9%; --chart-1: 220 70% 50%; - --chart-5: 160 60% 45%; + --chart-2: 340 75% 55%; --chart-3: 30 80% 55%; --chart-4: 280 65% 60%; - --chart-2: 340 75% 55%; + --chart-5: 160 60% 45%; + --chart-6: 180 50% 50%; + --chart-7: 216 50% 50%; + --chart-8: 252 50% 50%; + --chart-9: 288 50% 50%; + --chart-10: 324 50% 50%; } }