import type { ColumnDataMap } from "../../data/view-reader"; import type { WebGLContextManager } from "../../webgl/context-manager"; import { AbstractChart } from "../chart-base"; import { SpatialHitTester } from "../../interaction/hit-test"; import { PlotLayout } from "../../layout/plot-layout"; import { type AxisDomain } from "../../axis/numeric-axis"; import type { CategoricalDomain } from "../../axis/categorical-axis"; import type { GradientTextureCache } from "../../webgl/gradient-texture"; import type { Glyph } from "./glyph"; import type { LabelInterner } from "./label-interner"; import { LazyTooltip } from "../../interaction/lazy-tooltip"; export interface SplitGroup { prefix: string; xColName: string; yColName: string; colorColName: string; sizeColName: string; labelColName: string; } /** * Unified continuous (numeric X/Y) chart. Glyphs plug in to render * points, lines, or (future) areas over the shared data pipeline: * streaming chunk upload, per-series slotted buffer layout, pan/zoom, * spatial hit testing, chrome overlay, tooltip controller. * * Fields are package-internal (no `private`) so the split helper * modules and glyphs can read/write them. */ export declare class CartesianChart extends AbstractChart { readonly glyph: Glyph; constructor(glyph: Glyph); /** * Rendering pipeline selector. `"cartesian"` is the default — * draws axes, gridlines, and ticks via the chrome canvas. * `"map"` (set by `MapChart` subclasses) suppresses cartesian * chrome and inserts a raster tile layer underneath the glyph * draw in `_fullRender`, so the same glyphs (point / line / * density) render on top of a basemap. * * Read in `cartesian-render.ts` at three branch points; the * `"cartesian"` path is byte-for-byte unchanged by the addition * of this enum. */ _renderMode: "cartesian" | "map"; /** * Per-point data-space projection hook. Default is identity; map * subclasses override to map (lon, lat) → Mercator meters. Called * from `processCartesianChunk` immediately after the NaN guard, * before extent accumulation and the `_xData` / `_yData` slot * writes — so every downstream consumer (axis domain, projection * matrix, spatial hit-test, glyph buffers) sees projected space * uniformly. Returning `[NaN, NaN]` from a subclass discards the * row (e.g. Mercator's ±85° latitude clamp). */ projectPoint(x: number, y: number): [number, number]; /** * Paint a per-frame background inside the plot-frame scissor, * before the glyph draw. Map subclasses override to render the * raster tile basemap; the default no-op leaves cartesian charts * byte-for-byte unchanged. * * Called once per facet in faceted mode (each call's `projection` * and `domain` are that cell's), wrapped in the cell's scissor — * just like `glyph.drawSeries`. * * `xOrigin` / `yOrigin` are the rebase origins the projection * matrix bakes in (see `buildProjectionMatrix`). Glyphs ship * pre-rebased positions, so the background pass must subtract * them from absolute-domain coords (e.g. tile Mercator extents) * before uploading vertex positions; otherwise the matrix * over-corrects and the background lands off-screen by * `sx * xOrigin` clip units. */ renderBackground(_glManager: import("../../webgl/context-manager").WebGLContextManager, _layout: import("../../layout/plot-layout").PlotLayout, _projection: Float32Array, _domain: { xMin: number; xMax: number; yMin: number; yMax: number; }, _xOrigin: number, _yOrigin: number): void; /** * Paint chrome (attribution, scale bar) for map mode on top of the * chrome canvas, in place of the cartesian axes/gridlines/legend. * Called only when `_renderMode === "map"`. Default no-op so * cartesian charts still go through `renderAxesChrome`. */ renderMapChrome(_canvas: import("../canvas-types").Canvas2D | null, _layout: import("../../layout/plot-layout").PlotLayout, _theme: import("../../theme/theme").Theme, _dpr: number): void; _gradientCache: GradientTextureCache | null; _xName: string; _yName: string; _xLabel: string; _yLabel: string; _xIsRowIndex: boolean; _colorName: string; _sizeName: string; _labelName: string; _colorIsString: boolean; /** * When the X (or Y) axis source column is post-aggregation * `string`-typed, the build pipeline writes per-row dictionary slot * indices into `_xData` (or `_yData`) instead of numeric values, * and the render pass dispatches `renderCategoricalXTicks` / * `renderCategoricalYTicks` instead of the numeric axis painter. * * The companion `_xCategoryDictionary` / `_xCategorySeen` pair is * built lazily during `processCartesianChunk` in first-seen row * order; `(null)` is appended on first encounter of an invalid row * rather than reserved at slot 0, so charts without missing values * don't get a phantom slot. * * `_xCategoryDomain` is materialized once per frame in * `cartesian-render` and held for chrome overlay redraws (same * lifecycle as `_lastXDomain` on the numeric path). */ _xIsString: boolean; _yIsString: boolean; _xCategoryDictionary: string[]; _yCategoryDictionary: string[]; _xCategorySeen: Map; _yCategorySeen: Map; _xCategoryDomain: CategoricalDomain | null; _yCategoryDomain: CategoricalDomain | null; _splitGroups: SplitGroup[]; _xMin: number; _xMax: number; _yMin: number; _yMax: number; /** * Origin used to rebase x values before f32 narrowing. With datetime * x columns the absolute timestamp is ~1.7e12, beyond f32 precision; * storing `(x - _xOrigin)` keeps sub-millisecond fidelity in the * `_xData` mirror, the GPU position attribute, and the projection * matrix's `tx` term, avoiding the catastrophic cancellation that * would otherwise push points outside the clip volume. NaN until * the first valid x sample is observed. */ _xOrigin: number; _yOrigin: number; _colorMin: number; _colorMax: number; _sizeMin: number; _sizeMax: number; /** * `domain_mode: "expand"` accumulators. The build pipeline seeds * `_xMin/_xMax/_yMin/_yMax/_colorMin/_colorMax/_sizeMin/_sizeMax` * from these instead of `±Infinity` when expand mode is active, so * the per-row scan naturally unions new data into the running * extent. Mirrored back from the live fields at the end of every * `processCartesianChunk` so multi-chunk uploads accumulate into * the same union. Cleared via `resetExpandedDomain` (called from * the worker's `resetAllZooms` and the view-config setters on * `AbstractChart`). */ _expandedXMin: number; _expandedXMax: number; _expandedYMin: number; _expandedYMax: number; _expandedColorMin: number; _expandedColorMax: number; _expandedSizeMin: number; _expandedSizeMax: number; _seriesCapacity: number; _seriesUploadedCounts: number[]; _maxSeriesUploaded: number; _xData: Float32Array | null; _yData: Float32Array | null; _colorData: Float32Array | null; /** * Source view row index for each slot in `_xData` / `_yData`, * sized and laid out identically. Split expansion duplicates the * same arrow source row across every series; this sidecar stores * that source index so lazy tooltip fetches can retrieve the * original row. Int32 for compactness — at 1M points this is * ~4 MB, a small fraction of the ~70 MB that the prior eager * row-data buffers cost. */ _rowIndexData: Int32Array | null; /** * Slot-indexed string store for the scatter "Label" column. `null` * when no label column was wired. See {@link LabelInterner} — the * three formerly-separate label fields (`_labelData`, * `_labelDictionary`, `_labelDictMap`) live there as one unit, so * future label-related state stays cohesive instead of accreting * sibling fields on the chart. */ _labels: LabelInterner | null; _dataCount: number; _uniqueColorLabels: Map; /** * Lazy-tooltip cache. `lines` is `null` until the async row fetch * resolves — the chrome overlay skips the tooltip text box in * that state but still paints the crosshair + highlight ring * from geometry data so the hover cue is immediate. The * controller owns the serial dance that drops stale resolves * when the user moves before the fetch returns. Target type is * the flat slot index of the hovered point. */ _lazyTooltip: LazyTooltip; _stagingPositions: Float32Array | null; _stagingColors: Float32Array | null; _stagingSizes: Float32Array | null; _stagingChunkSize: number; _hitTest: SpatialHitTester; _lastLayout: PlotLayout | null; _hoveredIndex: number; _pinnedIndex: number; /** * Source facet for the current hover (`-1` when not over any facet). * Drives coordinated hover indicator painting in other facets. */ _hoveredFacet: number; _facetGrid: import("../../layout/facet-grid").FacetGrid | null; _lastXDomain: AxisDomain | null; _lastYDomain: AxisDomain | null; _lastXTicks: number[] | null; _lastYTicks: number[] | null; _lastGradientStops: import("../../theme/gradient").GradientStop[] | null; _lastHasColorCol: boolean; _lastLutStops: import("../../theme/gradient").GradientStop[] | null; _lastLutSeriesPalette: [number, number, number][] | null; _lastLutLabelCount: number; protected tooltipCallbacks(): { onHover: (mx: number, my: number) => void; onLeave: () => void; onPin: (mx: number, my: number) => void; onUnpin: () => void; }; /** * Resolve a clicked cartesian point into a `PerspectiveClickDetail` * and emit both `perspective-click` and * `perspective-global-filter selected:true`. * * Cartesian charts don't use `group_by` for positioning; X and Y * come from explicit user-selected columns. The only filter clause * we can build is the split-by prefix (when present). The source * row index is the chart's per-point `_rowIndexData[flatIdx]` * mirror — same lookup the lazy tooltip uses. */ private _emitCartesianClickSelect; uploadAndRender(glManager: WebGLContextManager, columns: ColumnDataMap, startRow: number, endRow: number): Promise; resetExpandedDomain(): void; _fullRender(glManager: WebGLContextManager): void; protected destroyInternal(): void; } /** * X/Y Scatter — continuous chart with the point glyph. */ export declare class ScatterChart extends CartesianChart { constructor(); } /** * X/Y Line — continuous chart with the line glyph. */ export declare class LineChart extends CartesianChart { constructor(); } /** * Density — continuous chart that rasterizes each row as an * additive radial splat, producing a density field over the plot rect. * Shares the cartesian pipeline (build, hit-test, zoom, facets, * tooltips); the glyph swaps the per-point glyph for the heat * accumulation + resolve pair. */ export declare class DensityChart extends CartesianChart { constructor(); }