@amcharts/amcharts5
Version:
amCharts 5
402 lines • 14.4 kB
TypeScript
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<IGeoPoint>;
/**
* 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<IMapSankeyNodesDataItem>;
/**
* Reference to the target node data item.
* @readonly
*/
targetNode?: DataItem<IMapSankeyNodesDataItem>;
}
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;
}
export declare class MapSankeySeries extends MapPolygonSeries {
/**
* Don't consume polygon features from geodata - our data comes from user's data array.
*/
protected _types: Array<GeoJSON.GeoJsonGeometryTypes>;
/**
* 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<DataItem<IMapSankeySeriesDataItem>, Array<IBezierSegment>>;
/**
* 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<DataItem<IMapSankeySeriesDataItem>, 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<string>;
_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<IMapSankeySeriesDataItem>, segments: Array<IBezierSegment>): 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<IMapSankeySeriesDataItem>, location: number, segments: Array<IBezierSegment>): {
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<IMapSankeySeriesDataItem>, location: number): IOrientationPoint;
/**
* Returns a geo point at a relative position (0-1) along the center-line bezier.
*/
getGeoPoint(dataItem: DataItem<IMapSankeySeriesDataItem>, 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<IMapSankeySeriesDataItem>): 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<this["_dataItemSettings"]>): 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<this["_dataItemSettings"]>): 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