import type { ColumnDataMap } from "../../data/view-reader"; import type { CategoricalLevel } from "../../axis/categorical-axis"; import { type AxisMode, type NumericCategoryDomain } from "../common/category-axis-resolver"; export interface HeatmapCell { xIdx: number; yIdx: number; value: number; } export interface HeatmapPipelineInput { columns: ColumnDataMap; numRows: number; groupBy: string[]; splitBy: string[]; /** * Source-column types keyed by column name (table.schema() merged * with view.expression_schema()). Drives both the X-axis level-type * lookup (for non-string row-paths) and the Y-axis numeric-mode * decision when there's a single split_by. */ groupByTypes: Record; } export interface HeatmapPipelineResult { /** * Hierarchical row_path levels driving the X axis (outermost-first). */ xLevels: CategoricalLevel[]; /** * Arrow column names in iteration order; `yIdx === index in this list`. */ yColumnNames: string[]; /** * Hierarchical Y levels derived by splitting each name on `|`. */ yLevels: CategoricalLevel[]; numX: number; numY: number; rowOffset: number; cells: HeatmapCell[]; /** * O(1) lookup by `yIdx * numX + xIdx`; `null` means no-data. */ cells2D: (HeatmapCell | null)[]; colorMin: number; colorMax: number; /** * X-axis mode. `numeric` fires when the single group_by is * date/datetime/integer/float; positions live in `xPositions` * and the domain in `xNumericDomain`. */ xAxisMode: AxisMode; yAxisMode: AxisMode; xPositions: Float64Array | null; yPositions: Float64Array | null; xNumericDomain: NumericCategoryDomain | null; yNumericDomain: NumericCategoryDomain | null; } /** * Pure heatmap pipeline. Y indexing maps 1:1 to the arrow column iteration * order — `yIdx` is the position of a value column in the ordered * `ColumnDataMap` (after skipping `__ROW_PATH_N__` metadata). No * aggregate/split reconstruction; the column name *is* the Y label. * * Externally enforced: only one entry sits in the `Color` slot, so every * non-metadata column is a splitwise expansion of that single aggregate. * * Numeric-axis mode (matching bar/candlestick): when there's exactly one * non-string group_by, the X axis switches to a real numeric/date axis * with `xPositions[xIdx]` carrying the data-space center. Y mirrors this * for a single non-string split_by, parsed best-effort out of the column * name leaf segment; on parse failure it falls back to category mode. */ export declare function buildHeatmapPipeline(input: HeatmapPipelineInput): HeatmapPipelineResult; /** * Partition a `ColumnDataMap` into one sub-map per user column. Every * arrow value column is assigned to the partition whose user column name * matches its terminal segment (everything after the last `|`, which * equals the whole name when there's no `split_by`). `__ROW_PATH_N__` * and `__GROUPING_ID__` metadata columns are copied into every partition * since they describe the shared X axis. * * Used to render one heatmap per user column in a facet grid. */ export declare function partitionColumnsPerFacet(columns: ColumnDataMap, userColumns: string[]): Array<{ label: string; columns: ColumnDataMap; }>;