mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-01 14:06:15 +00:00
fix resource usage chart
This commit is contained in:
@ -1,11 +1,12 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Area, AreaChart, XAxis } from 'recharts';
|
import { Area, AreaChart, XAxis, YAxis } from 'recharts';
|
||||||
|
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
|
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart';
|
||||||
import { Metric } from '@/types/metric';
|
import { Metric } from '@/types/metric';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Formatter } from 'recharts/types/component/DefaultTooltipContent';
|
import { router } from '@inertiajs/react';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
@ -13,10 +14,12 @@ interface Props {
|
|||||||
dataKey: 'load' | 'memory_used' | 'disk_used';
|
dataKey: 'load' | 'memory_used' | 'disk_used';
|
||||||
label: string;
|
label: string;
|
||||||
chartData: Metric[];
|
chartData: Metric[];
|
||||||
formatter?: Formatter<number | string, string>;
|
link: string;
|
||||||
|
formatter?: (value: unknown, name: unknown) => string | number;
|
||||||
|
single?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ResourceUsageChart({ title, color, dataKey, label, chartData, formatter }: Props) {
|
export function ResourceUsageChart({ title, color, dataKey, label, chartData, link, formatter, single }: Props) {
|
||||||
const chartConfig = {
|
const chartConfig = {
|
||||||
[dataKey]: {
|
[dataKey]: {
|
||||||
label: label,
|
label: label,
|
||||||
@ -24,37 +27,37 @@ export function ResourceUsageChart({ title, color, dataKey, label, chartData, fo
|
|||||||
},
|
},
|
||||||
} satisfies ChartConfig;
|
} satisfies ChartConfig;
|
||||||
|
|
||||||
const getCurrentValue = () => {
|
|
||||||
if (chartData.length === 0) return 'N/A';
|
|
||||||
|
|
||||||
const value = chartData[chartData.length - 1][dataKey];
|
|
||||||
if (formatter) {
|
|
||||||
return formatter(value, dataKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return typeof value === 'number' ? value.toLocaleString() : String(value);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<CardContent className="overflow-hidden p-0">
|
<CardContent className="overflow-hidden p-0">
|
||||||
<div className="flex items-start justify-between p-4">
|
<div className="flex items-start justify-between p-4">
|
||||||
<div className="space-y-2 py-[7px]">
|
<div className="space-y-2 py-[7px]">
|
||||||
<h2 className="text-muted-foreground text-sm">{title}</h2>
|
<h2 className="text-muted-foreground text-sm">{title}</h2>
|
||||||
<span className="text-3xl font-bold">{getCurrentValue()}</span>
|
<span className="text-3xl font-bold">
|
||||||
|
{chartData.length > 0
|
||||||
|
? formatter
|
||||||
|
? formatter(chartData[chartData.length - 1][dataKey], dataKey)
|
||||||
|
: chartData[chartData.length - 1][dataKey].toLocaleString()
|
||||||
|
: 'N/A'}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Button variant="ghost">View</Button>
|
{!single && (
|
||||||
|
<Button variant="ghost" onClick={() => router.visit(link)}>
|
||||||
|
View
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<ChartContainer config={chartConfig} className="aspect-auto h-[100px] w-full overflow-hidden rounded-b-xl">
|
<ChartContainer config={chartConfig} className={cn('aspect-auto w-full overflow-hidden rounded-b-xl', single ? 'h-[400px]' : 'h-[100px]')}>
|
||||||
<AreaChart data={chartData} margin={{ left: 0, right: 0, top: 0, bottom: 0 }}>
|
<AreaChart accessibilityLayer data={chartData} margin={{ left: 0, right: 0, top: 0, bottom: 0 }}>
|
||||||
<defs>
|
<defs>
|
||||||
<linearGradient id={`fill-${dataKey}`} x1="0" y1="0" x2="0" y2="1">
|
<linearGradient id={`fill-${dataKey}`} x1="0" y1="0" x2="0" y2="1">
|
||||||
<stop offset="5%" stopColor={color} stopOpacity={0.8} />
|
<stop offset="5%" stopColor={color} stopOpacity={0.8} />
|
||||||
<stop offset="95%" stopColor={color} stopOpacity={0.1} />
|
<stop offset="95%" stopColor={color} stopOpacity={0.1} />
|
||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
|
<YAxis dataKey={dataKey} hide />
|
||||||
<XAxis
|
<XAxis
|
||||||
hide
|
hide={!single}
|
||||||
dataKey="date"
|
dataKey="date"
|
||||||
tickLine={false}
|
tickLine={false}
|
||||||
axisLine={false}
|
axisLine={false}
|
||||||
@ -71,7 +74,7 @@ export function ResourceUsageChart({ title, color, dataKey, label, chartData, fo
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<ChartTooltip
|
<ChartTooltip
|
||||||
cursor={false}
|
cursor={true}
|
||||||
content={
|
content={
|
||||||
<ChartTooltipContent
|
<ChartTooltipContent
|
||||||
labelFormatter={(value) => {
|
labelFormatter={(value) => {
|
||||||
@ -87,7 +90,7 @@ export function ResourceUsageChart({ title, color, dataKey, label, chartData, fo
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Area dataKey={dataKey} type="natural" fill={`url(#fill-${dataKey})`} stroke={color} />
|
<Area dataKey={dataKey} type="monotone" fill={`url(#fill-${dataKey})`} stroke={color} />
|
||||||
</AreaChart>
|
</AreaChart>
|
||||||
</ChartContainer>
|
</ChartContainer>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
Reference in New Issue
Block a user