TypeScript 97.5%
SQL 1.4%
Python 0.8%
1"use client";2import * as React from "react";3import { CartesianGrid, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";4import { formatMs } from "@/lib/format";5import { AXIS_TICK, CHART_COLORS, CHART_MARGIN, formatBucketLabel, formatTick } from "./chart-theme";6import { ChartTooltip } from "./chart-tooltip";7import { ChartLegend } from "./chart-frame";89export interface LatencyPoint {10 t: string;11 p50: number | null;12 p95: number | null;13}1415/** P50 (accent) and P95 (neutral) latency over time; one axis, gaps where no requests happened. */16export function LatencyLineChart({ data, bucket, height = 240 }: { data: LatencyPoint[]; bucket: "hour" | "day"; height?: number }) {17 const last = [...data].reverse().find((d) => d.p50 !== null);18 const tickEvery = Math.max(1, Math.ceil(data.length / (bucket === "hour" ? 8 : 10)));19 return (20 <div>21 <ChartLegend22 className="mb-3"23 items={[24 { label: "P50", color: CHART_COLORS.accent, value: last ? formatMs(last.p50) : undefined },25 { label: "P95", color: CHART_COLORS.muted, value: last ? formatMs(last.p95) : undefined },26 ]}27 />28 <ResponsiveContainer width="100%" height={height}>29 <LineChart data={data} margin={CHART_MARGIN}>30 <CartesianGrid vertical={false} stroke={CHART_COLORS.grid} />31 <XAxis dataKey="t" tickFormatter={(v: string) => formatTick(v, bucket)} tick={AXIS_TICK} axisLine={false} tickLine={false} interval={tickEvery - 1} minTickGap={16} />32 <YAxis tick={AXIS_TICK} axisLine={false} tickLine={false} width={48} tickFormatter={(v: number) => formatMs(v)} />33 <Tooltip cursor={{ stroke: CHART_COLORS.faint, strokeWidth: 1 }} content={<ChartTooltip labelFormatter={(l) => formatBucketLabel(String(l), bucket)} names={{ p50: "P50", p95: "P95" }} valueFormatter={(v) => formatMs(v)} />} />34 <Line type="monotone" dataKey="p95" stroke={CHART_COLORS.muted} strokeWidth={2} dot={false} activeDot={{ r: 4, strokeWidth: 2, stroke: CHART_COLORS.surface }} connectNulls={false} isAnimationActive={false} />35 <Line type="monotone" dataKey="p50" stroke={CHART_COLORS.accent} strokeWidth={2} dot={false} activeDot={{ r: 4, strokeWidth: 2, stroke: CHART_COLORS.surface }} connectNulls={false} isAnimationActive={false} />36 </LineChart>37 </ResponsiveContainer>38 </div>39 );40}41