You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by sh...@apache.org on 2020/03/12 09:50:52 UTC

[incubator-echarts] branch typescript updated: ts: add types for sankey

This is an automated email from the ASF dual-hosted git repository.

shenyi pushed a commit to branch typescript
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git


The following commit(s) were added to refs/heads/typescript by this push:
     new 8271ff7  ts: add types for sankey
8271ff7 is described below

commit 8271ff71220f595498fc68ebe7fbedd4f67f07b3
Author: pissang <bm...@gmail.com>
AuthorDate: Thu Mar 12 17:50:17 2020 +0800

    ts: add types for sankey
---
 src/chart/bar/BarSeries.ts                     |   2 +
 src/chart/boxplot/BoxplotSeries.ts             |   1 +
 src/chart/candlestick/CandlestickSeries.ts     |   2 +
 src/chart/effectScatter/EffectScatterSeries.ts |   1 +
 src/chart/funnel/FunnelSeries.ts               |   1 +
 src/chart/gauge/GaugeSeries.ts                 |   1 +
 src/chart/graph/GraphSeries.ts                 |   2 +
 src/chart/heatmap/HeatmapSeries.ts             |   1 +
 src/chart/line/LineSeries.ts                   |   2 +
 src/chart/lines/LinesSeries.ts                 |   2 +
 src/chart/map/MapSeries.ts                     |   1 +
 src/chart/sankey/SankeySeries.ts               | 195 ++++++++++++++-----
 src/chart/sankey/SankeyView.ts                 | 250 ++++++++++++++++---------
 src/chart/sankey/sankeyAction.ts               |  18 +-
 src/chart/sankey/sankeyLayout.ts               | 179 ++++++++++--------
 src/chart/sankey/sankeyVisual.ts               |  10 +-
 src/chart/scatter/ScatterSeries.ts             |   1 +
 src/chart/sunburst/SunburstSeries.ts           |   1 +
 src/chart/sunburst/SunburstView.ts             |   1 +
 src/chart/themeRiver/ThemeRiverSeries.ts       |   2 +
 src/chart/tree/TreeSeries.ts                   |   1 +
 src/data/Graph.ts                              |   2 +-
 src/echarts.ts                                 |   2 +-
 src/util/model.ts                              |  13 +-
 24 files changed, 459 insertions(+), 232 deletions(-)

diff --git a/src/chart/bar/BarSeries.ts b/src/chart/bar/BarSeries.ts
index f5a26f0..7f756c9 100644
--- a/src/chart/bar/BarSeries.ts
+++ b/src/chart/bar/BarSeries.ts
@@ -48,6 +48,8 @@ export interface BarDataItemOption {
 }
 
 export interface BarSeriesOption extends BaseBarSeriesOption, SeriesStackOptionMixin {
+    type?: 'bar'
+
     coordinateSystem?: 'cartesian2d' | 'polar'
 
     clip?: boolean
diff --git a/src/chart/boxplot/BoxplotSeries.ts b/src/chart/boxplot/BoxplotSeries.ts
index b658f14..04eef95 100644
--- a/src/chart/boxplot/BoxplotSeries.ts
+++ b/src/chart/boxplot/BoxplotSeries.ts
@@ -48,6 +48,7 @@ export interface BoxplotDataItemOption {
 }
 
 export interface BoxplotSeriesOption extends SeriesOption, SeriesOnCartesianOptionMixin {
+    type?: 'boxplot'
 
     coordinateSystem?: 'cartesian2d'
 
diff --git a/src/chart/candlestick/CandlestickSeries.ts b/src/chart/candlestick/CandlestickSeries.ts
index 884ad76..172c303 100644
--- a/src/chart/candlestick/CandlestickSeries.ts
+++ b/src/chart/candlestick/CandlestickSeries.ts
@@ -55,6 +55,8 @@ interface CandlestickItemStyleOption extends ItemStyleOption {
 
 export interface CandlestickSeriesOption extends SeriesOption, SeriesOnCartesianOptionMixin, SeriesLargeOptionMixin {
 
+    type?: 'candlestick'
+
     coordinateSystem?: 'cartesian2d'
 
     hoverAnimation?: boolean
diff --git a/src/chart/effectScatter/EffectScatterSeries.ts b/src/chart/effectScatter/EffectScatterSeries.ts
index 7a634fe..b9b2ac2 100644
--- a/src/chart/effectScatter/EffectScatterSeries.ts
+++ b/src/chart/effectScatter/EffectScatterSeries.ts
@@ -56,6 +56,7 @@ export interface EffectScatterDataItemOption extends SymbolOptionMixin {
 export interface EffectScatterSeriesOption extends SeriesOption,
     SeriesOnCartesianOptionMixin, SeriesOnPolarOptionMixin, SeriesOnCalendarOptionMixin,
     SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin, SymbolOptionMixin {
+    type?: 'effectScatter'
 
     coordinateSystem?: string
 
diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts
index 07d650b..710879d 100644
--- a/src/chart/funnel/FunnelSeries.ts
+++ b/src/chart/funnel/FunnelSeries.ts
@@ -61,6 +61,7 @@ export interface FunnelDataItemOption {
 
 export interface FunnelSeriesOption
     extends SeriesOption, BoxLayoutOptionMixin {
+    type?: 'funnel'
 
     min?: number
     max?: number
diff --git a/src/chart/gauge/GaugeSeries.ts b/src/chart/gauge/GaugeSeries.ts
index 40de830..ae3bc2d 100644
--- a/src/chart/gauge/GaugeSeries.ts
+++ b/src/chart/gauge/GaugeSeries.ts
@@ -57,6 +57,7 @@ export interface GaugeDataItemOption {
     pointer?: PointerOption
 }
 export interface GaugeSeriesOption extends SeriesOption, CircleLayoutOptionMixin {
+    type?: 'gauge'
 
     // override radius
     radius?: number | string
diff --git a/src/chart/graph/GraphSeries.ts b/src/chart/graph/GraphSeries.ts
index b2d55e7..ad8a8cd 100644
--- a/src/chart/graph/GraphSeries.ts
+++ b/src/chart/graph/GraphSeries.ts
@@ -142,6 +142,8 @@ interface GraphSeriesOption extends SeriesOption,
     RoamOptionMixin,
     BoxLayoutOptionMixin {
 
+    type?: 'graph'
+
     coordinateSystem?: string
 
     hoverAnimation?: boolean
diff --git a/src/chart/heatmap/HeatmapSeries.ts b/src/chart/heatmap/HeatmapSeries.ts
index 2f44a13..bdff95c 100644
--- a/src/chart/heatmap/HeatmapSeries.ts
+++ b/src/chart/heatmap/HeatmapSeries.ts
@@ -50,6 +50,7 @@ export interface HeatmapDataItemOption {
 
 export interface HeatmapSeriesOption extends SeriesOption,
     SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin {
+    type?: 'heatmap'
 
     coordinateSystem?: 'cartesian2d' | 'geo' | 'calendar'
 
diff --git a/src/chart/line/LineSeries.ts b/src/chart/line/LineSeries.ts
index 0774393..810cf5b 100644
--- a/src/chart/line/LineSeries.ts
+++ b/src/chart/line/LineSeries.ts
@@ -59,6 +59,8 @@ export interface LineSeriesOption extends SeriesOption,
     SeriesStackOptionMixin,
     SeriesSamplingOptionMixin,
     SymbolOptionMixin {
+    type?: 'line'
+
     coordinateSystem?: 'cartesian2d' | 'polar'
 
     hoverAnimation?: boolean
diff --git a/src/chart/lines/LinesSeries.ts b/src/chart/lines/LinesSeries.ts
index dfbb0c6..589cc14 100644
--- a/src/chart/lines/LinesSeries.ts
+++ b/src/chart/lines/LinesSeries.ts
@@ -107,6 +107,8 @@ export interface LinesSeriesOption extends SeriesOption,
     SeriesOnCartesianOptionMixin, SeriesOnGeoOptionMixin, SeriesOnPolarOptionMixin,
     SeriesOnCalendarOptionMixin, SeriesLargeOptionMixin {
 
+    type?: 'lines'
+
     coordinateSystem?: string
     hoverAnimation?: boolean
 
diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts
index e8933c5..669e26c 100644
--- a/src/chart/map/MapSeries.ts
+++ b/src/chart/map/MapSeries.ts
@@ -68,6 +68,7 @@ export interface MapSeriesOption extends
     BoxLayoutOptionMixin,
     DataSelectableOptionMixin,
     SeriesEncodeOptionMixin {
+    type?: 'map'
 
     coordinateSystem?: string;
     silent?: boolean;
diff --git a/src/chart/sankey/SankeySeries.ts b/src/chart/sankey/SankeySeries.ts
index 8f74bd1..4da37b2 100644
--- a/src/chart/sankey/SankeySeries.ts
+++ b/src/chart/sankey/SankeySeries.ts
@@ -17,21 +17,137 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import SeriesModel from '../../model/Series';
 import createGraphFromNodeEdge from '../helper/createGraphFromNodeEdge';
 import {encodeHTML} from '../../util/format';
 import Model from '../../model/Model';
 import { __DEV__ } from '../../config';
+import {
+    SeriesOption,
+    BoxLayoutOptionMixin,
+    OptionDataValue,
+    LabelOption,
+    ItemStyleOption,
+    LineStyleOption,
+    LayoutOrient,
+    ColorString
+} from '../../util/types';
+import GlobalModel from '../../model/Global';
+import List from '../../data/List';
+import { LayoutRect } from '../../util/layout';
+
+type SankeyDataValue = OptionDataValue | OptionDataValue[]
+
+type FocusNodeAdjacency = boolean | 'inEdges' | 'outEdges' | 'allEdges'
+
+interface SankeyEdgeStyleOption extends LineStyleOption {
+    curveness?: number
+}
+
+export interface SankeyNodeItemOption {
+    id?: string
+    name?: string
+    value?: SankeyDataValue
+
+    localX?: number
+    localY?: number
+
+    depth?: number
+
+    draggable?: boolean
+
+    focusNodeAdjacency?: FocusNodeAdjacency
+
+    label?: LabelOption
+    itemStyle?: ItemStyleOption
+    emphasis?: {
+        label?: LabelOption
+        itemStyle?: ItemStyleOption
+    }
+}
+
+export interface SankeyEdgeItemOption {
+    /**
+     * Name or index of source node.
+     */
+    source?: string | number
+    /**
+     * Name or index of target node.
+     */
+    target?: string | number
+
+    focusNodeAdjacency?: FocusNodeAdjacency
+
+    lineStyle?: SankeyEdgeStyleOption
+    emphasis?: {
+        lineStyle?: SankeyEdgeStyleOption
+    }
+}
+
+export interface SankeyLevelOption {
+    depth: number
+}
+
+export interface SankeySeriesOption extends SeriesOption, BoxLayoutOptionMixin {
+    type?: 'sankey'
+
+    /**
+     * color will be linear mapped.
+     */
+    color?: ColorString[]
+
+    coordinateSystem?: 'view'
+
+    orient?: LayoutOrient
+    /**
+     * The width of the node
+     */
+    nodeWidth?: number
+    /**
+     * The vertical distance between two nodes
+     */
+    nodeGap?: number
 
-var SankeySeries = SeriesModel.extend({
+    /**
+     * Control if the node can move or not
+     */
+    draggable?: boolean
+    /**
+     * Will be allEdges if true.
+     */
+    focusNodeAdjacency?: FocusNodeAdjacency
+    /**
+     * The number of iterations to change the position of the node
+     */
+    layoutIterations?: number
+
+    nodeAlign?: 'justify' | 'left' | 'right'    // TODO justify should be auto
+
+    label?: LabelOption
+    itemStyle?: ItemStyleOption
+    lineStyle?: SankeyEdgeStyleOption
+    emphasis?: {
+        label?: LabelOption
+        itemStyle?: ItemStyleOption
+        lineStyle?: SankeyEdgeStyleOption
+    }
+
+    data?: SankeyNodeItemOption[]
+    nodes?: SankeyNodeItemOption[]
+
+    edges?: SankeyEdgeItemOption[]
+    links?: SankeyEdgeItemOption[]
 
-    type: 'series.sankey',
+    levels?: SankeyLevelOption[]
+}
 
-    layoutInfo: null,
+class SankeySeriesModel extends SeriesModel<SankeySeriesOption> {
+    static readonly type = 'series.sankey'
+    readonly type = SankeySeriesModel.type
 
-    levelModels: null,
+    levelModels: Model<SankeyLevelOption>[]
+
+    layoutInfo: LayoutRect
 
     /**
      * Init a graph data structure from data in option series
@@ -39,11 +155,12 @@ var SankeySeries = SeriesModel.extend({
      * @param  {Object} option  the object used to config echarts view
      * @return {module:echarts/data/List} storage initial data
      */
-    getInitialData: function (option, ecModel) {
+    getInitialData(option: SankeySeriesOption, ecModel: GlobalModel) {
         var links = option.edges || option.links;
         var nodes = option.data || option.nodes;
         var levels = option.levels;
-        var levelModels = this.levelModels = {};
+        this.levelModels = [];
+        var levelModels = this.levelModels;
 
         for (var i = 0; i < levels.length; i++) {
             if (levels[i].depth != null && levels[i].depth >= 0) {
@@ -59,10 +176,10 @@ var SankeySeries = SeriesModel.extend({
             var graph = createGraphFromNodeEdge(nodes, links, this, true, beforeLink);
             return graph.data;
         }
-        function beforeLink(nodeData, edgeData) {
+        function beforeLink(nodeData: List, edgeData: List) {
             nodeData.wrapMethod('getItemModel', function (model, idx) {
-                model.customizeGetParent(function (path) {
-                    var parentModel = this.parentModel;
+                model.customizeGetParent(function (this: Model, path: string | string[]) {
+                    var parentModel = this.parentModel as SankeySeriesModel;
                     var nodeDepth = parentModel.getData().getItemLayout(idx).depth;
                     var levelModel = parentModel.levelModels[nodeDepth];
                     return levelModel || this.parentModel;
@@ -71,8 +188,8 @@ var SankeySeries = SeriesModel.extend({
             });
 
             edgeData.wrapMethod('getItemModel', function (model, idx) {
-                model.customizeGetParent(function (path) {
-                    var parentModel = this.parentModel;
+                model.customizeGetParent(function (this: Model, path: string | string[]) {
+                    var parentModel = this.parentModel as SankeySeriesModel;
                     var edge = parentModel.getGraph().getEdgeByIndex(idx);
                     var depth = edge.node1.getLayout().depth;
                     var levelModel = parentModel.levelModels[depth];
@@ -81,36 +198,36 @@ var SankeySeries = SeriesModel.extend({
                 return model;
             });
         }
-    },
+    }
 
-    setNodePosition: function (dataIndex, localPosition) {
+    setNodePosition(dataIndex: number, localPosition: number[]) {
         var dataItem = this.option.data[dataIndex];
         dataItem.localX = localPosition[0];
         dataItem.localY = localPosition[1];
-    },
+    }
 
     /**
      * Return the graphic data structure
      *
-     * @return {module:echarts/data/Graph} graphic data structure
+     * @return graphic data structure
      */
-    getGraph: function () {
+    getGraph() {
         return this.getData().graph;
-    },
+    }
 
     /**
      * Get edge data of graphic data structure
      *
-     * @return {module:echarts/data/List} data structure of list
+     * @return data structure of list
      */
-    getEdgeData: function () {
+    getEdgeData() {
         return this.getGraph().edgeData;
-    },
+    }
 
     /**
      * @override
      */
-    formatTooltip: function (dataIndex, multipleSeries, dataType) {
+    formatTooltip(dataIndex: number, multipleSeries: boolean, dataType: 'node' | 'edge') {
         // dataType === 'node' or empty do not show tooltip by default
         if (dataType === 'edge') {
             var params = this.getDataParams(dataIndex, dataType);
@@ -130,57 +247,47 @@ var SankeySeries = SeriesModel.extend({
             }
             return encodeHTML(html);
         }
-        return SankeySeries.superCall(this, 'formatTooltip', dataIndex, multipleSeries);
-    },
+        return super.formatTooltip(dataIndex, multipleSeries);
+    }
 
-    optionUpdated: function () {
+    optionUpdated() {
         var option = this.option;
         if (option.focusNodeAdjacency === true) {
             option.focusNodeAdjacency = 'allEdges';
         }
-    },
+    }
 
     // Override Series.getDataParams()
-    getDataParams: function (dataIndex, dataType) {
-        var params = SankeySeries.superCall(this, 'getDataParams', dataIndex, dataType);
+    getDataParams(dataIndex: number, dataType: 'node' | 'edge') {
+        var params = super.getDataParams(dataIndex, dataType);
         if (params.value == null && dataType === 'node') {
             var node = this.getGraph().getNodeByIndex(dataIndex);
             var nodeValue = node.getLayout().value;
             params.value = nodeValue;
         }
         return params;
-    },
+    }
 
-    defaultOption: {
+    static defaultOption: SankeySeriesOption = {
         zlevel: 0,
         z: 2,
 
         coordinateSystem: 'view',
 
-        layout: null,
-
-        // The position of the whole view
         left: '5%',
         top: '5%',
         right: '20%',
         bottom: '5%',
 
-        // Value can be 'vertical'
         orient: 'horizontal',
 
-        // The dx of the node
         nodeWidth: 20,
 
-        // The vertical distance between two nodes
         nodeGap: 8,
-
-        // Control if the node can move or not
         draggable: true,
 
-        // Value can be 'inEdges', 'outEdges', 'allEdges', true (the same as 'allEdges').
         focusNodeAdjacency: false,
 
-        // The number of iterations to change the position of the node
         layoutIterations: 32,
 
         label: {
@@ -192,7 +299,6 @@ var SankeySeries = SeriesModel.extend({
 
         levels: [],
 
-        // Value can be 'left' or 'right'
         nodeAlign: 'justify',
 
         itemStyle: {
@@ -219,7 +325,8 @@ var SankeySeries = SeriesModel.extend({
 
         animationDuration: 1000
     }
+}
 
-});
+SeriesModel.registerClass(SankeySeriesModel);
 
-export default SankeySeries;
\ No newline at end of file
+export default SankeySeriesModel;
\ No newline at end of file
diff --git a/src/chart/sankey/SankeyView.ts b/src/chart/sankey/SankeyView.ts
index 3dcbeea..4d26dbc 100644
--- a/src/chart/sankey/SankeyView.ts
+++ b/src/chart/sankey/SankeyView.ts
@@ -17,23 +17,52 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as graphic from '../../util/graphic';
-import * as echarts from '../../echarts';
 import * as zrUtil from 'zrender/src/core/util';
+import { LayoutOrient, Payload } from '../../util/types';
+import { PathProps } from 'zrender/src/graphic/Path';
+import SankeySeriesModel, { SankeyEdgeItemOption, SankeyNodeItemOption } from './SankeySeries';
+import ChartView from '../../view/Chart';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { GraphNode, GraphEdge } from '../../data/Graph';
+import { GraphNodeItemOption, GraphEdgeItemOption } from '../graph/GraphSeries';
+import List from '../../data/List';
+import { RectLike } from 'zrender/src/core/BoundingRect';
+
+const nodeOpacityPath = ['itemStyle', 'opacity'] as const;
+const hoverNodeOpacityPath = ['emphasis', 'itemStyle', 'opacity'] as const;
+const lineOpacityPath = ['lineStyle', 'opacity'] as const;
+const hoverLineOpacityPath = ['emphasis', 'lineStyle', 'opacity'] as const;
+
+interface FocusNodeAdjacencyPayload extends Payload {
+    dataIndex?: number
+    edgeDataIndex?: number
+}
 
-var nodeOpacityPath = ['itemStyle', 'opacity'];
-var hoverNodeOpacityPath = ['emphasis', 'itemStyle', 'opacity'];
-var lineOpacityPath = ['lineStyle', 'opacity'];
-var hoverLineOpacityPath = ['emphasis', 'lineStyle', 'opacity'];
+interface SankeyEl extends graphic.Path {
+    downplay(): void
+    highlight(): void
 
-function getItemOpacity(item, opacityPath) {
-    return item.getVisual('opacity') || item.getModel().get(opacityPath);
+    focusNodeAdjHandler(): void
+    unfocusNodeAdjHandler(): void
 }
 
-function fadeOutItem(item, opacityPath, opacityRatio) {
-    var el = item.getGraphicEl();
+function getItemOpacity(
+    item: GraphNode | GraphEdge,
+    opacityPath: readonly string[]
+): number {
+    return item.getVisual('opacity')
+        // TODO: TYPE
+        || item.getModel<GraphNodeItemOption>().get(opacityPath as typeof nodeOpacityPath);
+}
+
+function fadeOutItem(
+    item: GraphNode | GraphEdge,
+    opacityPath: readonly string[],
+    opacityRatio?: number
+) {
+    var el = item.getGraphicEl() as SankeyEl;
     var opacity = getItemOpacity(item, opacityPath);
 
     if (opacityRatio != null) {
@@ -42,6 +71,7 @@ function fadeOutItem(item, opacityPath, opacityRatio) {
     }
 
     el.downplay && el.downplay();
+
     el.traverse(function (child) {
         if (child.type !== 'group') {
             child.setStyle('opacity', opacity);
@@ -49,31 +79,52 @@ function fadeOutItem(item, opacityPath, opacityRatio) {
     });
 }
 
-function fadeInItem(item, opacityPath) {
+function fadeInItem(
+    item: GraphNode | GraphEdge,
+    opacityPath: readonly string[]
+) {
     var opacity = getItemOpacity(item, opacityPath);
-    var el = item.getGraphicEl();
+    var el = item.getGraphicEl() as SankeyEl;
+
+    // Support emphasis here.
+    el.highlight && el.highlight();
 
     el.traverse(function (child) {
         if (child.type !== 'group') {
             child.setStyle('opacity', opacity);
         }
     });
+}
 
-    // Support emphasis here.
-    el.highlight && el.highlight();
+class SankeyPathShape {
+    x1 = 0
+    y1 = 0
+
+    x2 = 0
+    y2 = 0
+
+    cpx1 = 0
+    cpy1 = 0
+
+    cpx2 = 0
+    cpy2 = 0
+
+    extent = 0
+    orient: LayoutOrient
+}
+
+interface SankeyPathProps extends PathProps {
+    shape?: Partial<SankeyPathShape>
 }
 
-var SankeyShape = graphic.extendShape({
-    shape: {
-        x1: 0, y1: 0,
-        x2: 0, y2: 0,
-        cpx1: 0, cpy1: 0,
-        cpx2: 0, cpy2: 0,
-        extent: 0,
-        orient: ''
-    },
-
-    buildPath: function (ctx, shape) {
+class SankeyPath extends graphic.Path {
+    shape: SankeyPathShape
+
+    constructor(opts?: SankeyPathProps) {
+        super(opts, null, new SankeyPathShape());
+    }
+
+    buildPath(ctx: CanvasRenderingContext2D, shape: SankeyPathShape) {
         var extent = shape.extent;
         ctx.moveTo(shape.x1, shape.y1);
         ctx.bezierCurveTo(
@@ -98,34 +149,31 @@ var SankeyShape = graphic.extendShape({
             );
         }
         ctx.closePath();
-    },
+    }
 
-    highlight: function () {
+    highlight() {
         this.trigger('emphasis');
-    },
+    }
 
-    downplay: function () {
+    downplay() {
         this.trigger('normal');
     }
-});
+}
+
+class SankeyView extends ChartView {
 
-export default echarts.extendChartView({
+    static readonly type = 'sankey'
+    readonly type = SankeyView.type
 
-    type: 'sankey',
+    private _model: SankeySeriesModel
 
-    /**
-     * @private
-     * @type {module:echarts/chart/sankey/SankeySeries}
-     */
-    _model: null,
+    private _focusAdjacencyDisabled = false
 
-    /**
-     * @private
-     * @type {boolean}
-     */
-    _focusAdjacencyDisabled: false,
+    private _data: List
 
-    render: function (seriesModel, ecModel, api) {
+    private _unfocusDelayTimer: number
+
+    render(seriesModel: SankeySeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
         var sankeyView = this;
         var graph = seriesModel.getGraph();
         var group = this.group;
@@ -146,29 +194,31 @@ export default echarts.extendChartView({
 
         // generate a bezire Curve for each edge
         graph.eachEdge(function (edge) {
-            var curve = new SankeyShape();
-            curve.dataIndex = edge.dataIndex;
-            curve.seriesIndex = seriesModel.seriesIndex;
-            curve.dataType = 'edge';
-            var lineStyleModel = edge.getModel('lineStyle');
-            var curvature = lineStyleModel.get('curveness');
-            var n1Layout = edge.node1.getLayout();
-            var node1Model = edge.node1.getModel();
-            var dragX1 = node1Model.get('localX');
-            var dragY1 = node1Model.get('localY');
-            var n2Layout = edge.node2.getLayout();
-            var node2Model = edge.node2.getModel();
-            var dragX2 = node2Model.get('localX');
-            var dragY2 = node2Model.get('localY');
-            var edgeLayout = edge.getLayout();
-            var x1;
-            var y1;
-            var x2;
-            var y2;
-            var cpx1;
-            var cpy1;
-            var cpx2;
-            var cpy2;
+            var curve = new SankeyPath();
+            var ecData = graphic.getECData(curve);
+            ecData.dataIndex = edge.dataIndex;
+            ecData.seriesIndex = seriesModel.seriesIndex;
+            ecData.dataType = 'edge';
+            const edgeModel = edge.getModel<SankeyEdgeItemOption>();
+            const lineStyleModel = edgeModel.getModel('lineStyle');
+            const curvature = lineStyleModel.get('curveness');
+            const n1Layout = edge.node1.getLayout();
+            const node1Model = edge.node1.getModel<SankeyNodeItemOption>();
+            const dragX1 = node1Model.get('localX');
+            const dragY1 = node1Model.get('localY');
+            const n2Layout = edge.node2.getLayout();
+            const node2Model = edge.node2.getModel<SankeyNodeItemOption>();
+            const dragX2 = node2Model.get('localX');
+            const dragY2 = node2Model.get('localY');
+            const edgeLayout = edge.getLayout();
+            var x1: number;
+            var y1: number;
+            var x2: number;
+            var y2: number;
+            var cpx1: number;
+            var cpy1: number;
+            var cpx2: number;
+            var cpy2: number;
 
             curve.shape.extent = Math.max(1, edgeLayout.dy);
             curve.shape.orient = orient;
@@ -216,7 +266,10 @@ export default echarts.extendChartView({
                     break;
             }
 
-            graphic.setHoverStyle(curve, edge.getModel('emphasis.lineStyle').getItemStyle());
+            graphic.setHoverStyle(
+                curve,
+                edgeModel.getModel(['emphasis', 'lineStyle']).getItemStyle()
+            );
 
             group.add(curve);
 
@@ -226,11 +279,11 @@ export default echarts.extendChartView({
         // Generate a rect for each node
         graph.eachNode(function (node) {
             var layout = node.getLayout();
-            var itemModel = node.getModel();
+            var itemModel = node.getModel<SankeyNodeItemOption>();
             var dragX = itemModel.get('localX');
             var dragY = itemModel.get('localY');
             var labelModel = itemModel.getModel('label');
-            var labelHoverModel = itemModel.getModel('emphasis.label');
+            var labelHoverModel = itemModel.getModel(['emphasis', 'label']);
 
             var rect = new graphic.Rect({
                 shape: {
@@ -242,7 +295,7 @@ export default echarts.extendChartView({
                 style: itemModel.getModel('itemStyle').getItemStyle()
             });
 
-            var hoverStyle = node.getModel('emphasis.itemStyle').getItemStyle();
+            var hoverStyle = itemModel.getModel(['emphasis', 'itemStyle']).getItemStyle();
 
             graphic.setLabelStyle(
                 rect.style, hoverStyle, labelModel, labelHoverModel,
@@ -262,13 +315,13 @@ export default echarts.extendChartView({
 
             nodeData.setItemGraphicEl(node.dataIndex, rect);
 
-            rect.dataType = 'node';
+            graphic.getECData(rect).dataType = 'node';
         });
 
-        nodeData.eachItemGraphicEl(function (el, dataIndex) {
-            var itemModel = nodeData.getItemModel(dataIndex);
+        nodeData.eachItemGraphicEl(function (el: graphic.Rect & SankeyEl, dataIndex: number) {
+            var itemModel = nodeData.getItemModel<SankeyNodeItemOption>(dataIndex);
             if (itemModel.get('draggable')) {
-                el.drift = function (dx, dy) {
+                el.drift = function (this: typeof el, dx, dy) {
                     sankeyView._focusAdjacencyDisabled = true;
                     this.shape.x += dx;
                     this.shape.y += dy;
@@ -306,7 +359,7 @@ export default echarts.extendChartView({
                         api.dispatchAction({
                             type: 'focusNodeAdjacency',
                             seriesId: seriesModel.id,
-                            dataIndex: el.dataIndex
+                            dataIndex: graphic.getECData(el).dataIndex
                         });
                     }
                 });
@@ -319,8 +372,8 @@ export default echarts.extendChartView({
             }
         });
 
-        edgeData.eachItemGraphicEl(function (el, dataIndex) {
-            var edgeModel = edgeData.getItemModel(dataIndex);
+        edgeData.eachItemGraphicEl(function (el: SankeyPath & SankeyEl, dataIndex) {
+            var edgeModel = edgeData.getItemModel<GraphEdgeItemOption>(dataIndex);
 
             el.focusNodeAdjHandler && el.off('mouseover', el.focusNodeAdjHandler);
             el.unfocusNodeAdjHandler && el.off('mouseout', el.unfocusNodeAdjHandler);
@@ -332,7 +385,7 @@ export default echarts.extendChartView({
                         api.dispatchAction({
                             type: 'focusNodeAdjacency',
                             seriesId: seriesModel.id,
-                            edgeDataIndex: el.dataIndex
+                            edgeDataIndex: graphic.getECData(el).dataIndex
                         });
                     }
                 });
@@ -352,13 +405,13 @@ export default echarts.extendChartView({
         }
 
         this._data = seriesModel.getData();
-    },
+    }
 
-    dispose: function () {
+    dispose() {
         this._clearTimer();
-    },
+    }
 
-    _dispatchUnfocus: function (api) {
+    _dispatchUnfocus(api: ExtensionAPI) {
         var self = this;
         this._clearTimer();
         this._unfocusDelayTimer = setTimeout(function () {
@@ -367,21 +420,26 @@ export default echarts.extendChartView({
                 type: 'unfocusNodeAdjacency',
                 seriesId: self._model.id
             });
-        }, 500);
-    },
+        }, 500) as any;
+    }
 
-    _clearTimer: function () {
+    _clearTimer() {
         if (this._unfocusDelayTimer) {
             clearTimeout(this._unfocusDelayTimer);
             this._unfocusDelayTimer = null;
         }
-    },
+    }
 
-    focusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+    focusNodeAdjacency(
+        seriesModel: SankeySeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        payload: FocusNodeAdjacencyPayload
+    ) {
         var data = seriesModel.getData();
         var graph = data.graph;
         var dataIndex = payload.dataIndex;
-        var itemModel = data.getItemModel(dataIndex);
+        var itemModel = data.getItemModel<SankeyNodeItemOption>(dataIndex);
         var edgeDataIndex = payload.edgeDataIndex;
 
         if (dataIndex == null && edgeDataIndex == null) {
@@ -434,9 +492,11 @@ export default echarts.extendChartView({
             fadeInItem(edge.node1, hoverNodeOpacityPath);
             fadeInItem(edge.node2, hoverNodeOpacityPath);
         }
-    },
+    }
 
-    unfocusNodeAdjacency: function (seriesModel, ecModel, api, payload) {
+    unfocusNodeAdjacency(
+        seriesModel: SankeySeriesModel
+    ) {
         var graph = seriesModel.getGraph();
 
         graph.eachNode(function (node) {
@@ -446,10 +506,10 @@ export default echarts.extendChartView({
             fadeOutItem(edge, lineOpacityPath);
         });
     }
-});
+}
 
 // Add animation to the view
-function createGridClipShape(rect, seriesModel, cb) {
+function createGridClipShape(rect: RectLike, seriesModel: SankeySeriesModel, cb: () => void) {
     var rectEl = new graphic.Rect({
         shape: {
             x: rect.x - 10,
@@ -466,3 +526,7 @@ function createGridClipShape(rect, seriesModel, cb) {
 
     return rectEl;
 }
+
+ChartView.registerClass(SankeyView);
+
+export default SankeyView;
\ No newline at end of file
diff --git a/src/chart/sankey/sankeyAction.ts b/src/chart/sankey/sankeyAction.ts
index c512d7a..216795a 100644
--- a/src/chart/sankey/sankeyAction.ts
+++ b/src/chart/sankey/sankeyAction.ts
@@ -17,18 +17,28 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as echarts from '../../echarts';
 import '../helper/focusNodeAdjacencyAction';
+import { Payload } from '../../util/types';
+import GlobalModel from '../../model/Global';
+import SankeySeriesModel from './SankeySeries';
+
+interface SankeyDragNodePayload extends Payload {
+    localX: number
+    localY: number
+}
 
 echarts.registerAction({
     type: 'dragNode',
     event: 'dragnode',
     // here can only use 'update' now, other value is not support in echarts.
     update: 'update'
-}, function (payload, ecModel) {
-    ecModel.eachComponent({mainType: 'series', subType: 'sankey', query: payload}, function (seriesModel) {
+}, function (payload: SankeyDragNodePayload, ecModel: GlobalModel) {
+    ecModel.eachComponent({
+        mainType: 'series',
+        subType: 'sankey',
+        query: payload
+    }, function (seriesModel: SankeySeriesModel) {
         seriesModel.setNodePosition(payload.dataIndex, [payload.localX, payload.localY]);
     });
 });
diff --git a/src/chart/sankey/sankeyLayout.ts b/src/chart/sankey/sankeyLayout.ts
index 2fe08aa..9d6888d 100644
--- a/src/chart/sankey/sankeyLayout.ts
+++ b/src/chart/sankey/sankeyLayout.ts
@@ -17,15 +17,18 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as layout from '../../util/layout';
 import * as zrUtil from 'zrender/src/core/util';
 import {groupData} from '../../util/model';
+import ExtensionAPI from '../../ExtensionAPI';
+import SankeySeriesModel, { SankeySeriesOption, SankeyNodeItemOption } from './SankeySeries';
+import { GraphNode, GraphEdge } from '../../data/Graph';
+import { LayoutOrient } from '../../util/types';
+import GlobalModel from '../../model/Global';
 
-export default function (ecModel, api, payload) {
+export default function (ecModel: GlobalModel, api: ExtensionAPI) {
 
-    ecModel.eachSeriesByType('sankey', function (seriesModel) {
+    ecModel.eachSeriesByType('sankey', function (seriesModel: SankeySeriesModel) {
 
         var nodeWidth = seriesModel.get('nodeWidth');
         var nodeGap = seriesModel.get('nodeGap');
@@ -60,12 +63,8 @@ export default function (ecModel, api, payload) {
 
 /**
  * Get the layout position of the whole view
- *
- * @param {module:echarts/model/Series} seriesModel  the model object of sankey series
- * @param {module:echarts/ExtensionAPI} api  provide the API list that the developer can call
- * @return {module:zrender/core/BoundingRect}  size of rect to draw the sankey view
  */
-function getViewRect(seriesModel, api) {
+function getViewRect(seriesModel: SankeySeriesModel, api: ExtensionAPI) {
     return layout.getLayoutRect(
         seriesModel.getBoxLayoutParams(), {
             width: api.getWidth(),
@@ -74,7 +73,17 @@ function getViewRect(seriesModel, api) {
     );
 }
 
-function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations, orient, nodeAlign) {
+function layoutSankey(
+    nodes: GraphNode[],
+    edges: GraphEdge[],
+    nodeWidth: number,
+    nodeGap: number,
+    width: number,
+    height: number,
+    iterations: number,
+    orient: LayoutOrient,
+    nodeAlign: SankeySeriesOption['nodeAlign']
+) {
     computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign);
     computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient);
     computeEdgeDepths(nodes, orient);
@@ -82,14 +91,12 @@ function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iteration
 
 /**
  * Compute the value of each node by summing the associated edge's value
- *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
  */
-function computeNodeValues(nodes) {
+function computeNodeValues(nodes: GraphNode[]) {
     zrUtil.each(nodes, function (node) {
         var value1 = sum(node.outEdges, getEdgeValue);
         var value2 = sum(node.inEdges, getEdgeValue);
-        var nodeRawValue = node.getValue() || 0;
+        var nodeRawValue = node.getValue() as number || 0;
         var value = Math.max(value1, value2, nodeRawValue);
         node.setLayout({value: value}, true);
     });
@@ -100,20 +107,24 @@ function computeNodeValues(nodes) {
  *
  * Here we use Kahn algorithm to detect cycle when we traverse
  * the node to computer the initial x position.
- *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
- * @param  {number} nodeWidth  the dx of the node
- * @param  {number} width  the whole width of the area to draw the view
  */
-function computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign) {
+function computeNodeBreadths(
+    nodes: GraphNode[],
+    edges: GraphEdge[],
+    nodeWidth: number,
+    width: number,
+    height: number,
+    orient: LayoutOrient,
+    nodeAlign: SankeySeriesOption['nodeAlign']
+) {
     // Used to mark whether the edge is deleted. if it is deleted,
     // the value is 0, otherwise it is 1.
     var remainEdges = [];
     // Storage each node's indegree.
     var indegreeArr = [];
     //Used to storage the node with indegree is equal to 0.
-    var zeroIndegrees = [];
-    var nextTargetNode = [];
+    var zeroIndegrees: GraphNode[] = [];
+    var nextTargetNode: GraphNode[] = [];
     var x = 0;
     var kx = 0;
 
@@ -133,7 +144,7 @@ function computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nod
     while (zeroIndegrees.length) {
         for (var idx = 0; idx < zeroIndegrees.length; idx++) {
             var node = zeroIndegrees[idx];
-            var item = node.hostGraph.data.getRawDataItem(node.dataIndex);
+            var item = node.hostGraph.data.getRawDataItem(node.dataIndex) as SankeyNodeItemOption;
             var isItemDepth = item.depth != null && item.depth >= 0;
             if (isItemDepth && item.depth > maxNodeDepth) {
                 maxNodeDepth = item.depth;
@@ -176,14 +187,19 @@ function computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nod
     scaleNodeBreadths(nodes, kx, orient);
 }
 
-function isNodeDepth(node) {
-    var item = node.hostGraph.data.getRawDataItem(node.dataIndex);
+function isNodeDepth(node: GraphNode) {
+    var item = node.hostGraph.data.getRawDataItem(node.dataIndex) as SankeyNodeItemOption;
     return item.depth != null && item.depth >= 0;
 }
 
-function adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth) {
+function adjustNodeWithNodeAlign(
+    nodes: GraphNode[],
+    nodeAlign: SankeySeriesOption['nodeAlign'],
+    orient: LayoutOrient,
+    maxDepth: number
+) {
     if (nodeAlign === 'right') {
-        var nextSourceNode = [];
+        var nextSourceNode: GraphNode[] = [];
         var remainNodes = nodes;
         var nodeHeight = 0;
         while (remainNodes.length) {
@@ -217,10 +233,10 @@ function adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth) {
  * All the node without outEgdes are assigned maximum x-position and
  *     be aligned in the last column.
  *
- * @param {module:echarts/data/Graph~Node} nodes.  node of sankey view.
- * @param {number} maxDepth.  use to assign to node without outEdges as x-position.
+ * @param nodes.  node of sankey view.
+ * @param maxDepth.  use to assign to node without outEdges as x-position.
  */
-function moveSinksRight(nodes, maxDepth) {
+function moveSinksRight(nodes: GraphNode[], maxDepth: number) {
     zrUtil.each(nodes, function (node) {
         if (!isNodeDepth(node) && !node.outEdges.length) {
             node.setLayout({depth: maxDepth}, true);
@@ -231,10 +247,10 @@ function moveSinksRight(nodes, maxDepth) {
 /**
  * Scale node x-position to the width
  *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
- * @param {number} kx   multiple used to scale nodes
+ * @param nodes  node of sankey view
+ * @param kx   multiple used to scale nodes
  */
-function scaleNodeBreadths(nodes, kx, orient) {
+function scaleNodeBreadths(nodes: GraphNode[], kx: number, orient: LayoutOrient) {
     zrUtil.each(nodes, function (node) {
         var nodeDepth = node.getLayout().depth * kx;
         orient === 'vertical'
@@ -246,14 +262,22 @@ function scaleNodeBreadths(nodes, kx, orient) {
 /**
  * Using Gauss-Seidel iterations method to compute the node depth(y-position)
  *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
- * @param {module:echarts/data/Graph~Edge} edges  edge of sankey view
- * @param {number} height  the whole height of the area to draw the view
- * @param {number} nodeGap  the vertical distance between two nodes
+ * @param nodes  node of sankey view
+ * @param edges  edge of sankey view
+ * @param height  the whole height of the area to draw the view
+ * @param nodeGap  the vertical distance between two nodes
  *     in the same column.
- * @param {number} iterations  the number of iterations for the algorithm
+ * @param iterations  the number of iterations for the algorithm
  */
-function computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient) {
+function computeNodeDepths(
+    nodes: GraphNode[],
+    edges: GraphEdge[],
+    height: number,
+    width: number,
+    nodeGap: number,
+    iterations: number,
+    orient: LayoutOrient
+) {
     var nodesByBreadth = prepareNodesByBreadth(nodes, orient);
 
     initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient);
@@ -270,12 +294,12 @@ function computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, ori
     }
 }
 
-function prepareNodesByBreadth(nodes, orient) {
-    var nodesByBreadth = [];
+function prepareNodesByBreadth(nodes: GraphNode[], orient: LayoutOrient) {
+    var nodesByBreadth: GraphNode[][] = [];
     var keyAttr = orient === 'vertical' ? 'y' : 'x';
 
     var groupResult = groupData(nodes, function (node) {
-        return node.getLayout()[keyAttr];
+        return node.getLayout()[keyAttr] as number;
     });
     groupResult.keys.sort(function (a, b) {
         return a - b;
@@ -289,15 +313,15 @@ function prepareNodesByBreadth(nodes, orient) {
 
 /**
  * Compute the original y-position for each node
- *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
- * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
- *     group by the array of all sankey nodes based on the nodes x-position.
- * @param {module:echarts/data/Graph~Edge} edges  edge of sankey view
- * @param {number} height  the whole height of the area to draw the view
- * @param {number} nodeGap  the vertical distance between two nodes
  */
-function initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient) {
+function initializeNodeDepth(
+    nodesByBreadth: GraphNode[][],
+    edges: GraphEdge[],
+    height: number,
+    width: number,
+    nodeGap: number,
+    orient: LayoutOrient
+) {
     var minKy = Infinity;
     zrUtil.each(nodesByBreadth, function (nodes) {
         var n = nodes.length;
@@ -336,13 +360,14 @@ function initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orie
 
 /**
  * Resolve the collision of initialized depth (y-position)
- *
- * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
- *     group by the array of all sankey nodes based on the nodes x-position.
- * @param {number} nodeGap  the vertical distance between two nodes
- * @param {number} height  the whole height of the area to draw the view
  */
-function resolveCollisions(nodesByBreadth, nodeGap, height, width, orient) {
+function resolveCollisions(
+    nodesByBreadth: GraphNode[][],
+    nodeGap: number,
+    height: number,
+    width: number,
+    orient: LayoutOrient
+) {
     var keyAttr = orient === 'vertical' ? 'x' : 'y';
     zrUtil.each(nodesByBreadth, function (nodes) {
         nodes.sort(function (a, b) {
@@ -392,17 +417,19 @@ function resolveCollisions(nodesByBreadth, nodeGap, height, width, orient) {
 
 /**
  * Change the y-position of the nodes, except most the right side nodes
- *
- * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
- *     group by the array of all sankey nodes based on the node x-position.
- * @param {number} alpha  parameter used to adjust the nodes y-position
+ * @param nodesByBreadth
+ * @param alpha  parameter used to adjust the nodes y-position
  */
-function relaxRightToLeft(nodesByBreadth, alpha, orient) {
+function relaxRightToLeft(
+    nodesByBreadth: GraphNode[][],
+    alpha: number,
+    orient: LayoutOrient
+) {
     zrUtil.each(nodesByBreadth.slice().reverse(), function (nodes) {
         zrUtil.each(nodes, function (node) {
             if (node.outEdges.length) {
                 var y = sum(node.outEdges, weightedTarget, orient)
-                        / sum(node.outEdges, getEdgeValue, orient);
+                        / sum(node.outEdges, getEdgeValue);
                 if (orient === 'vertical') {
                     var nodeX = node.getLayout().x + (y - center(node, orient)) * alpha;
                     node.setLayout({x: nodeX}, true);
@@ -416,30 +443,30 @@ function relaxRightToLeft(nodesByBreadth, alpha, orient) {
     });
 }
 
-function weightedTarget(edge, orient) {
-    return center(edge.node2, orient) * edge.getValue();
+function weightedTarget(edge: GraphEdge, orient: LayoutOrient) {
+    return center(edge.node2, orient) * (edge.getValue() as number);
 }
 
-function weightedSource(edge, orient) {
-    return center(edge.node1, orient) * edge.getValue();
+function weightedSource(edge: GraphEdge, orient: LayoutOrient) {
+    return center(edge.node1, orient) * (edge.getValue() as number);
 }
 
-function center(node, orient) {
+function center(node: GraphNode, orient: LayoutOrient) {
     return orient === 'vertical'
             ? node.getLayout().x + node.getLayout().dx / 2
             : node.getLayout().y + node.getLayout().dy / 2;
 }
 
-function getEdgeValue(edge) {
-    return edge.getValue();
+function getEdgeValue(edge: GraphEdge) {
+    return edge.getValue() as number;
 }
 
-function sum(array, cb, orient) {
+function sum<T>(array: T[], cb: (item: T, orient?: LayoutOrient) => number, orient?: LayoutOrient) {
     var sum = 0;
     var len = array.length;
     var i = -1;
     while (++i < len) {
-        var value = +cb.call(array, array[i], orient);
+        var value = +cb(array[i], orient);
         if (!isNaN(value)) {
             sum += value;
         }
@@ -449,17 +476,13 @@ function sum(array, cb, orient) {
 
 /**
  * Change the y-position of the nodes, except most the left side nodes
- *
- * @param {Array.<Array.<module:echarts/data/Graph~Node>>} nodesByBreadth
- *     group by the array of all sankey nodes based on the node x-position.
- * @param {number} alpha  parameter used to adjust the nodes y-position
  */
-function relaxLeftToRight(nodesByBreadth, alpha, orient) {
+function relaxLeftToRight(nodesByBreadth: GraphNode[][], alpha: number, orient: LayoutOrient) {
     zrUtil.each(nodesByBreadth, function (nodes) {
         zrUtil.each(nodes, function (node) {
             if (node.inEdges.length) {
                 var y = sum(node.inEdges, weightedSource, orient)
-                        / sum(node.inEdges, getEdgeValue, orient);
+                        / sum(node.inEdges, getEdgeValue);
                 if (orient === 'vertical') {
                     var nodeX = node.getLayout().x + (y - center(node, orient)) * alpha;
                     node.setLayout({x: nodeX}, true);
@@ -475,10 +498,8 @@ function relaxLeftToRight(nodesByBreadth, alpha, orient) {
 
 /**
  * Compute the depth(y-position) of each edge
- *
- * @param {module:echarts/data/Graph~Node} nodes  node of sankey view
  */
-function computeEdgeDepths(nodes, orient) {
+function computeEdgeDepths(nodes: GraphNode[], orient: LayoutOrient) {
     var keyAttr = orient === 'vertical' ? 'x' : 'y';
     zrUtil.each(nodes, function (node) {
         node.outEdges.sort(function (a, b) {
diff --git a/src/chart/sankey/sankeyVisual.ts b/src/chart/sankey/sankeyVisual.ts
index 84ea667..15ffa7c 100644
--- a/src/chart/sankey/sankeyVisual.ts
+++ b/src/chart/sankey/sankeyVisual.ts
@@ -17,13 +17,13 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import VisualMapping from '../../visual/VisualMapping';
 import * as zrUtil from 'zrender/src/core/util';
+import GlobalModel from '../../model/Global';
+import SankeySeriesModel, { SankeyNodeItemOption } from './SankeySeries';
 
-export default function (ecModel, payload) {
-    ecModel.eachSeriesByType('sankey', function (seriesModel) {
+export default function (ecModel: GlobalModel) {
+    ecModel.eachSeriesByType('sankey', function (seriesModel: SankeySeriesModel) {
         var graph = seriesModel.getGraph();
         var nodes = graph.nodes;
         if (nodes.length) {
@@ -48,7 +48,7 @@ export default function (ecModel, payload) {
                 });
 
                 var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value);
-                var customColor = node.getModel().get('itemStyle.color');
+                var customColor = node.getModel<SankeyNodeItemOption>().get(['itemStyle', 'color']);
                 customColor != null
                     ? node.setVisual('color', customColor)
                     : node.setVisual('color', mapValueToColor);
diff --git a/src/chart/scatter/ScatterSeries.ts b/src/chart/scatter/ScatterSeries.ts
index b143d3d..94b2179 100644
--- a/src/chart/scatter/ScatterSeries.ts
+++ b/src/chart/scatter/ScatterSeries.ts
@@ -57,6 +57,7 @@ export interface ScatterSeriesOption extends SeriesOption,
     SeriesOnGeoOptionMixin, SeriesOnSingleOptionMixin,
     SeriesLargeOptionMixin, SeriesStackOptionMixin,
     SymbolOptionMixin {
+    type?: 'scatter'
 
     coordinateSystem?: string
 
diff --git a/src/chart/sunburst/SunburstSeries.ts b/src/chart/sunburst/SunburstSeries.ts
index 72e6345..c03233a 100644
--- a/src/chart/sunburst/SunburstSeries.ts
+++ b/src/chart/sunburst/SunburstSeries.ts
@@ -93,6 +93,7 @@ export interface SunburstSeriesLevelOption {
     }
 }
 export interface SunburstSeriesOption extends SeriesOption, CircleLayoutOptionMixin {
+    type?: 'sunburst'
 
     clockwise?: boolean
     startAngle?: number
diff --git a/src/chart/sunburst/SunburstView.ts b/src/chart/sunburst/SunburstView.ts
index 48249f0..25b47fb 100644
--- a/src/chart/sunburst/SunburstView.ts
+++ b/src/chart/sunburst/SunburstView.ts
@@ -184,6 +184,7 @@ class SunburstView extends ChartView {
                     group.add(self.virtualPiece);
                 }
 
+                // TODO event scope
                 viewRoot.piece.off('click');
                 self.virtualPiece.on('click', function (e) {
                     self._rootToNode(viewRoot.parentNode);
diff --git a/src/chart/themeRiver/ThemeRiverSeries.ts b/src/chart/themeRiver/ThemeRiverSeries.ts
index 1945833..f6309a3 100644
--- a/src/chart/themeRiver/ThemeRiverSeries.ts
+++ b/src/chart/themeRiver/ThemeRiverSeries.ts
@@ -52,6 +52,8 @@ interface ThemeRiverSeriesLabelOption extends LabelOption {
 }
 
 export interface ThemeRiverSeriesOption extends SeriesOption, SeriesOnSingleOptionMixin, BoxLayoutOptionMixin {
+    type?: 'themeRiver'
+
     color?: ZRColor[]
 
     coordinateSystem: 'singleAxis'
diff --git a/src/chart/tree/TreeSeries.ts b/src/chart/tree/TreeSeries.ts
index 2fc9383..aa353dc 100644
--- a/src/chart/tree/TreeSeries.ts
+++ b/src/chart/tree/TreeSeries.ts
@@ -63,6 +63,7 @@ export interface TreeSeriesNodeOption extends SymbolOptionMixin {
 
 export interface TreeSeriesOption extends
     SeriesOption, SymbolOptionMixin, BoxLayoutOptionMixin, RoamOptionMixin {
+    type?: 'tree'
 
     hoverAnimation?: boolean
 
diff --git a/src/data/Graph.ts b/src/data/Graph.ts
index 96c1aad..b978493 100644
--- a/src/data/Graph.ts
+++ b/src/data/Graph.ts
@@ -422,7 +422,7 @@ function createGraphDataProxyMixin<Host extends GraphEdge | GraphNode>(
         /**
          * @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'.
          */
-        getValue: function (this: Host, dimension: DimensionLoose): ParsedValue {
+        getValue: function (this: Host, dimension?: DimensionLoose): ParsedValue {
             var data = this[hostName][dataName];
             return data.get(data.getDimension(dimension || 'value'), this.dataIndex);
         },
diff --git a/src/echarts.ts b/src/echarts.ts
index b953714..d31a78a 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -776,7 +776,7 @@ class ECharts {
                 else if (ecData && ecData.dataIndex != null) {
                     var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex);
                     params = (
-                        dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType, targetEl) || {}
+                        dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType, el) || {}
                     ) as ECEvent;
                 }
                 // If element has custom eventData of components
diff --git a/src/util/model.ts b/src/util/model.ts
index 4c53a1d..7e27006 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -647,15 +647,15 @@ export function getTooltipRenderMode(renderModeOption: TooltipRenderMode | 'auto
 /**
  * Group a list by key.
  */
-export function groupData<T>(
+export function groupData<T, R extends string | number>(
     array: T[],
-    getKey: (item: T) => string // return key
+    getKey: (item: T) => R // return key
 ): {
-    keys: string[],
+    keys: R[],
     buckets: HashMap<T[]> // hasmap key: the key returned by `getKey`.
 } {
     var buckets = createHashMap<T[]>();
-    var keys = [] as string[];
+    var keys: R[] = [];
 
     each(array, function (item) {
         var key = getKey(item);
@@ -664,7 +664,10 @@ export function groupData<T>(
         ).push(item);
     });
 
-    return {keys: keys, buckets: buckets};
+    return {
+        keys: keys,
+        buckets: buckets
+    };
 }
 
 export function mergeOption<T, K>(option1: T, option2: K): T & K {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org