/** * Shared chart primitives for the dashboard timeline charts (BehaviorChart, * CostChart). Each chart owns its data shape and metric labels — this module * owns the layout, theme, legend/tooltip plumbing, and the top-N-by-model * bucketing scaffold that's identical between cost and behavior series. */ export declare const MODEL_COLORS: string[]; export declare const CHART_THEMES: { readonly dark: { readonly legendLabel: "#94a3b8"; readonly tooltipBackground: "#16161e"; readonly tooltipTitle: "#f8fafc"; readonly tooltipBody: "#94a3b8"; readonly tooltipBorder: "rgba(255, 255, 255, 0.1)"; readonly grid: "rgba(255, 255, 255, 0.06)"; readonly tick: "#64748b"; }; readonly light: { readonly legendLabel: "#475569"; readonly tooltipBackground: "#ffffff"; readonly tooltipTitle: "#0f172a"; readonly tooltipBody: "#334155"; readonly tooltipBorder: "rgba(15, 23, 42, 0.18)"; readonly grid: "rgba(15, 23, 42, 0.08)"; readonly tick: "#64748b"; }; }; export type ChartTheme = (typeof CHART_THEMES)[keyof typeof CHART_THEMES]; export interface ChartSeries { labels: string[]; datasets: Array<{ label: string; data: number[]; }>; } interface TooltipItem { parsed: { y: number | null; }; } /** Tooltip + legend config common to bar and line variants of the time charts. */ export declare function buildSharedPlugins(opts: { chartTheme: ChartTheme; showLegend: boolean; defaultLabel: string; formatValue: (n: number) => string; footer?: (items: TooltipItem[]) => string | undefined; }): { legend: { display: boolean; position: "top"; align: "start"; labels: { color: "#475569" | "#94a3b8"; usePointStyle: boolean; padding: number; font: { size: number; }; boxWidth: number; }; }; tooltip: { backgroundColor: "#16161e" | "#ffffff"; titleColor: "#0f172a" | "#f8fafc"; bodyColor: "#334155" | "#94a3b8"; borderColor: "rgba(15, 23, 42, 0.18)" | "rgba(255, 255, 255, 0.1)"; borderWidth: number; padding: number; cornerRadius: number; callbacks: { label: (ctx: { dataset: { label?: string; }; parsed: { y: number | null; }; }) => string; footer?: ((items: TooltipItem[]) => string | undefined) | undefined; }; }; }; /** Y-axis tick formatter + grid/tick styling shared by both charts. */ export declare function buildSharedScales(opts: { chartTheme: ChartTheme; formatY: (n: number) => string; }): { sharedScaleBase: { grid: { color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)"; drawBorder: boolean; }; ticks: { color: "#64748b"; font: { size: number; }; }; }; yScale: { grid: { color: "rgba(15, 23, 42, 0.08)" | "rgba(255, 255, 255, 0.06)"; drawBorder: boolean; }; ticks: { color: "#64748b"; font: { size: number; }; callback: (value: number | string) => string; }; min: number; }; }; /** Stylistic defaults for a single line dataset in a stacked/by-model chart. */ export declare function lineDatasetStyle(color: string): { borderColor: string; backgroundColor: string; fill: boolean; tension: number; pointRadius: number; pointHoverRadius: number; borderWidth: number; }; /** Stylistic defaults for a single bar dataset in a stacked chart. */ export declare function barDatasetStyle(color: string): { backgroundColor: string; borderColor: string; borderWidth: number; borderRadius: number; }; /** * Map a generic ChartSeries' datasets through a per-index style function so * callers can supply line or bar styling without repeating the label/data * spread at every chart site. */ export declare function styleDatasets(series: ChartSeries, styleFor: (index: number) => Record): { label: string; data: number[]; }[]; /** * Bucket points by day into a single aggregate series. Caller supplies the * per-bucket accumulator + final value extractor; mirrors the shape of * `buildTopNByModelSeries` for the non-by-model variant of each time chart. */ export declare function buildAggregateTimeSeries(points: T[], label: string, opts: { initBucket: () => B; accumulate: (bucket: B, point: T) => void; bucketToValue: (bucket: B) => number; }): ChartSeries; interface ModelKeyedPoint { timestamp: number; model: string; provider: string; } /** * Bucket points by day and by top-N model (with an "Other" rollup), producing * a ChartSeries. Caller controls how points contribute to ranking and to each * day-bucket value via the `rankWeight`/`accumulate`/`bucketToValue` callbacks * — keeps the behavior chart's rate math separate from the cost chart's sum. */ export declare function buildTopNByModelSeries(points: T[], opts: { topN?: number; rankWeight: (point: T) => number; initBucket: () => B; accumulate: (bucket: B, point: T) => void; bucketToValue: (bucket: B) => number; }): ChartSeries; /** * Outer surface card used by both time charts. `controls` slot covers * chart-specific tabs (e.g. behavior metric picker); the by-model toggle and * empty-state are part of the frame so callers don't redeclare them. */ export declare function ChartFrame({ title, subtitle, empty, emptyMessage, controls, byModel, onByModelChange, children, }: { title: string; subtitle: string; empty: boolean; emptyMessage: string; controls?: React.ReactNode; byModel: boolean; onByModelChange: (v: boolean) => void; children: React.ReactNode; }): import("react/jsx-runtime").JSX.Element; export {};