import { PlotLayout, type PlotRect } from "./plot-layout"; /** * Tri-state axis mode. * * - `"outer"` — one shared axis band reserved at the grid edge; * `outerXAxisRect` / `outerYAxisRect` populated, per-cell gutter * collapsed to 0 on that side. Caller paints the shared axis * once per frame using the grid's outer rect. * - `"cell"` — every cell reserves its own gutter on that side; * caller paints one axis per cell. Outer rect is undefined. * - `"none"` — no gutter anywhere on that side: neither an outer * band nor a per-cell reservation. Intended for chart types with * no numeric axis at all (treemap, sunburst). When BOTH axes are * `"none"` cells are also made flush on the right so adjacent * plot rects share a boundary. * * Defaults to `"cell"` when undefined. */ export type AxisMode = "outer" | "cell" | "none"; export interface FacetGridOptions { cssWidth: number; cssHeight: number; /** * See {@link AxisMode}. Default `"cell"`. */ xAxis?: AxisMode; /** * See {@link AxisMode}. Default `"cell"`. */ yAxis?: AxisMode; /** * Reserve a right gutter for a single shared legend. */ hasLegend?: boolean; /** Axis-label allowance (consumed only when the corresponding axis * mode produces a gutter — outer band or per-cell). */ hasXLabel?: boolean; hasYLabel?: boolean; /** * Per-facet title strip height (px). 0 disables. */ titleBand?: number; /** * Pixel gap between adjacent cells. Carved out of the grid * interior before cell sizing; outer edges of the leftmost / * rightmost columns and top / bottom rows are unaffected. Default * 0 (flush cells). */ gap?: number; } export interface FacetCell { index: number; label: string; /** * Sub-plot layout. Every cell in a grid has *identical* * `plotRect.width` and `plotRect.height` — cell internal margins * do not vary by edge position. Shared-axis gutters live in * `FacetGrid.outerXAxisRect` / `outerYAxisRect` instead, painted * once per frame by the caller. */ layout: PlotLayout; /** * Title strip above the facet's plot rect, if `titleBand > 0`. */ titleRect?: PlotRect; isLeftEdge: boolean; isBottomEdge: boolean; } export interface FacetGrid { cells: FacetCell[]; /** * Right-gutter rect for the shared legend. */ legendRect?: PlotRect; /** * Outer band reserved for the shared X axis (ticks + label). Only * set when `xAxis === "outer"`. Spans the grid interior's * horizontal extent and sits immediately below the bottom row of * cells. */ outerXAxisRect?: PlotRect; /** * Outer band reserved for the shared Y axis (ticks + label). Only * set when `yAxis === "outer"`. Spans the grid interior's * vertical extent and sits immediately left of the leftmost * column of cells. */ outerYAxisRect?: PlotRect; } /** * Collect the bottom-row cells' `PlotLayout`s — i.e. the cells that * sit on the grid's bottom edge. Shared-X axis renderers paint X * ticks aligned to each of these. Empty when the grid has zero cells. */ export declare function bottomRowLayouts(grid: FacetGrid): PlotLayout[]; /** * Collect the left-column cells' `PlotLayout`s — symmetric to * {@link bottomRowLayouts} for the shared-Y axis path. */ export declare function leftColumnLayouts(grid: FacetGrid): PlotLayout[]; /** * Arrange `labels.length` sub-plots in a row-major grid sized to fit * `(cssWidth, cssHeight)`. * * Grid shape is chosen to minimize cell aspect distance from square * given the container's grid interior: `cols ∈ [1, count]`, * `rows = ceil(count / cols)`, tie-broken toward fewer total cells. * * **Invariant:** every `cells[i].layout.plotRect` has the same * `width` and `height`. Shared-axis gutters are carved out of the * outer canvas BEFORE cell sizing, so a cell's edge position never * affects its internal margins. This lets per-facet draws reuse the * same projection scale and lets shared ticks line up with the * interior cell boundaries exactly. * * Axis modes — see {@link AxisMode}: * - `"outer"` → outer band rect is populated; per-cell gutter is 0. * - `"cell"` → outer band is undefined; each cell owns its own gutter. * - `"none"` → no gutter anywhere on that side; used by axis-less * chart types. * * Because all cells are identical in size, callers can sample *any* * cell's layout (e.g. `cells[0].layout`) for tick / scale * computations. */ export declare function buildFacetGrid(labels: string[], opts: FacetGridOptions): FacetGrid;