/** * Marker series (fixed-size point symbols), with optional clustering. * * The mark for **"something is here"**: offices, incidents, stores, sightings. * Size is deliberately fixed, because the moment size varies the reader starts * decoding it as a quantity. When it *is* a quantity, that is the bubble series, * which scales by area and ships a legend that can be decoded. * * Three decisions worth stating: * * 1. **Clustering is an option here, not a separate series.** The data is the * same; clustering is a decision about how to draw points that would otherwise * pile up. A separate series type would fork position resolution, hit testing, * colouring and the legend, and would force the caller to swap series at a zoom * threshold. * 2. **Categories colour themselves.** Point maps almost always encode a type * (incident kind, store format), so `colorBy` runs the ordinal scale and emits * a real legend rather than making the caller hand-assign colours. * 3. **Positions may come from the data or from geometry**, exactly as for * bubbles, so "one marker per country office" needs no coordinates. * * @module series/Marker */ import { Scale } from '../scales/Scale'; import type { Cluster } from '../geo/Cluster'; import type { JoinResult } from '../data/Join'; import { Viewport } from '../geo/Viewport'; import type { ClusterOptions, LonLat, MarkItem, MarkerSeriesOptions, MarkerShape, NormalizedGeo, WorldPoint } from '../types'; import type { MarkSpec } from '../renderers/SvgRenderer'; export interface MarkerItem extends MarkItem { lonLat: LonLat; world: WorldPoint | null; shape: MarkerShape; size: number; category?: string; } export declare class MarkerSeries { static readonly type: "marker"; static readonly kind: "marks"; readonly type: "marker"; readonly kind: "marks"; readonly config: MarkerSeriesOptions; readonly index: number; readonly id: string; readonly warnings: string[]; readonly items: MarkerItem[]; readonly colorScale: Scale | null; readonly join: JoinResult | null; /** * Categories switched off from the legend, by name rather than by legend index. * * A marker legend is categorical, so what a click means is "hide this kind", and * a kind is a string on the datum. Holding the index instead would cost a lookup * through `colorScale.categories` for every marker on every draw, and would go * wrong the moment the category set changes under an `updateSeries` while the * legend's own muted state survives it. */ readonly mutedCategories: Set; /** * Clusters for the level they were computed at, so a pan never recomputes. * * `cachedValid` is separate from `cachedLevel` because `null` is a legitimate * level meaning "not clustering at this zoom", and it must not be confused with * "nothing computed yet". */ private cachedLevel; private cachedValid; private cached; constructor({ config, geo, index, viewport, }: { config: MarkerSeriesOptions; geo: NormalizedGeo; index: number; viewport: Viewport; }); /** Recompute world positions after a projection change, and drop the cache. */ reproject(viewport: Viewport): void; itemAt(index: number): MarkerItem | undefined; fillFor(item: MarkerItem): string; get clusterOptions(): Required> & ClusterOptions; clusteringEnabled(zoom: number): boolean; /** * True when the drawn marks would change at this camera scale. * * Panning never changes the level, so a pan never reclusters, and a smooth zoom * crosses a level only a few times rather than sixty times a second. */ needsRedraw(zoom: number): boolean; private levelFor; /** Clusters at this camera scale, cached per level. */ clusters(zoom: number): Cluster[]; clusterAt(index: number): Cluster | undefined; /** Marks for the renderer at this camera scale: individual points or clusters. */ marks(zoom: number): MarkSpec[]; legendTitle(): string | undefined; /** A categorical legend, but only when categories are actually driving colour. */ legendItems(): { label: string; color: string; }[]; /** Whether the legend has switched off the category this marker belongs to. */ isMuted(item: MarkerItem): boolean; /** * Switch a legend category off, or back on. Returns the new muted state. * * The cluster cache goes with it, and that is the whole substance of this * method. Clusters are computed from `items` and cached per level, so filtering * only at the drawing stage would leave a cluster of twelve still saying twelve * with five of its members hidden. A wrong number on the map is worse than a * legend that does nothing, which is what this used to be. */ toggleClass(classIndex: number): boolean; describe(item: MarkerItem): string; describeCluster(cluster: Cluster): string; advise(): string[]; } //# sourceMappingURL=Marker.d.ts.map