import type { DataItem } from "../../core/render/Component"; import type { Bullet } from "../../core/render/Bullet"; import type { IOrientationPoint } from "../../core/util/IPoint"; import type { IGeoPoint } from "../../core/util/IGeoPoint"; import { MapPolygonSeries, IMapPolygonSeriesSettings, IMapPolygonSeriesDataItem, IMapPolygonSeriesPrivate } from "./MapPolygonSeries"; import { MapSankeyNodes, IMapSankeyNodesDataItem } from "./MapSankeyNodes"; /** * Parameters for a single cubic bezier segment in geographic coordinates. * @ignore */ export interface IBezierSegment { p0Lon: number; p0Lat: number; p1Lon: number; p1Lat: number; cp0Lon: number; cp0Lat: number; cp1Lon: number; cp1Lat: number; } export interface IMapSankeySeriesPrivate extends IMapPolygonSeriesPrivate { } export interface IMapSankeySeriesDataItem extends IMapPolygonSeriesDataItem { /** * Source polygon ID (matches id in polygonSeries). */ sourceId?: string; /** * Target polygon ID (matches id in polygonSeries). */ targetId?: string; /** * Source longitude (if not using sourceId). */ sourceLongitude?: number; /** * Source latitude (if not using sourceId). */ sourceLatitude?: number; /** * Target longitude (if not using targetId). */ targetLongitude?: number; /** * Target latitude (if not using targetId). */ targetLatitude?: number; /** * Numeric value controlling band thickness. */ value?: number; /** * Waypoints for routing the band through intermediate geographic points. */ waypoints?: Array; /** * Per-link control point distance. Overrides series-level `controlPointDistance`. */ controlPointDistance?: number; /** * Per-link control point distance at the source end. * Overrides series-level `controlPointDistanceSource`. */ controlPointDistanceSource?: number; /** * Per-link control point distance at the target end. * Overrides series-level `controlPointDistanceTarget`. */ controlPointDistanceTarget?: number; /** * Reference to the source node data item. * @readonly */ sourceNode?: DataItem; /** * Reference to the target node data item. * @readonly */ targetNode?: DataItem; } export interface IMapSankeySeriesSettings extends IMapPolygonSeriesSettings { /** * A [[MapPolygonSeries]] to use for resolving `sourceId`/`targetId` to geographic centroids. */ polygonSeries?: MapPolygonSeries; /** * Control point distance for bezier curves (0-0.5). Higher values = * longer straight sections before the S-curve transition. * * Used as fallback when `controlPointDistanceSource` or * `controlPointDistanceTarget` are not set. * * @default 0.5 */ controlPointDistance?: number; /** * Control point distance at the source (departure) end. * Higher values = longer straight section leaving the source node. * * Falls back to `controlPointDistance` if not set. */ controlPointDistanceSource?: number; /** * Control point distance at the target (arrival) end. * Higher values = longer straight section approaching the target node. * * Falls back to `controlPointDistance` if not set. */ controlPointDistanceTarget?: number; /** * Orientation of the S-curve links. * * `"horizontal"` — links depart and arrive horizontally (east/west). * Bands stack vertically at each endpoint. * `"vertical"` — links depart and arrive vertically (north/south). * Bands stack horizontally at each endpoint. * * @default "horizontal" */ orientation?: "horizontal" | "vertical"; /** * Maximum band width in geographic degrees. * @default 5 */ maxWidth?: number; /** * Number of sample points per bezier segment. Higher = smoother curves. * @default 50 */ resolution?: number; /** * Extra padding added to endpoint nodes in geographic degrees. * For circles, added to the radius. For bars, added to the half-height. * Helps avoid subpixel gaps between bands and the node shape. * @default 0.3 */ nodePadding?: number; /** * When `true`, bands at each endpoint are sorted by the latitude of * their target/source so that bands heading north are stacked above * bands heading south. This prevents bands from overlapping. * @default true */ autoSort?: boolean; /** * Controls how links handle the antimeridian (±180° longitude). * * `"short"` — links always take the shorter path, crossing the * antimeridian if needed (e.g. China → US goes east across the Pacific). * `"long"` — links never cross the antimeridian, always going the * long way around. * * Only applies to links without waypoints; waypoints define the * route explicitly. * * @default "short" */ antimeridian?: "short" | "long"; /** * Shape of the endpoint node. Styled via `nodes.mapPolygons.template`. * * `"circle"` — a circle covering all flows at the endpoint. * `"bar"` — a rectangular bar like in a traditional Sankey diagram. * Bar orientation is perpendicular to the flow direction. * * @default "circle" */ nodeType?: "circle" | "bar"; /** * Width of the bar at endpoint nodes in geographic degrees. * Only used when `nodeType` is `"bar"`. * @default 1 */ nodeWidth?: number; /** * Controls how link bands are colored. * * `"solid"` — all links use the template fill (default). * `"source"` — each link inherits the source node's fill. * `"target"` — each link inherits the target node's fill. * * @default "solid" */ linkColorMode?: "solid" | "source" | "target"; /** * A field in data that holds the source polygon ID. * @default "sourceId" */ sourceIdField?: string; /** * A field in data that holds the target polygon ID. * @default "targetId" */ targetIdField?: string; /** * A field in data that holds the source longitude. * @default "sourceLongitude" */ sourceLongitudeField?: string; /** * A field in data that holds the source latitude. * @default "sourceLatitude" */ sourceLatitudeField?: string; /** * A field in data that holds the target longitude. * @default "targetLongitude" */ targetLongitudeField?: string; /** * A field in data that holds the target latitude. * @default "targetLatitude" */ targetLatitudeField?: string; /** * A field in data that holds the waypoints array. * @default "waypoints" */ waypointsField?: string; } /** * Creates a map series for displaying Sankey-style flow bands on a map. * * Generates actual GeoJSON polygon geometries for each flow, so they * properly follow the map projection during panning, zooming, and rotation. * * @see {@link https://www.amcharts.com/docs/v5/charts/map-chart/map-sankey-series/} for more info * @since 5.17.0 * @important */ export declare class MapSankeySeries extends MapPolygonSeries { /** * Don't consume polygon features from geodata - our data comes from user's data array. */ protected _types: Array; /** * A sub-series that manages node data items and visuals. * * Nodes are auto-created from link data. You can also set * `nodes.data.setAll([...])` with custom names and fills. * * `nodes.mapPolygons.template` configures node appearance. */ readonly nodes: MapSankeyNodes; /** * Stored bezier segment params per data item for bullet positioning. * Each link can have multiple segments (when waypoints are used). * @ignore */ _bezierSegments: Map, Array>; /** * Cumulative arc-length array per data item for uniform-speed bullet positioning. * Entry i = cumulative length from segment 0 through segment i. * Last entry = total path length. * @ignore */ _segmentCumulativeLengths: Map, number[]>; private _geoSourceCoords; private _geoTargetCoords; private _geoWidths; private _geoSourceGroups; private _geoTargetGroups; private _geoNodeSourceTotal; private _geoNodeTargetTotal; private _geoNodeRange; private _geoSourceOffsets; private _geoTargetOffsets; /** * Disposer for the polygonSeries `datavalidated` listener. Re-attached * whenever the `polygonSeries` setting changes. */ private _polygonSeriesDP?; /** * @ignore */ protected _afterNew(): void; /** * (Re)subscribes to the current `polygonSeries` `datavalidated` event so * that any data items added before the polygon series finished loading * its geoJSON get their endpoints resolved automatically. */ private _setupPolygonSeriesListener; /** * Walks all data items and resolves any whose source/target endpoints * weren't resolved during the initial `processDataItem` call (because * the polygon series wasn't ready yet). Marks values dirty so the * geometries get regenerated. */ private _resolvePendingDataItems; static className: string; static classNames: Array; _settings: IMapSankeySeriesSettings; _privateSettings: IMapSankeySeriesPrivate; _dataItemSettings: IMapSankeySeriesDataItem; /** * @ignore */ markDirtyProjection(): void; /** * Evaluate a single bezier segment at parameter t. * * Same formula as $math.getPointOnCubicCurve but operates on flat * IBezierSegment fields (lon/lat) to avoid IPoint object allocation. */ protected _evalBezier(bp: IBezierSegment, t: number): IGeoPoint; /** * Approximates the arc length of a single bezier segment by sampling * points along the curve and summing Haversine distances. * * @param bp Bezier segment parameters * @param samples Number of sample intervals (default 20) * @return Approximate arc length in radians */ protected _segmentArcLength(bp: IBezierSegment, samples?: number): number; /** * Computes cumulative arc lengths for a set of bezier segments and * stores them in `_segmentCumulativeLengths` for arc-length parameterization. * * @param dataItem Link data item (used as cache key) * @param segments Array of bezier segment parameters */ protected _computeCumulativeLengths(dataItem: DataItem, segments: Array): void; /** * Resolves a normalized location (0–1) to a segment index and local t * using arc-length parameterization. Delegates to `$math.resolveLocationOnPath` * when cumulative lengths are available; falls back to equal distribution. * * @param dataItem Link data item (for cumulative length lookup) * @param location Relative position along the full path (0–1) * @param segments Array of bezier segment parameters (used for fallback) * @return Segment index and local t (0–1) */ protected _resolveLocation(dataItem: DataItem, location: number, segments: Array): { segIdx: number; t: number; }; /** * Returns a screen-space point at a relative position (0-1) along * the center-line bezier for the given data item. * * Used internally for bullet positioning, but can also be called * directly to get coordinates along a flow path. * * @param dataItem Target data item * @param location Relative position (0 = source, 1 = target) * @return Screen coordinates and angle */ getPoint(dataItem: DataItem, location: number): IOrientationPoint; /** * Returns a geo point at a relative position (0-1) along the center-line bezier. */ getGeoPoint(dataItem: DataItem, location: number): IGeoPoint | undefined; /** * Returns the approximate arc length of the path for a data item. * Useful for scaling animation duration proportionally to distance. */ getPathLength(dataItem: DataItem): number; /** * Combined getPoint + getGeoPoint in a single pass (avoids double * _resolveLocation + _evalBezier per bullet per frame). * @ignore */ private _getPointWithGeo; /** * Positions a bullet along its parent link's bezier path. * * @param bullet Bullet to position */ _positionBullet(bullet: Bullet): void; /** * @ignore */ disposeDataItem(dataItem: DataItem): void; /** * @ignore */ protected _dispose(): void; /** * Processes a newly added data item, creating placeholder geometry and * registering it with source/target nodes. * * @param dataItem Data item to process */ protected processDataItem(dataItem: DataItem): void; /** * Resolves the source/target endpoints for a single data item: * looks up centroids on the polygon series (if `sourceId`/`targetId` is set), * then creates or attaches the appropriate sankey nodes. * * Returns `true` if anything was newly resolved, so callers can decide * whether to mark geometries dirty. * * Safe to call repeatedly: skips endpoints that are already resolved. */ private _resolveEndpoints; /** * @ignore */ protected _onDataClear(): void; /** * @ignore */ _prepareChildren(): void; /** * Rebuilds all link band geometries from current data. * * Computes bezier control points, stacking offsets, band polygons, * and cumulative arc lengths for each link. */ protected _generateGeometries(): void; } //# sourceMappingURL=MapSankeySeries.d.ts.map