import { type Dayjs } from 'dayjs'; import type { TimelineScale } from '../data-view.types'; /** * Average unit durations in ms. Used only to derive px density (px/ms) from * `unitWidth`; card and tick positions always use real timestamps, so * variable-length months don't distort placement. */ export declare const TIMELINE_UNIT_MS: Record; /** Default px width of one `scale` unit when `unitWidth` is not provided. */ export declare const TIMELINE_DEFAULT_UNIT_WIDTH: Record; /** Coerce a consumer-provided date (Date | epoch ms | parseable string) to ms. */ export declare function toTimestamp(value: unknown): number | null; /** `startOf` that also understands quarters without a dayjs plugin. */ export declare function startOfUnit(date: Dayjs, scale: TimelineScale): Dayjs; export declare function addUnits(date: Dayjs, scale: TimelineScale, n: number): Dayjs; export interface TimelineTimeScale { /** Domain start (ms), snapped to a unit boundary. */ t0: number; /** Domain end (ms), snapped to a unit boundary. */ t1: number; pxPerMs: number; totalWidth: number; /** Time (ms) → x offset (px) from the canvas left edge. */ x: (time: number) => number; /** Inverse of `x` — px offset → time (ms). */ timeAt: (px: number) => number; } export declare function createTimeScale(params: { minTime: number; maxTime: number; scale: TimelineScale; unitWidth: number; /** Whole units of padding added on each side of the extent. */ padUnits?: number; /** * Minimum rendered width (px). The domain end extends by whole units until * `totalWidth` reaches it; a domain already wider is left untouched. Lets * the timeline fill its container when the data span is narrower. */ minWidth?: number; }): TimelineTimeScale; export interface TimelineTick { time: number; x: number; label: string; /** False when labels are thinned out at dense zoom levels. */ showLabel: boolean; /** Sequential unit index from the domain start — drives interval thinning. */ index: number; } export interface TimelineBand { time: number; x: number; width: number; label: string; } /** * Generates the two-tier axis: minor ticks at `scale` granularity and major * bands one level up (months over day/week ticks, years over month/quarter * ticks). The first band — and any band starting a new year — carries the * year in its label ("Jan 2025", then "Feb"). * * `labelEvery` labels every Nth unit, counted from the domain start. The * collision floor (labels never closer than `TICK_LABEL_MIN_SPACE`) still * applies, so a too-dense request degrades instead of overlapping. * * Cost note: this materializes one tick per `scale` unit across the whole * domain on every rebuild — `virtualized` culls what renders, not what gets * built here. Fine at the intended densities (weeks/months, a few years of * days); a `day` scale over a decade-wide `range` allocates ~3.6k ticks per * rebuild and would need windowed generation instead. */ export declare function buildAxis(timeScale: TimelineTimeScale, scale: TimelineScale, unitWidth: number, labelEvery?: number): { ticks: TimelineTick[]; bands: TimelineBand[]; }; //# sourceMappingURL=time-scale.d.ts.map