Files
Unraid-AppOps-Gateway-Public/src/components/SystemLoadSvgChart.tsx
T

39 lines
2.0 KiB
TypeScript

import { useMemo } from "react";
import type { SystemLoadChartPoint } from "@/lib/systemLoadChartView";
const polylinePoints = (points: SystemLoadChartPoint[], key: "cpu" | "ram") => {
const denominator = Math.max(1, points.length - 1);
return points.flatMap((point, index) => {
const value = point[key];
return typeof value === "number"
? [`${(index / denominator) * 100},${100 - Math.max(0, Math.min(value, 100))}`]
: [];
}).join(" ");
};
export const SystemLoadSvgChart = ({ points }: { points: SystemLoadChartPoint[] }) => {
const cpu = useMemo(() => polylinePoints(points, "cpu"), [points]);
const ram = useMemo(() => polylinePoints(points, "ram"), [points]);
const firstTime = points[0]?.time ?? "";
const lastTime = points.at(-1)?.time ?? "";
return (
<figure className="flex h-full flex-col" aria-label="Live CPU- en RAM-belasting">
<svg className="min-h-0 flex-1 overflow-visible" viewBox="0 0 100 100" preserveAspectRatio="none" role="img">
<title>Live CPU- en RAM-belasting in procenten</title>
<desc>CPU is blauw en RAM is groen. De verticale schaal loopt van nul tot honderd procent.</desc>
{[0, 25, 50, 75, 100].map(value => (
<line key={value} x1="0" x2="100" y1={100 - value} y2={100 - value} vectorEffect="non-scaling-stroke" className="stroke-slate-800" strokeDasharray="2 6" />
))}
{cpu ? <polyline points={cpu} fill="none" vectorEffect="non-scaling-stroke" className="stroke-cyan-400" strokeWidth="2" /> : null}
{ram ? <polyline points={ram} fill="none" vectorEffect="non-scaling-stroke" className="stroke-emerald-400" strokeWidth="2" /> : null}
</svg>
<figcaption className="mt-2 flex items-center justify-between text-[10px] text-slate-500">
<span>{firstTime}</span>
<span className="flex gap-3"><span className="text-cyan-300">CPU</span><span className="text-emerald-300">RAM</span></span>
<span>{lastTime}</span>
</figcaption>
</figure>
);
};