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 { /** * Id of the polygon in `polygonSeries` the link starts from, at its * geographic centroid. Also the id of the source node. */ sourceId?: string; /** * Id of the polygon in `polygonSeries` the link ends at, at its geographic * centroid. Also the id of the target node. */ targetId?: string; /** * Longitude the link starts at, when `sourceId` names no polygon. */ sourceLongitude?: number; /** * Latitude the link starts at, when `sourceId` names no polygon. */ sourceLatitude?: number; /** * Longitude the link ends at, when `targetId` names no polygon. */ targetLongitude?: number; /** * Latitude the link ends at, when `targetId` names no polygon. */ targetLatitude?: number; /** * The link's value: its band is as wide as its share of the largest value. */ value?: number; /** * Points the band passes through on its way, in order. */ waypoints?: Array; /** * `controlPointDistance` for this link, instead of the series'. */ controlPointDistance?: number; /** * `controlPointDistanceSource` for this link, instead of the series'. */ controlPointDistanceSource?: number; /** * `controlPointDistanceTarget` for this link, instead of the series'. */ controlPointDistanceTarget?: number; /** * The node the link starts from. * @readonly */ sourceNode?: DataItem; /** * The node the link ends at. * @readonly */ targetNode?: DataItem; } export interface IMapSankeySeriesSettings extends IMapPolygonSeriesSettings { /** * The polygon series that `sourceId` and `targetId` refer to. */ polygonSeries?: MapPolygonSeries; /** * How far a band's curve control points sit from its ends, as a share of * the distance between them, from `0` to `0.5`. Larger values keep the * band level for longer before its S-bend. * * Used where `controlPointDistanceSource` or `controlPointDistanceTarget` * isn't set. * * @default 0.5 */ controlPointDistance?: number; /** * `controlPointDistance` at the source end: larger values keep the band * level for longer as it leaves. */ controlPointDistanceSource?: number; /** * `controlPointDistance` at the target end: larger values keep the band * level for longer as it arrives. */ controlPointDistanceTarget?: number; /** * Which way bands leave and arrive at their nodes: * * * `"horizontal"` - east or west, with bands stacked north to south at each node. * * `"vertical"` - north or south, with bands stacked west to east at each node. * * @default "horizontal" */ orientation?: "horizontal" | "vertical"; /** * Width of the band with the largest value, in degrees. Other bands are as * wide as their share of that value. * * @default 5 */ maxWidth?: number; /** * Points worked out along each curve of a band. More is smoother. * * @default 50 */ resolution?: number; /** * How far, in degrees, a node reaches past the bands it holds: added to a * circle's radius, or to each end of a bar. Hides thin gaps between the * bands and the node. * * @default 0.3 */ nodePadding?: number; /** * Stacks the bands at each node by the latitude of their other end, so * bands heading north sit above those heading south and don't cross. * * @default true */ autoSort?: boolean; /** * How links without `waypoints` treat the 180th meridian: * * * `"short"` - take the shorter way, across it if need be (from China to the US, east over the Pacific). * * `"long"` - never cross it, going the long way round. * * @default "short" */ antimeridian?: "short" | "long"; /** * Shape of the nodes, styled via `nodes.mapPolygons.template`: * * * `"circle"` - a circle around all bands at the node. * * `"bar"` - a bar across the bands, as in a classic Sankey diagram. * * @default "circle" */ nodeType?: "circle" | "bar"; /** * Thickness of a bar node, in degrees, along the way the bands run. Only * with `nodeType: "bar"`. * * @default 1 */ nodeWidth?: number; /** * How bands are colored: * * * `"solid"` - all with the `mapPolygons.template` fill. * * `"source"` - each with its source node's fill. * * `"target"` - each with its target node's fill. * * @default "solid" */ linkColorMode?: "solid" | "source" | "target"; /** * A field in data that holds `sourceId`. * @default "sourceId" */ sourceIdField?: string; /** * A field in data that holds `targetId`. * @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; } /** * A map series of Sankey-style flow bands between places, each as wide as * its value. The bands are polygons on the map, so they follow it as it is * panned, zoomed and rotated. * * @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; /** * The nodes at the ends of the bands. They are made from the link data; set * `nodes.data.setAll([...])` to give them names and fills of your own. * Style them via `nodes.mapPolygons.template`. */ 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; /** * Colors each band from its source or target node, as `linkColorMode` * says, or gives it back its own fill for `"solid"`. * * @ignore */ _applyLinkColors(): void; /** * Unbinds links from nodes that are no longer in `nodes` and binds them * again, to the current nodes. */ private _rebindLinks; /** * (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 the point at a position along a band's center line, relative to * the map's area, and the line's angle there in degrees. * * @param dataItem Data item of the link * @param location Position from `0` (source) to `1` (target) * @return Point in pixels, and angle */ getPoint(dataItem: DataItem, location: number): IOrientationPoint; /** * Returns the geographic point at a position along a band's center line. * * @param dataItem Data item of the link * @param location Position from `0` (source) to `1` (target) * @return Geographic point */ getGeoPoint(dataItem: DataItem, location: number): IGeoPoint | undefined; /** * Returns the approximate length of a band's center line, in radians of * arc on the globe. Useful for making an animation's duration fit the * distance. * * @param dataItem Data item of the link * @return Length in radians */ 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