fix(metrics): reorder graph cards, per-chart hover cursor, readable dark tooltip

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 01:21:04 +05:00
parent 0f7c5a44df
commit 7a5485c63c

View File

@@ -29,7 +29,6 @@ const PRESETS = [
{ tf: 'month', label: '30d' }, { tf: 'month', label: '30d' },
]; ];
const SYNC_ID = 'vm-graphs';
const MAX_SPAN = 30 * 86400; const MAX_SPAN = 30 * 86400;
function fmtTime(ts: number): string { function fmtTime(ts: number): string {
@@ -71,7 +70,7 @@ function ChartCard({ title, data, dataKey, color, formatValue, unit, headerRight
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<ResponsiveContainer width="100%" height={200}> <ResponsiveContainer width="100%" height={200}>
<AreaChart syncId={SYNC_ID} data={data} margin={{ top: 5, right: 5, bottom: 0, left: 0 }}> <AreaChart data={data} margin={{ top: 5, right: 5, bottom: 0, left: 0 }}>
<defs> <defs>
<linearGradient id={`grad-${dataKey}`} x1="0" y1="0" x2="0" y2="1"> <linearGradient id={`grad-${dataKey}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor={color} stopOpacity={0.3} /> <stop offset="0%" stopColor={color} stopOpacity={0.3} />
@@ -93,11 +92,14 @@ function ChartCard({ title, data, dataKey, color, formatValue, unit, headerRight
/> />
<Tooltip <Tooltip
contentStyle={{ contentStyle={{
backgroundColor: 'hsl(var(--popover))', backgroundColor: 'rgba(0, 0, 0, 0.65)',
border: '1px solid hsl(var(--border))', border: '1px solid rgba(255, 255, 255, 0.25)',
borderRadius: '6px', borderRadius: '6px',
fontSize: 12, fontSize: 12,
color: '#fff',
}} }}
labelStyle={{ color: '#fff' }}
itemStyle={{ color: '#fff' }}
formatter={(val: unknown) => [ formatter={(val: unknown) => [
val != null && typeof val === 'number' && formatValue val != null && typeof val === 'number' && formatValue
? formatValue(val) ? formatValue(val)
@@ -246,12 +248,18 @@ export default function GraphsTab({ serverId, vmid, type, node }: Props) {
formatValue={(v) => formatBytes(v)} formatValue={(v) => formatBytes(v)}
/> />
<ChartCard <ChartCard
title="Заполненность диска" title={t('graphs.disk_write')}
data={points} data={points}
dataKey="diskpct" dataKey="diskwrite"
color="hsl(45, 93%, 47%)" color="hsl(0, 84%, 60%)"
formatValue={(v) => `${v.toFixed(1)}%`} formatValue={(v) => `${formatBytes(v)}/s`}
unit="%" />
<ChartCard
title={t('graphs.disk_read')}
data={points}
dataKey="diskread"
color="hsl(199, 89%, 48%)"
formatValue={(v) => `${formatBytes(v)}/s`}
/> />
<ChartCard <ChartCard
title={t('graphs.network_in')} title={t('graphs.network_in')}
@@ -270,18 +278,12 @@ export default function GraphsTab({ serverId, vmid, type, node }: Props) {
headerRight={nicSelector} headerRight={nicSelector}
/> />
<ChartCard <ChartCard
title={t('graphs.disk_read')} title="Заполненность диска"
data={points} data={points}
dataKey="diskread" dataKey="diskpct"
color="hsl(199, 89%, 48%)" color="hsl(45, 93%, 47%)"
formatValue={(v) => `${formatBytes(v)}/s`} formatValue={(v) => `${v.toFixed(1)}%`}
/> unit="%"
<ChartCard
title={t('graphs.disk_write')}
data={points}
dataKey="diskwrite"
color="hsl(0, 84%, 60%)"
formatValue={(v) => `${formatBytes(v)}/s`}
/> />
<ChartCard <ChartCard
title="IOPS чтение" title="IOPS чтение"