feat(analytics): add formatDurationMs function for improved duration formatting

This commit is contained in:
Kyush 2026-04-23 02:04:49 +09:00
commit 48455d94e8
3 changed files with 28 additions and 5 deletions

View file

@ -1,6 +1,7 @@
import { Show, createMemo, createResource, createSignal, type Component } from 'solid-js'; import { Show, createMemo, createResource, createSignal, type Component } from 'solid-js';
import { api } from '../api/client'; import { api } from '../api/client';
import { Layout } from '../components/Layout'; import { Layout } from '../components/Layout';
import { formatDurationMs } from '../ui/lib/format';
import { import {
BoxPlotChart, BoxPlotChart,
ChartLegend, ChartLegend,
@ -142,7 +143,7 @@ export const Analytics: Component = () => {
return [ return [
{ label: 'Requests', value: formatInteger.format(totals.requests), hint: `Last ${days()} days` }, { label: 'Requests', value: formatInteger.format(totals.requests), hint: `Last ${days()} days` },
{ label: 'Tokens', value: formatInteger.format(totals.tokens), hint: `Selected ${days()}-day window total` }, { label: 'Tokens', value: formatInteger.format(totals.tokens), hint: `Selected ${days()}-day window total` },
{ label: 'Avg Response', value: `${avgLatency.toFixed(1)}ms`, hint: 'Across visible backend series' }, { label: 'Avg Response', value: formatDurationMs(avgLatency), hint: 'Across visible backend series' },
{ label: 'Errors', value: formatInteger.format(errorCount), hint: 'Absolute backend error count' }, { label: 'Errors', value: formatInteger.format(errorCount), hint: 'Absolute backend error count' },
]; ];
}); });
@ -252,8 +253,8 @@ export const Analytics: Component = () => {
showLegend={false} showLegend={false}
hiddenKeys={hiddenResponseSeries()} hiddenKeys={hiddenResponseSeries()}
onToggleLegend={(key) => toggleHiddenKey(setHiddenResponseSeries, key)} onToggleLegend={(key) => toggleHiddenKey(setHiddenResponseSeries, key)}
yLeftLabel="Milliseconds" yLeftLabel="Response time"
formatLeftValue={(value) => `${value.toFixed(0)}ms`} formatLeftValue={formatDurationMs}
tooltipTitle="Average backend response time" tooltipTitle="Average backend response time"
/> />
</Panel> </Panel>

View file

@ -2,6 +2,7 @@ import RefreshCcw from 'lucide-solid/icons/refresh-ccw';
import { Show, createMemo, createResource, createSignal, type Component } from 'solid-js'; import { Show, createMemo, createResource, createSignal, type Component } from 'solid-js';
import { api } from '../api/client'; import { api } from '../api/client';
import { Layout } from '../components/Layout'; import { Layout } from '../components/Layout';
import { formatDurationMs } from '../ui/lib/format';
import { import {
ChartLegend, ChartLegend,
ComboChart, ComboChart,
@ -248,8 +249,8 @@ export const Dashboard: Component = () => {
showLegend={false} showLegend={false}
hiddenKeys={hiddenLatencySeries()} hiddenKeys={hiddenLatencySeries()}
onToggleLegend={(key) => toggleHiddenKey(setHiddenLatencySeries, key)} onToggleLegend={(key) => toggleHiddenKey(setHiddenLatencySeries, key)}
yLeftLabel="Milliseconds" yLeftLabel="Latency"
formatLeftValue={(value) => `${value.toFixed(0)}ms`} formatLeftValue={formatDurationMs}
tooltipTitle="Backend latency" tooltipTitle="Backend latency"
/> />
</Panel> </Panel>

View file

@ -0,0 +1,21 @@
const durationFormatters = {
seconds: new Intl.NumberFormat('en-US', { maximumFractionDigits: 1 }),
minutes: new Intl.NumberFormat('en-US', { maximumFractionDigits: 1 }),
};
export function formatDurationMs(value: number): string {
if (!Number.isFinite(value)) {
return '0ms';
}
const absoluteValue = Math.abs(value);
if (absoluteValue < 1000) {
return `${Math.round(value)}ms`;
}
if (absoluteValue < 60_000) {
return `${durationFormatters.seconds.format(value / 1000)}s`;
}
return `${durationFormatters.minutes.format(value / 60_000)}m`;
}