/** * ASCII line-chart renderer for `log10x_top_patterns`. * * Draws a smooth-line ASCII chart with Y-axis labels and an X-axis time * scale. Two modes: * - zero-anchored: floor at $0/h, peak at the data max. Used when the * pattern's volume actually spans a wide range — keeps the Reader * honest about magnitude. * - auto-zoomed: floor at the data min, peak at the data max. Used * when min/max > 0.2 (data is tightly clustered) — without this * the chart would be a flat band at the top with 80% empty canvas. * A caveat line below the chart names the floor so the Reader * knows the chart is zoomed and doesn't read the variation as * larger than it is. * * Connector chars are the same family the Python prototype uses: * ● for the first data point * ─ horizontal between same-row points * ╭ ╯ ╮ ╰ corners for one-row transitions * │ vertical for multi-row jumps * That set survives in plain terminals, IDE chat panels, and Markdown * renderers — no fragile fonts required. * * Height adapts: 4 rows when zoomed, 6 rows when zero-anchored. * Width is data-driven (one column per bucket up to `widthCap`). */ export interface LineChartOpts { /** Max chart columns. Data wider than this is max-pooled into widthCap buckets. */ widthCap?: number; /** Hard cap on the TOTAL rendered line width (y-label + axis + canvas), * in monospace columns. Charts wider than the chat panel soft-wrap into * garbage; this bounds the whole line so it can't. Default 54 (fits VS * Code's side panel); raise it for full-width terminals. */ maxTotalWidth?: number; /** Total time span the data covers, in seconds. Drives the x-axis labels. */ spanSeconds?: number; } /** * Render a line chart. Input `vals` are byte-rates (bytes/second from * a PromQL `rate(...)` query). The y-axis renders **volume per period**, * where the period matches the x-axis span: per-hour for sub-2-day * windows, per-day once the window is multi-day. This keeps the chart's * unit aligned with the per-day prose the tools narrate at week/month * scale (e.g. "73.7 GB/day") instead of forcing the reader to reconcile a * "3069 MB/h" peak against it. The KB/MB/GB scale is then chosen from the * peak so low-volume noise isn't a row of "0.0" labels. Volume (not $/h) * because the row header already names the cost and cost = volume × $/GB * is a linear scale, so the trend shape is identical either way. * * The x-axis likewise picks ONE time unit for the whole axis from the * total span — minutes / hours / days — so a 30-day window reads * "-30d / -15d / now" rather than an unreadable "-720h / -360h". * * Returns `null` if there is nothing to render (all zero / empty input); * callers fall back to a textual note. */ export declare function lineChart(vals: number[], opts?: LineChartOpts): string | null; /** * 8-bar Unicode sparkline for the table column. No y-axis labels. * Returns 8 chars wide regardless of input length (max-pool if longer, * pad with ─ if shorter — the shape stays comparable across rows). */ export declare function sparkline(vals: number[], width?: number): string;