refactor(web): add value formatter to ChartCard component

Introduce a `valueFormatter` prop to the `ChartCard` component to allow
customized data presentation in tooltips. This enables more readable
units for specific metrics, such as converting bytes to MiB or
seconds to milliseconds.
This commit is contained in:
MythEclipse
2026-06-08 02:03:23 +07:00
parent b0dd1f289a
commit 09602b3fe0
+10 -4
View File
@@ -72,8 +72,9 @@ function StatCard({ icon: Icon, label, value, sub, color }: {
); );
} }
function ChartCard({ title, data, color, unit = "", domain }: { function ChartCard({ title, data, color, unit = "", domain, valueFormatter }: {
title: string; data: PromValue[]; color: string; unit?: string; domain?: [number, number]; title: string; data: PromValue[]; color: string; unit?: string; domain?: [number, number];
valueFormatter?: (v: number) => string;
}) { }) {
if (!data || data.length === 0) { if (!data || data.length === 0) {
return ( return (
@@ -106,7 +107,10 @@ function ChartCard({ title, data, color, unit = "", domain }: {
<YAxis domain={domain ?? ["auto", "auto"]} tick={{ fontSize: 9 }} unit={unit} /> <YAxis domain={domain ?? ["auto", "auto"]} tick={{ fontSize: 9 }} unit={unit} />
<Tooltip <Tooltip
labelFormatter={(v) => new Date(v).toLocaleTimeString()} labelFormatter={(v) => new Date(v).toLocaleTimeString()}
formatter={(val: unknown) => [typeof val === "number" ? val.toFixed(2) : String(val ?? ""), title]} formatter={(val: unknown) => {
const v = typeof val === "number" ? val : 0;
return [valueFormatter ? valueFormatter(v) : v.toFixed(2), title];
}}
/> />
<Area type="monotone" dataKey="value" stroke={color} <Area type="monotone" dataKey="value" stroke={color}
fill={`url(#g-${title.replace(/\s+/g, "")})`} strokeWidth={2} /> fill={`url(#g-${title.replace(/\s+/g, "")})`} strokeWidth={2} />
@@ -354,8 +358,10 @@ export function TelemetryPage() {
<StatCard icon={Activity} label="Process Mem (api)" value={procMem !== null ? fmtBytes(procMem) : "N/A"} color="text-indigo-600" /> <StatCard icon={Activity} label="Process Mem (api)" value={procMem !== null ? fmtBytes(procMem) : "N/A"} color="text-indigo-600" />
</div> </div>
<div className="grid gap-3 md:grid-cols-2"> <div className="grid gap-3 md:grid-cols-2">
<ChartCard title="Heap Used" data={heapData} color="#8b5cf6" /> <ChartCard title="Heap Used" data={heapData} color="#8b5cf6"
<ChartCard title="Event Loop Lag" data={elLagData} color="#eab308" /> valueFormatter={(v) => (v / 1024 / 1024).toFixed(1) + " MiB"} />
<ChartCard title="Event Loop Lag" data={elLagData} color="#eab308"
valueFormatter={(v) => (v * 1000).toFixed(2) + " ms"} />
</div> </div>
</div> </div>
); );