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

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

commit 4ee8ee674c5563eafda559d5cdbb8cfbfb75e8bf
Author: 100pah <sushuang0...@gmail.com>
AuthorDate: Mon Feb 17 05:27:13 2020 +0800

    migrate PieSeries and PieView as an example.
---
 src/chart/helper/createListSimply.ts    |  15 +-
 src/chart/map/MapSeries.ts              |   4 +-
 src/chart/pie/PieSeries.ts              |  75 +++--
 src/chart/pie/PieView.ts                | 490 +++++++++++++++++---------------
 src/component/helper/selectableMixin.ts |  77 +++--
 src/coord/geo/GeoModel.ts               |   4 +-
 src/data/List.ts                        |  12 +-
 src/data/helper/createDimensions.ts     |  41 ++-
 src/data/helper/dimensionHelper.ts      |  12 +-
 src/echarts.ts                          |  10 +-
 src/model/Component.ts                  |  12 +-
 src/model/Global.ts                     |   2 +-
 src/model/Model.ts                      |  10 +-
 src/model/Series.ts                     |  14 +-
 src/model/mixin/colorPalette.ts         |   4 +-
 src/model/mixin/dataFormat.ts           |  36 +--
 src/model/mixin/itemStyle.ts            |  20 +-
 src/model/mixin/lineStyle.ts            |  20 +-
 src/model/mixin/makeStyleMapper.ts      |   2 +-
 src/util/clazz.ts                       |  27 +-
 src/util/graphic.ts                     |   8 +-
 src/util/model.ts                       |   4 +-
 src/util/types.ts                       |  49 +++-
 src/view/Chart.ts                       |   7 +-
 src/view/Component.ts                   |   1 +
 src/visual/LegendVisualProvider.ts      |   1 -
 26 files changed, 538 insertions(+), 419 deletions(-)

diff --git a/src/chart/helper/createListSimply.ts 
b/src/chart/helper/createListSimply.ts
index c3f7be2..92c6612 100644
--- a/src/chart/helper/createListSimply.ts
+++ b/src/chart/helper/createListSimply.ts
@@ -19,9 +19,10 @@
 
 // @ts-nocheck
 
-import createDimensions from '../../data/helper/createDimensions';
+import createDimensions, {CreateDimensionsParams} from 
'../../data/helper/createDimensions';
 import List from '../../data/List';
 import {extend, isArray} from 'zrender/src/core/util';
+import SeriesModel from '../../model/Series';
 
 /**
  * [Usage]:
@@ -32,14 +33,12 @@ import {extend, isArray} from 'zrender/src/core/util';
  *     coordDimensions: ['value'],
  *     dimensionsCount: 5
  * });
- *
- * @param {module:echarts/model/Series} seriesModel
- * @param {Object|Array.<string|Object>} opt opt or coordDimensions
- *        The options in opt, see `echarts/data/helper/createDimensions`
- * @param {Array.<string>} [nameList]
- * @return {module:echarts/data/List}
  */
-export default function (seriesModel, opt, nameList) {
+export default function (
+    seriesModel: SeriesModel,
+    opt: CreateDimensionsParams | CreateDimensionsParams['coordDimensions'],
+    nameList?: string[]
+): List {
     opt = isArray(opt) && {coordDimensions: opt} || extend({}, opt);
 
     var source = seriesModel.getSource();
diff --git a/src/chart/map/MapSeries.ts b/src/chart/map/MapSeries.ts
index 6bc864b..a1f4b8c 100644
--- a/src/chart/map/MapSeries.ts
+++ b/src/chart/map/MapSeries.ts
@@ -23,7 +23,7 @@ import * as zrUtil from 'zrender/src/core/util';
 import createListSimply from '../helper/createListSimply';
 import SeriesModel from '../../model/Series';
 import {encodeHTML, addCommas} from '../../util/format';
-import dataSelectableMixin from '../../component/helper/selectableMixin';
+import {DataSelectableMixin} from '../../component/helper/selectableMixin';
 import {retrieveRawAttr} from '../../data/helper/dataProvider';
 import geoSourceManager from '../../coord/geo/geoSourceManager';
 import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
@@ -263,6 +263,6 @@ var MapSeries = SeriesModel.extend({
 
 });
 
-zrUtil.mixin(MapSeries, dataSelectableMixin);
+zrUtil.mixin(MapSeries, DataSelectableMixin.prototype);
 
 export default MapSeries;
\ No newline at end of file
diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts
index 1a1697b..8d44523 100644
--- a/src/chart/pie/PieSeries.ts
+++ b/src/chart/pie/PieSeries.ts
@@ -17,26 +17,32 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import * as echarts from '../../echarts';
 import createListSimply from '../helper/createListSimply';
 import * as zrUtil from 'zrender/src/core/util';
 import * as modelUtil from '../../util/model';
 import {getPercentWithPrecision} from '../../util/number';
-import dataSelectableMixin from '../../component/helper/selectableMixin';
+import {DataSelectableMixin, SelectableTarget} from 
'../../component/helper/selectableMixin';
 import {retrieveRawAttr} from '../../data/helper/dataProvider';
 import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
 import LegendVisualProvider from '../../visual/LegendVisualProvider';
+import SeriesModel from '../../model/Series';
+import { SeriesOption, DataParamsUserOutput, ParsedDataValue } from 
'../../util/types';
+import List from '../../data/List';
 
+export interface PieOption extends SeriesOption {
+    // FIXME:TS need more. [k: string]: any should be removed finally.
+    [k: string]: any
+}
 
-var PieSeries = echarts.extendSeriesModel({
+class PieSeries extends SeriesModel {
 
-    type: 'series.pie',
+    static type = 'series.pie';
 
-    // Overwrite
-    init: function (option) {
-        PieSeries.superApply(this, 'init', arguments);
+    /**
+     * @overwrite
+     */
+    init(option: PieOption): void {
+        super.init.apply(this, arguments as any);
 
         // Enable legend selection for each data item
         // Use a function instead of direct access because data reference may 
changed
@@ -47,23 +53,28 @@ var PieSeries = echarts.extendSeriesModel({
         this.updateSelectedMap(this._createSelectableList());
 
         this._defaultLabelLine(option);
-    },
+    }
 
-    // Overwrite
-    mergeOption: function (newOption) {
-        PieSeries.superCall(this, 'mergeOption', newOption);
+    /**
+     * @overwrite
+     */
+    mergeOption(): void {
+        super.mergeOption.apply(this, arguments as any);
 
         this.updateSelectedMap(this._createSelectableList());
-    },
+    }
 
-    getInitialData: function (option, ecModel) {
+    /**
+     * @overwrite
+     */
+    getInitialData(): List {
         return createListSimply(this, {
             coordDimensions: ['value'],
             encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
         });
-    },
+    }
 
-    _createSelectableList: function () {
+    private _createSelectableList(): SelectableTarget[] {
         var data = this.getRawData();
         var valueDim = data.mapDimension('value');
         var targetList = [];
@@ -75,15 +86,17 @@ var PieSeries = echarts.extendSeriesModel({
             });
         }
         return targetList;
-    },
+    }
 
-    // Overwrite
-    getDataParams: function (dataIndex) {
+    /**
+     * @overwrite
+     */
+    getDataParams(dataIndex: number): DataParamsUserOutput {
         var data = this.getData();
-        var params = PieSeries.superCall(this, 'getDataParams', dataIndex);
+        var params = super.getDataParams(dataIndex);
         // FIXME toFixed?
 
-        var valueList = [];
+        var valueList = [] as ParsedDataValue[];
         data.each(data.mapDimension('value'), function (value) {
             valueList.push(value);
         });
@@ -96,9 +109,9 @@ var PieSeries = echarts.extendSeriesModel({
 
         params.$vars.push('percent');
         return params;
-    },
+    }
 
-    _defaultLabelLine: function (option) {
+    private _defaultLabelLine(option: PieOption): void {
         // Extend labelLine emphasis
         modelUtil.defaultEmphasis(option, 'labelLine', ['show']);
 
@@ -109,9 +122,9 @@ var PieSeries = echarts.extendSeriesModel({
             && option.label.show;
         labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
             && option.emphasis.label.show;
-    },
+    }
 
-    defaultOption: {
+    static defaultOption: PieOption = {
         zlevel: 0,
         z: 2,
         legendHoverLink: true,
@@ -201,8 +214,12 @@ var PieSeries = echarts.extendSeriesModel({
 
         animationEasing: 'cubicOut'
     }
-});
 
-zrUtil.mixin(PieSeries, dataSelectableMixin);
+}
+
+interface PieSeries extends DataSelectableMixin {}
+zrUtil.tsMixin(PieSeries, DataSelectableMixin);
+
+SeriesModel.registerClass(PieSeries);
 
-export default PieSeries;
\ No newline at end of file
+export default PieSeries;
diff --git a/src/chart/pie/PieView.ts b/src/chart/pie/PieView.ts
index 68d1f92..1d9c350 100644
--- a/src/chart/pie/PieView.ts
+++ b/src/chart/pie/PieView.ts
@@ -17,18 +17,26 @@
 * under the License.
 */
 
-// @ts-nocheck
 
 import * as zrUtil from 'zrender/src/core/util';
 import * as graphic from '../../util/graphic';
 import ChartView from '../../view/Chart';
-
-/**
- * @param {module:echarts/model/Series} seriesModel
- * @param {boolean} hasAnimation
- * @inner
- */
-function updateDataSelected(uid, seriesModel, hasAnimation, api) {
+import SeriesModel from '../../model/Series';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { Payload, DisplayState } from '../../util/types';
+import List from '../../data/List';
+import PieSeries from './PieSeries';
+import { Dictionary } from 'zrender/src/core/types';
+import Element from 'zrender/src/Element';
+
+function updateDataSelected(
+    this: PiePiece,
+    uid: string,
+    seriesModel: PieSeries,
+    hasAnimation: boolean,
+    api: ExtensionAPI
+): void {
     var data = seriesModel.getData();
     var dataIndex = this.dataIndex;
     var name = data.getName(dataIndex);
@@ -52,15 +60,13 @@ function updateDataSelected(uid, seriesModel, hasAnimation, 
api) {
     });
 }
 
-/**
- * @param {module:zrender/graphic/Sector} el
- * @param {Object} layout
- * @param {boolean} isSelected
- * @param {number} selectedOffset
- * @param {boolean} hasAnimation
- * @inner
- */
-function toggleItemSelected(el, layout, isSelected, selectedOffset, 
hasAnimation) {
+function toggleItemSelected(
+    el: Element,
+    layout: Dictionary<any>, // FIXME:TS make a type.
+    isSelected: boolean,
+    selectedOffset: number,
+    hasAnimation: boolean
+): void {
     var midAngle = (layout.startAngle + layout.endAngle) / 2;
 
     var dx = Math.cos(midAngle);
@@ -71,6 +77,7 @@ function toggleItemSelected(el, layout, isSelected, 
selectedOffset, hasAnimation
 
     hasAnimation
         // animateTo will stop revious animation like update transition
+        // @ts-ignore FIXME:TS zr?
         ? el.animate()
             .when(200, {
                 position: position
@@ -79,251 +86,273 @@ function toggleItemSelected(el, layout, isSelected, 
selectedOffset, hasAnimation
         : el.attr('position', position);
 }
 
+type PieceElementExtension = {
+    hoverIgnore?: boolean,
+    normalIgnore?: boolean,
+    ignore?: boolean
+};
+
 /**
  * Piece of pie including Sector, Label, LabelLine
- * @constructor
- * @extends {module:zrender/graphic/Group}
  */
-function PiePiece(data, idx) {
-
-    graphic.Group.call(this);
-
-    var sector = new graphic.Sector({
-        z2: 2
-    });
-    var polyline = new graphic.Polyline();
-    var text = new graphic.Text();
-    this.add(sector);
-    this.add(polyline);
-    this.add(text);
-
-    this.updateData(data, idx, true);
-}
+class PiePiece extends graphic.Group {
 
-var piePieceProto = PiePiece.prototype;
+    // FIXME:TS add a type in `util/graphic.ts` for `highDownOnUpdate`.
+    highDownOnUpdate: any;
+    dataIndex: number;
 
-piePieceProto.updateData = function (data, idx, firstCreate) {
+    constructor(data: List, idx: number) {
+        super();
 
-    var sector = this.childAt(0);
-    var labelLine = this.childAt(1);
-    var labelText = this.childAt(2);
+        // @ts-ignore FIXME:TS modify zr?
+        var sector = new graphic.Sector({
+            z2: 2
+        });
+        var polyline = new graphic.Polyline();
+        var text = new graphic.Text();
+        this.add(sector);
+        this.add(polyline);
+        this.add(text);
 
-    var seriesModel = data.hostModel;
-    var itemModel = data.getItemModel(idx);
-    var layout = data.getItemLayout(idx);
-    var sectorShape = zrUtil.extend({}, layout);
-    sectorShape.label = null;
+        this.updateData(data, idx, true);
+    }
 
-    var animationTypeUpdate = seriesModel.getShallow('animationTypeUpdate');
+    updateData(data: List, idx: number, firstCreate?: boolean): void {
+        var sector = this.childAt(0) as graphic.Sector;
+        var labelLine = this.childAt(1) as PieceElementExtension;
+        var labelText = this.childAt(2) as PieceElementExtension;
 
-    if (firstCreate) {
-        sector.setShape(sectorShape);
+        var seriesModel = data.hostModel as PieSeries;
+        var itemModel = data.getItemModel(idx);
+        var layout = data.getItemLayout(idx);
+        var sectorShape = zrUtil.extend({}, layout);
+        // @ts-ignore FIXME:TS label?
+        sectorShape.label = null;
 
-        var animationType = seriesModel.getShallow('animationType');
-        if (animationType === 'scale') {
-            sector.shape.r = layout.r0;
-            graphic.initProps(sector, {
-                shape: {
-                    r: layout.r
-                }
-            }, seriesModel, idx);
-        }
-        // Expansion
-        else {
-            sector.shape.endAngle = layout.startAngle;
-            graphic.updateProps(sector, {
-                shape: {
-                    endAngle: layout.endAngle
-                }
-            }, seriesModel, idx);
-        }
+        var animationTypeUpdate = 
seriesModel.getShallow('animationTypeUpdate');
 
-    }
-    else {
-        if (animationTypeUpdate === 'expansion') {
-            // Sectors are set to be target shape and an overlaying clipPath 
is used for animation
+        if (firstCreate) {
             sector.setShape(sectorShape);
-        }
-        else {
-            // Transition animation from the old shape
-            graphic.updateProps(sector, {
-                shape: sectorShape
-            }, seriesModel, idx);
-        }
-    }
-
-    // Update common style
-    var visualColor = data.getItemVisual(idx, 'color');
 
-    sector.useStyle(
-        zrUtil.defaults(
-            {
-                lineJoin: 'bevel',
-                fill: visualColor
-            },
-            itemModel.getModel('itemStyle').getItemStyle()
-        )
-    );
-    sector.hoverStyle = 
itemModel.getModel('emphasis.itemStyle').getItemStyle();
-
-    var cursorStyle = itemModel.getShallow('cursor');
-    cursorStyle && sector.attr('cursor', cursorStyle);
-
-    // Toggle selected
-    toggleItemSelected(
-        this,
-        data.getItemLayout(idx),
-        seriesModel.isSelected(data.getName(idx)),
-        seriesModel.get('selectedOffset'),
-        seriesModel.get('animation')
-    );
-
-    // Label and text animation should be applied only for transition type 
animation when update
-    var withAnimation = !firstCreate && animationTypeUpdate === 'transition';
-    this._updateLabel(data, idx, withAnimation);
-
-    this.highDownOnUpdate = (itemModel.get('hoverAnimation') && 
seriesModel.isAnimationEnabled())
-        ? function (fromState, toState) {
-            if (toState === 'emphasis') {
-                labelLine.ignore = labelLine.hoverIgnore;
-                labelText.ignore = labelText.hoverIgnore;
-
-                // Sector may has animation of updating data. Force to move to 
the last frame
-                // Or it may stopped on the wrong shape
-                sector.stopAnimation(true);
-                sector.animateTo({
+            var animationType = seriesModel.getShallow('animationType');
+            if (animationType === 'scale') {
+                sector.shape.r = layout.r0;
+                graphic.initProps(sector, {
                     shape: {
-                        r: layout.r + seriesModel.get('hoverOffset')
+                        r: layout.r
                     }
-                }, 300, 'elasticOut');
+                }, seriesModel, idx);
             }
+            // Expansion
             else {
-                labelLine.ignore = labelLine.normalIgnore;
-                labelText.ignore = labelText.normalIgnore;
-
-                sector.stopAnimation(true);
-                sector.animateTo({
+                sector.shape.endAngle = layout.startAngle;
+                graphic.updateProps(sector, {
                     shape: {
-                        r: layout.r
+                        endAngle: layout.endAngle
                     }
-                }, 300, 'elasticOut');
+                }, seriesModel, idx);
+            }
+
+        }
+        else {
+            if (animationTypeUpdate === 'expansion') {
+                // Sectors are set to be target shape and an overlaying 
clipPath is used for animation
+                sector.setShape(sectorShape);
+            }
+            else {
+                // Transition animation from the old shape
+                graphic.updateProps(sector, {
+                    shape: sectorShape
+                }, seriesModel, idx);
             }
         }
-        : null;
 
-    graphic.setHoverStyle(this);
-};
+        // Update common style
+        var visualColor = data.getItemVisual(idx, 'color');
+
+        sector.useStyle(
+            zrUtil.defaults(
+                {
+                    lineJoin: 'bevel',
+                    fill: visualColor
+                },
+                itemModel.getModel('itemStyle').getItemStyle()
+            )
+        );
+        // @ts-ignore FIXME:TS make a type in util/graphic.ts to support 
`hoverStyle`.
+        sector.hoverStyle = 
itemModel.getModel('emphasis.itemStyle').getItemStyle();
 
-piePieceProto._updateLabel = function (data, idx, withAnimation) {
+        var cursorStyle = itemModel.getShallow('cursor');
+        // @ts-ignore FIXME:TS update zr.
+        cursorStyle && sector.attr('cursor', cursorStyle);
 
-    var labelLine = this.childAt(1);
-    var labelText = this.childAt(2);
+        // Toggle selected
+        toggleItemSelected(
+            this,
+            data.getItemLayout(idx),
+            seriesModel.isSelected(data.getName(idx)),
+            seriesModel.get('selectedOffset'),
+            seriesModel.get('animation')
+        );
 
-    var seriesModel = data.hostModel;
-    var itemModel = data.getItemModel(idx);
-    var layout = data.getItemLayout(idx);
-    var labelLayout = layout.label;
-    var visualColor = data.getItemVisual(idx, 'color');
+        // Label and text animation should be applied only for transition type 
animation when update
+        var withAnimation = !firstCreate && animationTypeUpdate === 
'transition';
+        this._updateLabel(data, idx, withAnimation);
+
+        this.highDownOnUpdate = (itemModel.get('hoverAnimation') && 
seriesModel.isAnimationEnabled())
+            ? function (fromState: DisplayState, toState: DisplayState): void {
+                if (toState === 'emphasis') {
+                    labelLine.ignore = labelLine.hoverIgnore;
+                    labelText.ignore = labelText.hoverIgnore;
+
+                    // Sector may has animation of updating data. Force to 
move to the last frame
+                    // Or it may stopped on the wrong shape
+                    sector.stopAnimation(true);
+                    sector.animateTo({
+                        shape: {
+                            r: layout.r + seriesModel.get('hoverOffset')
+                        }
+                    // @ts-ignore FIXME:TS modify zr
+                    }, 300, 'elasticOut');
+                }
+                else {
+                    labelLine.ignore = labelLine.normalIgnore;
+                    labelText.ignore = labelText.normalIgnore;
+
+                    sector.stopAnimation(true);
+                    sector.animateTo({
+                        shape: {
+                            r: layout.r
+                        }
+                    // @ts-ignore FIXME:TS modify zr
+                    }, 300, 'elasticOut');
+                }
+            }
+            : null;
 
-    if (!labelLayout || isNaN(labelLayout.x) || isNaN(labelLayout.y)) {
-        labelText.ignore = labelText.normalIgnore = labelText.hoverIgnore =
-        labelLine.ignore = labelLine.normalIgnore = labelLine.hoverIgnore = 
true;
-        return;
+        graphic.setHoverStyle(this);
     }
 
-    var targetLineShape = {
-        points: labelLayout.linePoints || [
-            [labelLayout.x, labelLayout.y], [labelLayout.x, labelLayout.y], 
[labelLayout.x, labelLayout.y]
-        ]
-    };
-    var targetTextStyle = {
-        x: labelLayout.x,
-        y: labelLayout.y
-    };
-    if (withAnimation) {
-        graphic.updateProps(labelLine, {
-            shape: targetLineShape
-        }, seriesModel, idx);
-
-        graphic.updateProps(labelText, {
-            style: targetTextStyle
-        }, seriesModel, idx);
-    }
-    else {
-        labelLine.attr({
-            shape: targetLineShape
-        });
-        labelText.attr({
-            style: targetTextStyle
-        });
-    }
+    private _updateLabel(data: List, idx: number, withAnimation: boolean): 
void {
 
-    labelText.attr({
-        rotation: labelLayout.rotation,
-        origin: [labelLayout.x, labelLayout.y],
-        z2: 10
-    });
+        var labelLine = this.childAt(1) as (PieceElementExtension & 
graphic.Line);
+        var labelText = this.childAt(2) as (PieceElementExtension & 
graphic.Text);
 
-    var labelModel = itemModel.getModel('label');
-    var labelHoverModel = itemModel.getModel('emphasis.label');
-    var labelLineModel = itemModel.getModel('labelLine');
-    var labelLineHoverModel = itemModel.getModel('emphasis.labelLine');
-    var visualColor = data.getItemVisual(idx, 'color');
-
-    graphic.setLabelStyle(
-        labelText.style, labelText.hoverStyle = {}, labelModel, 
labelHoverModel,
-        {
-            labelFetcher: data.hostModel,
-            labelDataIndex: idx,
-            defaultText: labelLayout.text,
-            autoColor: visualColor,
-            useInsideStyle: !!labelLayout.inside
-        },
-        {
-            textAlign: labelLayout.textAlign,
-            textVerticalAlign: labelLayout.verticalAlign,
-            opacity: data.getItemVisual(idx, 'opacity')
+        var seriesModel = data.hostModel;
+        var itemModel = data.getItemModel(idx);
+        var layout = data.getItemLayout(idx);
+        var labelLayout = layout.label;
+        var visualColor = data.getItemVisual(idx, 'color');
+
+        if (!labelLayout || isNaN(labelLayout.x) || isNaN(labelLayout.y)) {
+            labelText.ignore = labelText.normalIgnore = labelText.hoverIgnore =
+            labelLine.ignore = labelLine.normalIgnore = labelLine.hoverIgnore 
= true;
+            return;
         }
-    );
 
-    labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
-    labelText.hoverIgnore = !labelHoverModel.get('show');
+        var targetLineShape = {
+            points: labelLayout.linePoints || [
+                [labelLayout.x, labelLayout.y], [labelLayout.x, 
labelLayout.y], [labelLayout.x, labelLayout.y]
+            ]
+        };
+        var targetTextStyle = {
+            x: labelLayout.x,
+            y: labelLayout.y
+        };
+        if (withAnimation) {
+            graphic.updateProps(labelLine, {
+                shape: targetLineShape
+            }, seriesModel, idx);
 
-    labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');
-    labelLine.hoverIgnore = !labelLineHoverModel.get('show');
+            graphic.updateProps(labelText, {
+                style: targetTextStyle
+            }, seriesModel, idx);
+        }
+        else {
+            labelLine.attr({
+                // @ts-ignore FIXME:TS modify zr
+                shape: targetLineShape
+            });
+            labelText.attr({
+                // @ts-ignore FIXME:TS modify zr
+                style: targetTextStyle
+            });
+        }
 
-    // Default use item visual color
-    labelLine.setStyle({
-        stroke: visualColor,
-        opacity: data.getItemVisual(idx, 'opacity')
-    });
-    labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());
+        labelText.attr({
+            rotation: labelLayout.rotation,
+            origin: [labelLayout.x, labelLayout.y],
+            // @ts-ignore FIXME:TS modify zr
+            z2: 10
+        });
 
-    labelLine.hoverStyle = 
labelLineHoverModel.getModel('lineStyle').getLineStyle();
+        var labelModel = itemModel.getModel('label');
+        var labelHoverModel = itemModel.getModel('emphasis.label');
+        var labelLineModel = itemModel.getModel('labelLine');
+        var labelLineHoverModel = itemModel.getModel('emphasis.labelLine');
+        var visualColor = data.getItemVisual(idx, 'color');
+
+        graphic.setLabelStyle(
+            labelText.style,
+            // @ts-ignore FIXME:TS make a type in util/graphic.
+            labelText.hoverStyle = {},
+            labelModel,
+            labelHoverModel,
+            {
+                labelFetcher: data.hostModel,
+                labelDataIndex: idx,
+                defaultText: labelLayout.text,
+                autoColor: visualColor,
+                useInsideStyle: !!labelLayout.inside
+            },
+            {
+                textAlign: labelLayout.textAlign,
+                textVerticalAlign: labelLayout.verticalAlign,
+                opacity: data.getItemVisual(idx, 'opacity')
+            }
+        );
 
-    var smooth = labelLineModel.get('smooth');
-    if (smooth && smooth === true) {
-        smooth = 0.4;
-    }
-    labelLine.setShape({
-        smooth: smooth
-    });
-};
+        labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
+        labelText.hoverIgnore = !labelHoverModel.get('show');
 
-zrUtil.inherits(PiePiece, graphic.Group);
+        labelLine.ignore = labelLine.normalIgnore = 
!labelLineModel.get('show');
+        labelLine.hoverIgnore = !labelLineHoverModel.get('show');
+
+        // Default use item visual color
+        labelLine.setStyle({
+            stroke: visualColor,
+            opacity: data.getItemVisual(idx, 'opacity')
+        });
+        
labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());
+
+        // @ts-ignore FIXME:TS
+        labelLine.hoverStyle = 
labelLineHoverModel.getModel('lineStyle').getLineStyle();
+
+        var smooth = labelLineModel.get('smooth');
+        if (smooth && smooth === true) {
+            smooth = 0.4;
+        }
+        labelLine.setShape({
+            smooth: smooth
+        });
+    }
+}
 
 
 // Pie view
-var PieView = ChartView.extend({
+class PieView extends ChartView {
 
-    type: 'pie',
+    static type = 'pie';
 
-    init: function () {
+    private _sectorGroup: graphic.Group;
+    private _data: List;
+
+    init(): void {
         var sectorGroup = new graphic.Group();
         this._sectorGroup = sectorGroup;
-    },
+    }
 
-    render: function (seriesModel, ecModel, api, payload) {
+    render(seriesModel: PieSeries, ecModel: GlobalModel, api: ExtensionAPI, 
payload: Payload): void {
         if (payload && (payload.from === this.uid)) {
             return;
         }
@@ -347,6 +376,7 @@ var PieView = ChartView.extend({
                 var piePiece = new PiePiece(data, idx);
                 // Default expansion animation
                 if (isFirstRender && animationType !== 'scale') {
+                    // @ts-ignore FIXME:TS modify zr?
                     piePiece.eachChild(function (child) {
                         child.stopAnimation(true);
                     });
@@ -359,9 +389,10 @@ var PieView = ChartView.extend({
                 group.add(piePiece);
             })
             .update(function (newIdx, oldIdx) {
-                var piePiece = oldData.getItemGraphicEl(oldIdx);
+                var piePiece = oldData.getItemGraphicEl(oldIdx) as PiePiece;
 
                 if (!isFirstRender && animationTypeUpdate !== 'transition') {
+                    // @ts-ignore FIXME:TS modify zr?
                     piePiece.eachChild(function (child) {
                         child.stopAnimation(true);
                     });
@@ -402,13 +433,17 @@ var PieView = ChartView.extend({
         }
 
         this._data = data;
-    },
+    }
 
-    dispose: function () {},
+    dispose() {}
 
-    _createClipPath: function (
-        cx, cy, r, startAngle, clockwise, cb, seriesModel, isFirstRender
-    ) {
+    _createClipPath(
+        cx: number, cy: number, r: number,
+        startAngle: number, clockwise: boolean,
+        // @ts-ignore FIXME:TS make type in util.grpahic
+        cb,
+        seriesModel: PieSeries, isFirstRender: boolean
+    ): graphic.Sector {
         var clipPath = new graphic.Sector({
             shape: {
                 cx: cx,
@@ -429,12 +464,12 @@ var PieView = ChartView.extend({
         }, seriesModel, cb);
 
         return clipPath;
-    },
+    }
 
     /**
-     * @implement
+     * @implements
      */
-    containPoint: function (point, seriesModel) {
+    containPoint = function (point: number[], seriesModel: PieSeries): boolean 
{
         var data = seriesModel.getData();
         var itemLayout = data.getItemLayout(0);
         if (itemLayout) {
@@ -444,7 +479,8 @@ var PieView = ChartView.extend({
             return radius <= itemLayout.r && radius >= itemLayout.r0;
         }
     }
+}
 
-});
+ChartView.registerClass(PieView);
 
 export default PieView;
diff --git a/src/component/helper/selectableMixin.ts 
b/src/component/helper/selectableMixin.ts
index 7f4db3d..9ca7a61 100644
--- a/src/component/helper/selectableMixin.ts
+++ b/src/component/helper/selectableMixin.ts
@@ -17,8 +17,6 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 /**
  * Data selectable mixin for chart series.
  * To eanble data select, option of series must have `selectedMode`.
@@ -26,34 +24,49 @@
  */
 
 import * as zrUtil from 'zrender/src/core/util';
+import Model from '../../model/Model';
+
+export type SelectableTarget = {
+    name: string,
+    value: any,
+    selected: boolean
+};
+
+interface DataSelectableMixin extends Pick<Model, 'get'> {};
+
+class DataSelectableMixin {
+
+    private _targetList: SelectableTarget[];
+
+    // Key: target.name
+    private _selectTargetMap: zrUtil.HashMap<SelectableTarget>;
 
-export default {
 
     /**
-     * @param {Array.<Object>} targetList [{name, value, selected}, ...]
+     * @param targetList [{name, value, selected}, ...]
      *        If targetList is an array, it should like [{name: ..., value: 
...}, ...].
      *        If targetList is a "List", it must have coordDim: 'value' 
dimension and name.
      */
-    updateSelectedMap: function (targetList) {
+    updateSelectedMap(targetList?: SelectableTarget[]): void {
         this._targetList = zrUtil.isArray(targetList) ? targetList.slice() : 
[];
 
         this._selectTargetMap = zrUtil.reduce(targetList || [], function 
(targetMap, target) {
             targetMap.set(target.name, target);
             return targetMap;
         }, zrUtil.createHashMap());
-    },
+    }
 
     /**
      * Either name or id should be passed as input here.
      * If both of them are defined, id is used.
      *
-     * @param {string|undefined} name name of data
-     * @param {number|undefined} id dataIndex of data
+     * @param name name of data. Can be null/undefined.
+     * @param idx dataIndex of data. Can be null/undefined.
      */
     // PENGING If selectedMode is null ?
-    select: function (name, id) {
-        var target = id != null
-            ? this._targetList[id]
+    select(name?: string, idx?: number): void {
+        var target = idx != null
+            ? this._targetList[idx]
             : this._selectTargetMap.get(name);
         var selectedMode = this.get('selectedMode');
         if (selectedMode === 'single') {
@@ -62,52 +75,54 @@ export default {
             });
         }
         target && (target.selected = true);
-    },
+    }
 
     /**
      * Either name or id should be passed as input here.
      * If both of them are defined, id is used.
      *
-     * @param {string|undefined} name name of data
-     * @param {number|undefined} id dataIndex of data
+     * @param name name of data. Can be null/undefined.
+     * @param idx dataIndex of data. Can be null/undefined.
      */
-    unSelect: function (name, id) {
-        var target = id != null
-            ? this._targetList[id]
+    unSelect(name?: string, idx?: number): void {
+        var target = idx != null
+            ? this._targetList[idx]
             : this._selectTargetMap.get(name);
         // var selectedMode = this.get('selectedMode');
         // selectedMode !== 'single' && target && (target.selected = false);
         target && (target.selected = false);
-    },
+    }
 
     /**
      * Either name or id should be passed as input here.
      * If both of them are defined, id is used.
      *
-     * @param {string|undefined} name name of data
-     * @param {number|undefined} id dataIndex of data
+     * @param name name of data. Can be null/undefined.
+     * @param idx dataIndex of data. Can be null/undefined.
      */
-    toggleSelected: function (name, id) {
-        var target = id != null
-            ? this._targetList[id]
+    toggleSelected(name?: string, idx?: number): boolean {
+        var target = idx != null
+            ? this._targetList[idx]
             : this._selectTargetMap.get(name);
         if (target != null) {
-            this[target.selected ? 'unSelect' : 'select'](name, id);
+            this[target.selected ? 'unSelect' : 'select'](name, idx);
             return target.selected;
         }
-    },
+    }
 
     /**
      * Either name or id should be passed as input here.
      * If both of them are defined, id is used.
      *
-     * @param {string|undefined} name name of data
-     * @param {number|undefined} id dataIndex of data
+     * @param name name of data. Can be null/undefined.
+     * @param idx dataIndex of data. Can be null/undefined.
      */
-    isSelected: function (name, id) {
-        var target = id != null
-            ? this._targetList[id]
+    isSelected(name?: string, idx?: number): boolean {
+        var target = idx != null
+            ? this._targetList[idx]
             : this._selectTargetMap.get(name);
         return target && target.selected;
     }
-};
\ No newline at end of file
+}
+
+export {DataSelectableMixin};
diff --git a/src/coord/geo/GeoModel.ts b/src/coord/geo/GeoModel.ts
index 341c422..4f9361c 100644
--- a/src/coord/geo/GeoModel.ts
+++ b/src/coord/geo/GeoModel.ts
@@ -23,7 +23,7 @@ import * as zrUtil from 'zrender/src/core/util';
 import * as modelUtil from '../../util/model';
 import ComponentModel from '../../model/Component';
 import Model from '../../model/Model';
-import selectableMixin from '../../component/helper/selectableMixin';
+import {DataSelectableMixin} from '../../component/helper/selectableMixin';
 import geoCreator from './geoCreator';
 
 var GeoModel = ComponentModel.extend({
@@ -176,6 +176,6 @@ var GeoModel = ComponentModel.extend({
     }
 });
 
-zrUtil.mixin(GeoModel, selectableMixin);
+zrUtil.mixin(GeoModel, DataSelectableMixin.prototype);
 
 export default GeoModel;
\ No newline at end of file
diff --git a/src/data/List.ts b/src/data/List.ts
index f9d7ac1..7344dbe 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -30,13 +30,13 @@ import Model from '../model/Model';
 import DataDiffer from './DataDiffer';
 import Source, { SourceConstructor } from './Source';
 import {DefaultDataProvider, DataProvider} from './helper/dataProvider';
-import {summarizeDimensions, DimensionSummary, DimensionUserOuput} from 
'./helper/dimensionHelper';
+import {summarizeDimensions, DimensionSummary} from './helper/dimensionHelper';
 import DataDimensionInfo from './DataDimensionInfo';
 import {ArrayLike, Dictionary, FunctionPropertyNames} from 
'zrender/src/core/types';
 import Element from 'zrender/src/Element';
 import {
     DimensionIndex, DimensionName, ECElement, DimensionLoose, OptionDataItem,
-    ParsedDataValue, ParsedDataNumeric, OrdinalRawValueIndex
+    ParsedDataValue, ParsedDataNumeric, OrdinalRawValueIndex, 
DimensionUserOuput
 } from '../util/types';
 import {parseDate} from '../util/number';
 import {isDataItemOption} from '../util/model';
@@ -330,10 +330,10 @@ class List {
      *        If idx is number, and not found, return null/undefined.
      *        If idx is `true`, and not found, return empty array (always 
return array).
      */
-    mapDimension<Idx extends (number | true)>(
-        coordDim: DimensionName,
-        idx?: Idx
-    ): (true extends Idx ? DimensionName[] : DimensionName) {
+    mapDimension(coordDim: DimensionName): DimensionName;
+    mapDimension(coordDim: DimensionName, idx: true): DimensionName[];
+    mapDimension(coordDim: DimensionName, idx: number): DimensionName;
+    mapDimension(coordDim: DimensionName, idx?: true | number): DimensionName 
| DimensionName[] {
         var dimensionsSummary = this._dimensionsSummary;
 
         if (idx == null) {
diff --git a/src/data/helper/createDimensions.ts 
b/src/data/helper/createDimensions.ts
index e159c77..ae187f3 100644
--- a/src/data/helper/createDimensions.ts
+++ b/src/data/helper/createDimensions.ts
@@ -17,31 +17,42 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 /**
  * Substitute `completeDimensions`.
  * `completeDimensions` is to be deprecated.
  */
 import completeDimensions from './completeDimensions';
+import { DimensionDefinitionLoose, OptionEncode, OptionEncodeValue, 
EncodeDefaulter } from '../../util/types';
+import Source from '../Source';
+import List from '../List';
+import DataDimensionInfo from '../DataDimensionInfo';
+import { HashMap } from 'zrender/src/core/util';
+
+export type CreateDimensionsParams = {
+    coordDimensions?: DimensionDefinitionLoose[],
+    dimensionsDefine?: DimensionDefinitionLoose[],
+    encodeDefine?: HashMap<OptionEncodeValue> | OptionEncode,
+    dimensionsCount?: number,
+    encodeDefaulter?: EncodeDefaulter,
+    generateCoord?: boolean,
+    generateCoordCount?: number
+};
 
 /**
- * @param {module:echarts/data/Source|module:echarts/data/List} source or data.
- * @param {Object|Array} [opt]
- * @param {Array.<string|Object>} [opt.coordDimensions=[]]
- * @param {number} [opt.dimensionsCount]
- * @param {string} [opt.generateCoord]
- * @param {string} [opt.generateCoordCount]
- * @param {Array.<string|Object>} 
[opt.dimensionsDefine=source.dimensionsDefine] Overwrite source define.
- * @param {Object|HashMap} [opt.encodeDefine=source.encodeDefine] Overwrite 
source define.
- * @param {Function} [opt.encodeDefaulter] Make default encode if user not 
specified.
- * @return {Array.<Object>} dimensionsInfo
+ * @param opt.coordDimensions
+ * @param opt.dimensionsDefine By default `source.dimensionsDefine` Overwrite 
source define.
+ * @param opt.encodeDefine By default `source.encodeDefine` Overwrite source 
define.
+ * @param opt.encodeDefaulter Make default encode if user not specified.
  */
-export default function (source, opt) {
+export default function (
+    source: Source | List,
+    opt?: CreateDimensionsParams
+): DataDimensionInfo[] {
     opt = opt || {};
     return completeDimensions(opt.coordDimensions || [], source, {
-        dimsDef: opt.dimensionsDefine || source.dimensionsDefine,
-        encodeDef: opt.encodeDefine || source.encodeDefine,
+        // FIXME:TS detect whether source then call `.dimensionsDefine` and 
`.encodeDefine`?
+        dimsDef: opt.dimensionsDefine || (source as Source).dimensionsDefine,
+        encodeDef: opt.encodeDefine || (source as Source).encodeDefine,
         dimCount: opt.dimensionsCount,
         encodeDefaulter: opt.encodeDefaulter,
         generateCoord: opt.generateCoord,
diff --git a/src/data/helper/dimensionHelper.ts 
b/src/data/helper/dimensionHelper.ts
index 1db36ed..7a3fb17 100644
--- a/src/data/helper/dimensionHelper.ts
+++ b/src/data/helper/dimensionHelper.ts
@@ -23,7 +23,7 @@ import {each, createHashMap, assert} from 
'zrender/src/core/util';
 import { __DEV__ } from '../../config';
 import List from '../List';
 import {
-    DimensionName, DimensionIndex, VISUAL_DIMENSIONS, DimensionType
+    DimensionName, VISUAL_DIMENSIONS, DimensionType, DimensionUserOuput
 } from '../../util/types';
 
 export type DimensionSummaryEncode = {
@@ -33,16 +33,6 @@ export type DimensionSummaryEncode = {
         // index: coordDimIndex, value: dataDimName
         DimensionName[]
 };
-export type DimensionUserOuputEncode = {
-    [coordOrVisualDimName: string]:
-        // index: coordDimIndex, value: dataDimIndex
-        DimensionIndex[]
-};
-export type DimensionUserOuput = {
-    // The same as `data.dimensions`
-    dimensionNames: DimensionName[]
-    encode: DimensionUserOuputEncode
-};
 export type DimensionSummary = {
     encode: DimensionSummaryEncode,
     // Those details that can be expose to users are put int `userOutput`.
diff --git a/src/echarts.ts b/src/echarts.ts
index 32fc419..57dbdc2 100644
--- a/src/echarts.ts
+++ b/src/echarts.ts
@@ -1121,7 +1121,15 @@ class ECharts {
                     var classType = parseClassType(model.type);
                     var Clazz = isComponent
                         ? (ComponentView as 
ComponentViewConstructor).getClass(classType.main, classType.sub)
-                        : (ChartView as 
ChartViewConstructor).getClass(classType.sub);
+                        : (
+                            // FIXME:TS
+                            // (ChartView as 
ChartViewConstructor).getClass('series', classType.sub)
+                            // For backward compat, still support a chart type 
declared as only subType
+                            // like "liquidfill", but recommend 
"series.liquidfill"
+                            // But need a base class to make a type series.
+                            // ||
+                            (ChartView as 
ChartViewConstructor).getClass(classType.sub)
+                        );
 
                     if (__DEV__) {
                         assert(Clazz, classType.sub + ' does not exist.');
diff --git a/src/model/Component.ts b/src/model/Component.ts
index 0a5ebeb..2e38e1f 100644
--- a/src/model/Component.ts
+++ b/src/model/Component.ts
@@ -34,7 +34,7 @@ import * as layout from '../util/layout';
 import boxLayoutMixin from './mixin/boxLayout';
 import { CoordinateSystem } from '../coord/CoordinateSystem';
 import GlobalModel from './Global';
-import { ComponentOption, ComponentMainType, ComponentSubType } from 
'../util/types';
+import { ComponentOption, ComponentMainType, ComponentSubType, 
ComponentFullType } from '../util/types';
 
 var inner = makeInner();
 
@@ -49,7 +49,7 @@ class ComponentModel extends Model {
     /**
      * @readonly
      */
-    type: string;
+    type: ComponentFullType;
 
     /**
      * @readonly
@@ -176,10 +176,12 @@ class ComponentModel extends Model {
      *     aaa: number
      * }
      * export class XxxModel extends Component {
-     *     readonly defaultOption: XxxOption = {
+     *     static type = 'xxx';
+     *     static defaultOption: XxxOption = {
      *         aaa: 123
      *     }
      * }
+     * Component.registerClass(XxxModel);
      * ```
      * ```ts
      * import {mergeOption} from '../model/util';
@@ -225,7 +227,8 @@ class ComponentModel extends Model {
         // in legacy env and auto merge defaultOption. So if using class
         // declaration, defaultOption should be merged manually.
         if (!isExtendedClass(ctor)) {
-            return ctor.prototype.defaultOption;
+            // When using ts class, defaultOption must be declared as static.
+            return (ctor as any).defaultOption;
         }
 
         // FIXME: remove this approach?
@@ -256,6 +259,7 @@ class ComponentModel extends Model {
         });
     }
 
+    static registerClass: ClassManager['registerClass'];
 }
 
 // Reset ComponentModel.extend, add preConstruct.
diff --git a/src/model/Global.ts b/src/model/Global.ts
index 41eb447..b4d3a05 100644
--- a/src/model/Global.ts
+++ b/src/model/Global.ts
@@ -40,7 +40,7 @@ import * as modelUtil from '../util/model';
 import Model from './Model';
 import ComponentModel, {ComponentModelConstructor} from './Component';
 import globalDefault from './globalDefault';
-import ColorPaletteMixin from './mixin/colorPalette';
+import {ColorPaletteMixin} from './mixin/colorPalette';
 import {resetSourceDefaulter} from '../data/helper/sourceHelper';
 import SeriesModel from './Series';
 import { Payload, OptionPreprocessor, ECOption, ECUnitOption, ThemeOption, 
ComponentOption, ComponentMainType, ComponentSubType } from '../util/types';
diff --git a/src/model/Model.ts b/src/model/Model.ts
index 3f7e32d..f65cebc 100644
--- a/src/model/Model.ts
+++ b/src/model/Model.ts
@@ -31,10 +31,10 @@ import {
     CheckableConstructor
 } from '../util/clazz';
 
-import lineStyleMixin from './mixin/lineStyle';
 import areaStyleMixin from './mixin/areaStyle';
 import textStyleMixin from './mixin/textStyle';
-import itemStyleMixin from './mixin/itemStyle';
+import {LineStyleMixin} from './mixin/lineStyle';
+import {ItemStyleMixin} from './mixin/itemStyle';
 import GlobalModel from './Global';
 import { ModelOption } from '../util/types';
 import { Dictionary } from 'zrender/src/core/types';
@@ -254,9 +254,11 @@ type ModelConstructor = typeof Model
 enableClassExtend(Model as ModelConstructor);
 enableClassCheck(Model as ModelConstructor);
 
-mixin(Model, lineStyleMixin);
+interface Model extends LineStyleMixin, ItemStyleMixin {}
+
+zrUtil.tsMixin(Model, LineStyleMixin);
 mixin(Model, areaStyleMixin);
 mixin(Model, textStyleMixin);
-mixin(Model, itemStyleMixin);
+zrUtil.tsMixin(Model, ItemStyleMixin);
 
 export default Model;
diff --git a/src/model/Series.ts b/src/model/Series.ts
index 0f64d53..4191a1a 100644
--- a/src/model/Series.ts
+++ b/src/model/Series.ts
@@ -32,7 +32,7 @@ import {
     SeriesOption, ComponentLayoutMode, TooltipRenderMode, AxisValue, ZRColor
 } from '../util/types';
 import ComponentModel, { ComponentModelConstructor } from './Component';
-import ColorPaletteMixin from './mixin/colorPalette';
+import {ColorPaletteMixin} from './mixin/colorPalette';
 import DataFormatMixin from '../model/mixin/dataFormat';
 import Model from '../model/Model';
 import {
@@ -47,9 +47,9 @@ import {
 import {retrieveRawValue} from '../data/helper/dataProvider';
 import GlobalModel from './Global';
 import { CoordinateSystem } from '../coord/CoordinateSystem';
-import { ExtendableConstructor, mountExtend } from '../util/clazz';
+import { ExtendableConstructor, mountExtend, ClassManager, Constructor } from 
'../util/clazz';
 import { PipelineContext, SeriesTaskContext, GeneralTask, OverallTask, 
SeriesTask } from '../stream/Scheduler';
-import { LegendVisualProviderType } from '../visual/LegendVisualProvider';
+import LegendVisualProvider from '../visual/LegendVisualProvider';
 import List from '../data/List';
 import Source from '../data/Source';
 
@@ -66,6 +66,9 @@ class SeriesModel extends ComponentModel {
     // @readonly
     type: string;
 
+    // Should be implenented in subclass.
+    defaultOption: SeriesOption;
+
     // @readonly
     seriesIndex: number;
 
@@ -78,7 +81,7 @@ class SeriesModel extends ComponentModel {
     pipelineContext: PipelineContext;
 
     // legend visual provider to the legend component
-    legendVisualProvider: LegendVisualProviderType;
+    legendVisualProvider: LegendVisualProvider;
 
     // Access path of color for visual
     visualColorAccessPath: string;
@@ -540,6 +543,9 @@ class SeriesModel extends ComponentModel {
      */
     preventIncremental: () => boolean;
 
+    static registerClass(clz: Constructor): Constructor {
+        return ComponentModel.registerClass(clz);
+    }
 }
 
 interface SeriesModel extends DataFormatMixin, ColorPaletteMixin, DataHost {}
diff --git a/src/model/mixin/colorPalette.ts b/src/model/mixin/colorPalette.ts
index b53daf1..3e72159 100644
--- a/src/model/mixin/colorPalette.ts
+++ b/src/model/mixin/colorPalette.ts
@@ -36,7 +36,7 @@ function getNearestColorPalette(
     return colors[paletteNum - 1];
 }
 
-interface ColorPaletteMixin extends Model {}
+interface ColorPaletteMixin extends Pick<Model, 'get'> {}
 
 class ColorPaletteMixin {
 
@@ -87,4 +87,4 @@ class ColorPaletteMixin {
     }
 };
 
-export default ColorPaletteMixin
+export {ColorPaletteMixin};
diff --git a/src/model/mixin/dataFormat.ts b/src/model/mixin/dataFormat.ts
index c337cb8..3c3b283 100644
--- a/src/model/mixin/dataFormat.ts
+++ b/src/model/mixin/dataFormat.ts
@@ -20,43 +20,13 @@
 import {retrieveRawValue} from '../../data/helper/dataProvider';
 import {getTooltipMarker, formatTpl, TooltipMarker} from '../../util/format';
 import { getTooltipRenderMode } from '../../util/model';
-import { DataHost, DisplayStatus, DimensionName, TooltipRenderMode } from 
'../../util/types';
+import { DataHost, DisplayState, TooltipRenderMode, DataParamsUserOutput } 
from '../../util/types';
 import GlobalModel from '../Global';
 import Element from 'zrender/src/Element';
-import { DimensionUserOuputEncode } from '../../data/helper/dimensionHelper';
 
 var DIMENSION_LABEL_REG = /\{@(.+?)\}/g;
 
 
-interface DataParams {
-    // component main type
-    componentType: string;
-    // component sub type
-    componentSubType: string;
-    componentIndex: number;
-    // series component sub type
-    seriesType?: string;
-    // series component index (the alias of `componentIndex` for series)
-    seriesIndex?: number;
-    seriesId?: string;
-    seriesName?: string;
-    name: string;
-    dataIndex: number;
-    data: any;
-    dataType?: string;
-    value: any;
-    color?: string;
-    borderColor?: string;
-    dimensionNames?: DimensionName[];
-    encode?: DimensionUserOuputEncode;
-    marker?: TooltipMarker;
-    status?: DisplayStatus;
-    dimensionIndex?: number;
-
-    // Param name list for mapping `a`, `b`, `c`, `d`, `e`
-    $vars: string[];
-}
-
 interface DataFormatMixin extends DataHost {
     ecModel: GlobalModel;
     mainType: string;
@@ -76,7 +46,7 @@ class DataFormatMixin {
         dataIndex: number,
         dataType?: string,
         el?: Element // May be used in override.
-    ): DataParams {
+    ): DataParamsUserOutput {
 
         var data = this.getData(dataType);
         var rawValue = this.getRawValue(dataIndex, dataType);
@@ -132,7 +102,7 @@ class DataFormatMixin {
     getFormattedLabel(
         this: DataFormatMixin,
         dataIndex: number,
-        status?: DisplayStatus,
+        status?: DisplayState,
         dataType?: string,
         dimIndex?: number,
         labelProp?: string
diff --git a/src/model/mixin/itemStyle.ts b/src/model/mixin/itemStyle.ts
index 8875635..5703152 100644
--- a/src/model/mixin/itemStyle.ts
+++ b/src/model/mixin/itemStyle.ts
@@ -17,9 +17,8 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import makeStyleMapper from './makeStyleMapper';
+import Model from '../Model';
 
 var getItemStyle = makeStyleMapper(
     [
@@ -36,17 +35,22 @@ var getItemStyle = makeStyleMapper(
     ]
 );
 
-export default {
-    getItemStyle: function (excludes, includes) {
+interface ItemStyleMixin extends Pick<Model, 'get'> {}
+
+class ItemStyleMixin {
+
+    getItemStyle(excludes?: string[], includes?: string[]) {
         var style = getItemStyle(this, excludes, includes);
         var lineDash = this.getBorderLineDash();
-        lineDash && (style.lineDash = lineDash);
+        lineDash && ((style as any).lineDash = lineDash);
         return style;
-    },
+    }
 
-    getBorderLineDash: function () {
+    getBorderLineDash() {
         var lineType = this.get('borderType');
         return (lineType === 'solid' || lineType == null) ? null
             : (lineType === 'dashed' ? [5, 5] : [1, 1]);
     }
-};
\ No newline at end of file
+}
+
+export {ItemStyleMixin};
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index 1925d57..3a0c8cb 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -17,9 +17,8 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import makeStyleMapper from './makeStyleMapper';
+import Model from '../Model';
 
 var getLineStyle = makeStyleMapper(
     [
@@ -33,16 +32,19 @@ var getLineStyle = makeStyleMapper(
     ]
 );
 
-export default {
-    getLineStyle: function (excludes) {
+interface LineStyleMixin extends Pick<Model, 'get'> {}
+
+class LineStyleMixin {
+
+    getLineStyle(excludes?: string[]) {
         var style = getLineStyle(this, excludes);
         // Always set lineDash whether dashed, otherwise we can not
         // erase the previous style when assigning to el.style.
-        style.lineDash = this.getLineDash(style.lineWidth);
+        (style as any).lineDash = this.getLineDash((style as any).lineWidth);
         return style;
-    },
+    }
 
-    getLineDash: function (lineWidth) {
+    getLineDash(lineWidth?: number) {
         if (lineWidth == null) {
             lineWidth = 1;
         }
@@ -60,4 +62,6 @@ export default {
             ? [dashSize, dashSize]
             : [dotSize, dotSize];
     }
-};
\ No newline at end of file
+};
+
+export {LineStyleMixin};
diff --git a/src/model/mixin/makeStyleMapper.ts 
b/src/model/mixin/makeStyleMapper.ts
index 319cd38..e7de475 100644
--- a/src/model/mixin/makeStyleMapper.ts
+++ b/src/model/mixin/makeStyleMapper.ts
@@ -30,7 +30,7 @@ export default function (properties) {
             properties[i][1] = properties[i][0];
         }
     }
-    return function (model, excludes, includes) {
+    return function (model, excludes, includes?) {
         var style = {};
         for (var i = 0; i < properties.length; i++) {
             var propName = properties[i][1];
diff --git a/src/util/clazz.ts b/src/util/clazz.ts
index de45dd5..619b041 100644
--- a/src/util/clazz.ts
+++ b/src/util/clazz.ts
@@ -189,11 +189,11 @@ function superApply(this: any, context: any, methodName: 
string, args: any): any
     return this.superClass.prototype[methodName].apply(context, args);
 }
 
-type Constructor = new (...args: any) => any;
+export type Constructor = new (...args: any) => any;
 type SubclassContainer = {[subType: string]: Constructor} & {[IS_CONTAINER]?: 
true};
 
 export interface ClassManager {
-    registerClass: (clz: Constructor, componentType: ComponentFullType) => 
Constructor;
+    registerClass: (clz: Constructor) => Constructor;
     getClass: (
         componentMainType: ComponentMainType, subType?: ComponentSubType, 
throwWhenNotFound?: boolean
     ) => Constructor;
@@ -232,12 +232,23 @@ export function enableClassManagement(
     } = {};
 
     target.registerClass = function (
-        clz: Constructor,
-        componentType: ComponentFullType
+        clz: Constructor
     ): Constructor {
-        if (componentType) {
-            checkClassType(componentType);
-            var componentTypeInfo = parseClassType(componentType);
+
+        // `type` should not be a "instance memeber".
+        // If using TS class, should better declared as `static type = 
'series.pie'`.
+        // otherwise users have to mount `type` on prototype manually.
+        // For backward compat and enable instance visit type via `this.type`,
+        // we stil support fetch `type` from prototype.
+        var componentFullType = (clz as any).type || clz.prototype.type;
+
+        if (componentFullType) {
+            checkClassType(componentFullType);
+
+            // If only static type declared, we assign it to prototype 
mandatorily.
+            clz.prototype.type = componentFullType;
+
+            var componentTypeInfo = parseClassType(componentFullType);
 
             if (!componentTypeInfo.sub) {
                 if (__DEV__) {
@@ -336,7 +347,7 @@ export function enableClassManagement(
         if (originalExtend) {
             (target as any).extend = function (proto: any) {
                 var ExtendedClass = originalExtend.call(this, proto);
-                return target.registerClass(ExtendedClass, proto.type);
+                return target.registerClass(ExtendedClass);
             };
         }
     }
diff --git a/src/util/graphic.ts b/src/util/graphic.ts
index 1064c2d..a7cd84a 100644
--- a/src/util/graphic.ts
+++ b/src/util/graphic.ts
@@ -559,7 +559,7 @@ function shouldSilent(el, e) {
  * @param {Function} [el.highDownOnUpdate] See 
`graphic.setAsHighDownDispatcher`.
  * @param {Object|boolean} [hoverStyle] See `graphic.setElementHoverStyle`.
  */
-export function setHoverStyle(el, hoverStyle) {
+export function setHoverStyle(el, hoverStyle?) {
     setAsHighDownDispatcher(el, true);
     traverseUpdate(el, setElementHoverStyle, hoverStyle);
 }
@@ -666,7 +666,7 @@ export function setLabelStyle(
     normalStyle, emphasisStyle,
     normalModel, emphasisModel,
     opt,
-    normalSpecified, emphasisSpecified
+    normalSpecified, emphasisSpecified?
 ) {
     opt = opt || EMPTY_OBJ;
     var labelFetcher = opt.labelFetcher;
@@ -1143,7 +1143,7 @@ function animateOrSetProps(isUpdate, el, props, 
animatableModel, dataIndex, cb)
  *         position: [100, 100]
  *     }, seriesModel, function () { console.log('Animation done!'); });
  */
-export function updateProps(el, props, animatableModel, dataIndex, cb) {
+export function updateProps(el, props, animatableModel, dataIndex, cb?) {
     animateOrSetProps(true, el, props, animatableModel, dataIndex, cb);
 }
 
@@ -1161,7 +1161,7 @@ export function updateProps(el, props, animatableModel, 
dataIndex, cb) {
  * @param {number} [dataIndex]
  * @param {Function} cb
  */
-export function initProps(el, props, animatableModel, dataIndex, cb) {
+export function initProps(el, props, animatableModel, dataIndex, cb?) {
     animateOrSetProps(false, el, props, animatableModel, dataIndex, cb);
 }
 
diff --git a/src/util/model.ts b/src/util/model.ts
index ccac59b..f6a3ee0 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -23,7 +23,7 @@ import Component from '../model/Component';
 import GlobalModel, { QueryConditionKindB } from '../model/Global';
 import ComponentModel from '../model/Component';
 import List from '../data/List';
-import { Payload, ComponentOption, ComponentMainType, ComponentSubType, 
DisplayStatusHostOption, OptionDataItem, OptionDataPrimitive, TooltipRenderMode 
} from './types';
+import { Payload, ComponentOption, ComponentMainType, ComponentSubType, 
DisplayStateHostOption, OptionDataItem, OptionDataPrimitive, TooltipRenderMode 
} from './types';
 import { Dictionary } from 'zrender/src/core/types';
 
 var each = zrUtil.each;
@@ -63,7 +63,7 @@ export function normalizeToArray<T>(value: T | T[]): T[] {
  *     }
  */
 export function defaultEmphasis(
-    opt: DisplayStatusHostOption,
+    opt: DisplayStateHostOption,
     key: string,
     subOpts: string[]
 ): void {
diff --git a/src/util/types.ts b/src/util/types.ts
index 3809873..9eba141 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -37,6 +37,8 @@ import List, {ListDimensionType} from '../data/List';
 import { Dictionary } from 'zrender/src/core/types';
 import { GradientObject } from 'zrender/src/graphic/Gradient';
 import { PatternObject } from 'zrender/src/graphic/Pattern';
+import Source from '../data/Source';
+import { TooltipMarker } from './format';
 
 
 
@@ -259,7 +261,6 @@ export type SourceFormat =
     | typeof SOURCE_FORMAT_TYPED_ARRAY
     | typeof SOURCE_FORMAT_UNKNOWN;
 
-// FIXME:TS remove it finally
 export var SERIES_LAYOUT_BY_COLUMN = 'column' as const;
 export var SERIES_LAYOUT_BY_ROW = 'row' as const;
 
@@ -369,13 +370,12 @@ export type OptionDataItem =
     | {value: ArrayLike<OptionDataPrimitive>}; // Only for 
`SOURCE_FORMAT_KEYED_ORIGINAL`
 export type OptionDataPrimitive = string | number | Date;
 
-// FIXME:TS in fact ModelOption can be any?
 // export type ModelOption = Dictionary<any> | any[] | string | number | 
boolean | ((...args: any) => any);
 export type ModelOption = any;
 export type ThemeOption = Dictionary<any>;
 
-export type DisplayStatus = 'normal' | 'emphasis';
-export type DisplayStatusHostOption = {
+export type DisplayState = 'normal' | 'emphasis';
+export type DisplayStateHostOption = {
     emphasis?: Dictionary<any>,
     [key: string]: any
 };
@@ -393,6 +393,47 @@ export interface OptionEncode extends 
OptionEncodeVisualDimensions {
     [coordDim: string]: OptionEncodeValue
 }
 export type OptionEncodeValue = DimensionIndex[] | DimensionIndex | 
DimensionName[] | DimensionName;
+export type EncodeDefaulter = (source: Source, dimCount: number) => 
OptionEncode;
+
+export interface DataParamsUserOutput {
+    // component main type
+    componentType: string;
+    // component sub type
+    componentSubType: string;
+    componentIndex: number;
+    // series component sub type
+    seriesType?: string;
+    // series component index (the alias of `componentIndex` for series)
+    seriesIndex?: number;
+    seriesId?: string;
+    seriesName?: string;
+    name: string;
+    dataIndex: number;
+    data: any;
+    dataType?: string;
+    value: any;
+    color?: string;
+    borderColor?: string;
+    dimensionNames?: DimensionName[];
+    encode?: DimensionUserOuputEncode;
+    marker?: TooltipMarker;
+    status?: DisplayState;
+    dimensionIndex?: number;
+    percent?: number; // Only for chart like 'pie'
+
+    // Param name list for mapping `a`, `b`, `c`, `d`, `e`
+    $vars: string[];
+}
+export type DimensionUserOuputEncode = {
+    [coordOrVisualDimName: string]:
+        // index: coordDimIndex, value: dataDimIndex
+        DimensionIndex[]
+};
+export type DimensionUserOuput = {
+    // The same as `data.dimensions`
+    dimensionNames: DimensionName[]
+    encode: DimensionUserOuputEncode
+};
 
 export interface MediaQuery {
     minWidth?: number;
diff --git a/src/view/Chart.ts b/src/view/Chart.ts
index 87ace50..0e2ac7e 100644
--- a/src/view/Chart.ts
+++ b/src/view/Chart.ts
@@ -31,7 +31,7 @@ import ExtensionAPI from '../ExtensionAPI';
 import Element from 'zrender/src/Element';
 import {
     Payload, ViewRootGroup, ECEvent, EventQueryItem,
-    StageHandlerPlanReturn, DisplayStatus, StageHandlerProgressParams
+    StageHandlerPlanReturn, DisplayState, StageHandlerProgressParams
 } from '../util/types';
 import { SeriesTaskContext, SeriesTask } from '../stream/Scheduler';
 import List from '../data/List';
@@ -180,13 +180,14 @@ class Chart {
         inner(payload).updateMethod = methodName;
     }
 
+    static registerClass: clazzUtil.ClassManager['registerClass'];
 };
 
 
 /**
  * Set state of single element
  */
-function elSetState(el: Element, state: DisplayStatus, highlightDigit: number) 
{
+function elSetState(el: Element, state: DisplayState, highlightDigit: number) {
     if (el) {
         el.trigger(state, highlightDigit);
         if (el.isGroup
@@ -200,7 +201,7 @@ function elSetState(el: Element, state: DisplayStatus, 
highlightDigit: number) {
     }
 }
 
-function toggleHighlight(data: List, payload: Payload, state: DisplayStatus) {
+function toggleHighlight(data: List, payload: Payload, state: DisplayState) {
     var dataIndex = modelUtil.queryDataIndex(data, payload);
 
     var highlightDigit = (payload && payload.highlightKey != null)
diff --git a/src/view/Component.ts b/src/view/Component.ts
index 5cbf955..0417ccd 100644
--- a/src/view/Component.ts
+++ b/src/view/Component.ts
@@ -83,6 +83,7 @@ class Component {
         seriesModel: ComponentModel, ecModel: GlobalModel, api: ExtensionAPI, 
payload: Payload
     ) => void | {update: true};
 
+    static registerClass: clazzUtil.ClassManager['registerClass'];
 };
 
 export type ComponentViewConstructor = typeof Component
diff --git a/src/visual/LegendVisualProvider.ts 
b/src/visual/LegendVisualProvider.ts
index 9f4663e..e3b8778 100644
--- a/src/visual/LegendVisualProvider.ts
+++ b/src/visual/LegendVisualProvider.ts
@@ -67,4 +67,3 @@ class LegendVisualProvider {
 }
 
 export default LegendVisualProvider;
-export type LegendVisualProviderType = typeof LegendVisualProvider;


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

Reply via email to