import { GeoPath, GeoProjection } from 'd3-geo'; import { Topology } from 'topojson-specification'; import { ComputedRef, MaybeRefOrGetter } from '../../node_modules/vue'; /** * Reactive inputs driving {@link useSymbolMap}. Each input is a plain value, ref * or getter so the composable adapts to how the caller wires its state. The * composable holds no DOM state: the measured `width`/`height`, the parsed * topojson and the loaded marker data are passed in from the component. */ export interface UseSymbolMapOptions { /** * The parsed TopoJSON topology used to build the base map features. */ topojson: MaybeRefOrGetter; /** * The marker rows to plot, each carrying at least `longitude`/`latitude`. */ loadedData: MaybeRefOrGetter[] | null>; /** * Measured outer width of the map, in pixels. */ width: MaybeRefOrGetter; /** * Measured outer height of the map, in pixels. */ height: MaybeRefOrGetter; /** * Padding, in pixels, kept between the fitted geometry and the map edges. */ padding: MaybeRefOrGetter; /** * Name of the TopoJSON objects collection to render as map features. */ topojsonObjects: MaybeRefOrGetter; /** * Path in the marker rows to the category value used for grouping/coloring. */ categoryObjectsPath: MaybeRefOrGetter; /** * When true, fit the projection to the marker bounds instead of the feature * bounds. */ fitToMarkers: MaybeRefOrGetter; } /** * Reactive API returned by {@link useSymbolMap}. */ export interface UseSymbolMap { /** * The GeoJSON the projection is fitted to: the markers polygon when * `fitToMarkers` is set, otherwise the topojson features collection. */ geojson: ComputedRef; /** * The topojson features collection rendered as the base map layer. */ featuresGeojson: ComputedRef; /** * A single polygon spanning the markers' coordinates, used to fit the * projection to the markers' bounds. */ markersGeojson: ComputedRef; /** * The `[longitude, latitude]` pairs of every loaded marker. */ coordinates: ComputedRef; /** * The Robinson projection fitted to the map size and the geojson bounds, * inset by `padding` on every edge. */ mapProjection: ComputedRef; /** * The geo path generator bound to {@link mapProjection}. */ featurePath: ComputedRef; /** * The distinct category values across the loaded markers, stringified. */ categories: ComputedRef; /** * Category name to index lookup, so per-marker class assignment stays O(1) * instead of running an `indexOf` (O(n)) for every marker. */ categoryIndexByName: ComputedRef>; /** * Pure geometry helper that turns a projected point and the marker's measured * bounding box into the SVG `transform` that centers and scales the marker. */ markerTransformValue: (point: [number, number], box: { width: number; height: number; }, markerWidth: number) => string; } /** * Owns the symbol-map-specific reactive geometry: it derives the GeoJSON to * render (features or marker bounds), fits a Robinson projection to the map size * with edge padding, exposes the matching geo path generator, indexes the marker * categories, and centers/scales each marker around its projected coordinate. It * holds no DOM state — the measured size, parsed topojson and marker rows are * passed in, and rendering stays in the component. * * @remarks The projection is fitted with `fitExtent` (inset by `padding`), NOT * `fitSize`, so it differs from the shared `useMapProjection` and is kept here * to preserve the symbol map's exact framing behavior. * @param options - Reactive options (see {@link UseSymbolMapOptions}). * @returns The {@link UseSymbolMap} API of derived symbol-map geometry. * @example * // Internal building block of SymbolMap; not exported from the package root. * // Inside a `