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/02/25 04:11:45 UTC

[incubator-echarts] branch typescript updated: ts: add types on funnel and gauge

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 786ae68  ts: add types on funnel and gauge
786ae68 is described below

commit 786ae682bfaf9a43eb3ed78f86a67028dc0cd8f8
Author: pissang <bm...@gmail.com>
AuthorDate: Tue Feb 25 12:10:59 2020 +0800

    ts: add types on funnel and gauge
---
 src/chart/funnel/FunnelSeries.ts              | 103 +++++++--
 src/chart/funnel/FunnelView.ts                | 296 ++++++++++++++------------
 src/chart/funnel/funnelLayout.ts              |  25 ++-
 src/chart/gauge/GaugeSeries.ts                | 112 +++++++++-
 src/chart/gauge/GaugeView.ts                  | 112 ++++++----
 src/chart/gauge/PointerPath.ts                |  35 +--
 src/chart/pie/PieSeries.ts                    |  19 +-
 src/chart/pie/PieView.ts                      |  14 +-
 src/chart/pie/labelLayout.ts                  |   4 +-
 src/chart/pie/pieLayout.ts                    |   6 +-
 src/component/axisPointer/AxisPointerModel.ts |  24 ++-
 src/data/List.ts                              |   1 +
 src/model/Model.ts                            |  10 +-
 src/model/mixin/areaStyle.ts                  |  39 ++--
 src/model/mixin/itemStyle.ts                  |  24 ++-
 src/model/mixin/lineStyle.ts                  |  35 +--
 src/model/mixin/makeStyleMapper.ts            |  10 +-
 src/model/mixin/textStyle.ts                  |   6 +-
 src/util/types.ts                             |   8 +-
 19 files changed, 578 insertions(+), 305 deletions(-)

diff --git a/src/chart/funnel/FunnelSeries.ts b/src/chart/funnel/FunnelSeries.ts
index 07710a0..cead1b7 100644
--- a/src/chart/funnel/FunnelSeries.ts
+++ b/src/chart/funnel/FunnelSeries.ts
@@ -17,21 +17,83 @@
 * under the License.
 */
 
-// @ts-nocheck
-
-import * as echarts from '../../echarts';
 import * as zrUtil from 'zrender/src/core/util';
 import createListSimply from '../helper/createListSimply';
 import {defaultEmphasis} from '../../util/model';
 import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper';
 import LegendVisualProvider from '../../visual/LegendVisualProvider';
+import SeriesModel from '../../model/Series';
+import {
+    SeriesOption,
+    BoxLayoutOptionMixin,
+    ZRAlign,
+    LabelOption,
+    LabelLineOption,
+    ItemStyleOption,
+    OptionDataValueNumeric
+} from '../../util/types';
+import GlobalModel from '../../model/Global';
+import List from '../../data/List';
+import ComponentModel from '../../model/Component';
+
+
+type FunnelLabelOption = Omit<LabelOption, 'position'> & {
+    position?: LabelOption['position'] | 'outer'
+}
+
+interface FunnelDataItem {
+    name?: string
+
+    value?: OptionDataValueNumeric
+
+    itemStyle?: ItemStyleOption
+    label?: FunnelLabelOption
+    labelLine?: LabelLineOption
+
+    emphasis?: {
+        itemStyle?: ItemStyleOption
+        label?: FunnelLabelOption
+        labelLine?: LabelLineOption
+    }
+}
+
+export interface FunnelSeriesOption
+    extends SeriesOption, BoxLayoutOptionMixin {
+
+    min?: number
+    max?: number
+
+    /**
+     * Absolute number or percent string
+     */
+    minSize?: number | string
+    maxSize?: number | string
+
+    sort?: 'ascending' | 'descending' | 'none'
 
-var FunnelSeries = echarts.extendSeriesModel({
+    gap?: number
 
-    type: 'series.funnel',
+    funnelAlign?: ZRAlign
 
-    init: function (option) {
-        FunnelSeries.superApply(this, 'init', arguments);
+    label?: FunnelLabelOption
+    labelLine?: LabelLineOption
+    itemStyle?: ItemStyleOption
+
+    emphasis?: {
+        label?: FunnelLabelOption
+        labelLine?: LabelLineOption
+        itemStyle?: ItemStyleOption
+    }
+
+    data?: OptionDataValueNumeric[] | FunnelDataItem[]
+}
+
+class FunnelSeriesModel extends SeriesModel<FunnelSeriesOption> {
+    static type = 'series.funnel' as const
+    type = FunnelSeriesModel.type
+
+    init(option: FunnelSeriesOption) {
+        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
@@ -40,16 +102,16 @@ var FunnelSeries = echarts.extendSeriesModel({
         );
         // Extend labelLine emphasis
         this._defaultLabelLine(option);
-    },
+    }
 
-    getInitialData: function (option, ecModel) {
+    getInitialData(option: FunnelSeriesOption, ecModel: GlobalModel): List {
         return createListSimply(this, {
             coordDimensions: ['value'],
             encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this)
         });
-    },
+    }
 
-    _defaultLabelLine: function (option) {
+    _defaultLabelLine(option: FunnelSeriesOption) {
         // Extend labelLine emphasis
         defaultEmphasis(option, 'labelLine', ['show']);
 
@@ -60,22 +122,22 @@ var FunnelSeries = echarts.extendSeriesModel({
             && option.label.show;
         labelLineEmphasisOpt.show = labelLineEmphasisOpt.show
             && option.emphasis.label.show;
-    },
+    }
 
     // Overwrite
-    getDataParams: function (dataIndex) {
+    getDataParams(dataIndex: number) {
         var data = this.getData();
-        var params = FunnelSeries.superCall(this, 'getDataParams', dataIndex);
+        var params = super.getDataParams(dataIndex);
         var valueDim = data.mapDimension('value');
         var sum = data.getSum(valueDim);
         // Percent is 0 if sum is 0
-        params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) / sum * 100).toFixed(2);
+        params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) as number / sum * 100).toFixed(2);
 
         params.$vars.push('percent');
         return params;
-    },
+    }
 
-    defaultOption: {
+    static defaultOption: FunnelSeriesOption = {
         zlevel: 0,                  // 一级层叠
         z: 2,                       // 二级层叠
         legendHoverLink: true,
@@ -119,6 +181,9 @@ var FunnelSeries = echarts.extendSeriesModel({
             }
         }
     }
-});
 
-export default FunnelSeries;
+}
+
+ComponentModel.registerClass(FunnelSeriesModel);
+
+export default FunnelSeriesModel;
diff --git a/src/chart/funnel/FunnelView.ts b/src/chart/funnel/FunnelView.ts
index 80cae48..d942e4a 100644
--- a/src/chart/funnel/FunnelView.ts
+++ b/src/chart/funnel/FunnelView.ts
@@ -17,173 +17,184 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as graphic from '../../util/graphic';
 import * as zrUtil from 'zrender/src/core/util';
 import ChartView from '../../view/Chart';
-
+import ComponentView from '../../view/Component';
+import FunnelSeriesModel from './FunnelSeries';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import List from '../../data/List';
+import { DisplayState } from '../../util/types';
+import Displayable from 'zrender/src/graphic/Displayable';
+
+const opacityAccessPath = ['itemStyle', 'opacity'] as const;
+
+type ExtendedDisplayable = Displayable & {
+    hoverIgnore?: boolean
+    normalIgnore?: boolean
+}
 /**
  * Piece of pie including Sector, Label, LabelLine
- * @constructor
- * @extends {module:zrender/graphic/Group}
  */
-function FunnelPiece(data, idx) {
+class FunnelPiece extends graphic.Group {
+
+    constructor(data: List, idx: number) {
+        super();
+
+        var polygon = new graphic.Polygon();
+        var labelLine = new graphic.Polyline();
+        var text = new graphic.Text();
+        this.add(polygon);
+        this.add(labelLine);
+        this.add(text);
+
+        this.updateData(data, idx, true);
+    }
 
-    graphic.Group.call(this);
+    highDownOnUpdate(fromState: DisplayState, toState: DisplayState) {
 
-    var polygon = new graphic.Polygon();
-    var labelLine = new graphic.Polyline();
-    var text = new graphic.Text();
-    this.add(polygon);
-    this.add(labelLine);
-    this.add(text);
+        var labelLine = this.childAt(1) as graphic.Polyline;
+        var text = this.childAt(2) as graphic.Text;
 
-    this.highDownOnUpdate = function (fromState, toState) {
         if (toState === 'emphasis') {
-            labelLine.ignore = labelLine.hoverIgnore;
-            text.ignore = text.hoverIgnore;
+            labelLine.ignore = (labelLine as ExtendedDisplayable).hoverIgnore;
+            text.ignore = (text as ExtendedDisplayable).hoverIgnore;
         }
         else {
-            labelLine.ignore = labelLine.normalIgnore;
-            text.ignore = text.normalIgnore;
+            labelLine.ignore = (labelLine as ExtendedDisplayable).normalIgnore;
+            text.ignore = (text as ExtendedDisplayable).normalIgnore;
         }
-    };
-
-    this.updateData(data, idx, true);
-}
-
-var funnelPieceProto = FunnelPiece.prototype;
+    }
 
-var opacityAccessPath = ['itemStyle', 'opacity'];
-funnelPieceProto.updateData = function (data, idx, firstCreate) {
+    updateData(data: List, idx: number, firstCreate?: boolean) {
 
-    var polygon = this.childAt(0);
+        var polygon = this.childAt(0) as graphic.Polygon;
 
-    var seriesModel = data.hostModel;
-    var itemModel = data.getItemModel(idx);
-    var layout = data.getItemLayout(idx);
-    var opacity = data.getItemModel(idx).get(opacityAccessPath);
-    opacity = opacity == null ? 1 : opacity;
+        var seriesModel = data.hostModel;
+        var itemModel = data.getItemModel(idx);
+        var layout = data.getItemLayout(idx);
+        var opacity = data.getItemModel(idx).get(opacityAccessPath);
+        opacity = opacity == null ? 1 : opacity;
 
-    // Reset style
-    polygon.useStyle({});
+        // Reset style
+        polygon.useStyle({});
 
-    if (firstCreate) {
-        polygon.setShape({
-            points: layout.points
-        });
-        polygon.setStyle({opacity: 0});
-        graphic.initProps(polygon, {
-            style: {
-                opacity: opacity
-            }
-        }, seriesModel, idx);
-    }
-    else {
-        graphic.updateProps(polygon, {
-            style: {
-                opacity: opacity
-            },
-            shape: {
+        if (firstCreate) {
+            polygon.setShape({
                 points: layout.points
-            }
-        }, seriesModel, idx);
-    }
+            });
+            polygon.setStyle({opacity: 0});
+            graphic.initProps(polygon, {
+                style: {
+                    opacity: opacity
+                }
+            }, seriesModel, idx);
+        }
+        else {
+            graphic.updateProps(polygon, {
+                style: {
+                    opacity: opacity
+                },
+                shape: {
+                    points: layout.points
+                }
+            }, seriesModel, idx);
+        }
 
-    // Update common style
-    var itemStyleModel = itemModel.getModel('itemStyle');
-    var visualColor = data.getItemVisual(idx, 'color');
+        // Update common style
+        var itemStyleModel = itemModel.getModel('itemStyle');
+        var visualColor = data.getItemVisual(idx, 'color');
 
-    polygon.setStyle(
-        zrUtil.defaults(
-            {
-                lineJoin: 'round',
-                fill: visualColor
-            },
-            itemStyleModel.getItemStyle(['opacity'])
-        )
-    );
-    polygon.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();
+        polygon.setStyle(
+            zrUtil.defaults(
+                {
+                    lineJoin: 'round',
+                    fill: visualColor
+                },
+                itemStyleModel.getItemStyle(['opacity'])
+            )
+        );
+        polygon.hoverStyle = itemStyleModel.getModel('emphasis').getItemStyle();
 
-    this._updateLabel(data, idx);
+        this._updateLabel(data, idx);
 
-    graphic.setHoverStyle(this);
-};
+        graphic.setHoverStyle(this);
+    }
 
-funnelPieceProto._updateLabel = function (data, idx) {
+    _updateLabel(data: List, idx: number) {
 
-    var labelLine = this.childAt(1);
-    var labelText = this.childAt(2);
+        var labelLine = this.childAt(1) as graphic.Polyline;
+        var labelText = this.childAt(2) as graphic.Text;
 
-    var seriesModel = data.hostModel;
-    var itemModel = data.getItemModel(idx);
-    var layout = data.getItemLayout(idx);
-    var labelLayout = layout.label;
-    var visualColor = data.getItemVisual(idx, 'color');
+        var seriesModel = data.hostModel;
+        var itemModel = data.getItemModel(idx);
+        var layout = data.getItemLayout(idx);
+        var labelLayout = layout.label;
+        var visualColor = data.getItemVisual(idx, 'color');
 
-    graphic.updateProps(labelLine, {
-        shape: {
-            points: labelLayout.linePoints || labelLayout.linePoints
-        }
-    }, seriesModel, idx);
+        graphic.updateProps(labelLine, {
+            shape: {
+                points: labelLayout.linePoints || labelLayout.linePoints
+            }
+        }, seriesModel, idx);
 
-    graphic.updateProps(labelText, {
-        style: {
-            x: labelLayout.x,
-            y: labelLayout.y
-        }
-    }, seriesModel, idx);
-    labelText.attr({
-        rotation: labelLayout.rotation,
-        origin: [labelLayout.x, labelLayout.y],
-        z2: 10
-    });
-
-    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: data.getName(idx),
-            autoColor: visualColor,
-            useInsideStyle: !!labelLayout.inside
-        },
-        {
-            textAlign: labelLayout.textAlign,
-            textVerticalAlign: labelLayout.verticalAlign
-        }
-    );
+        graphic.updateProps(labelText, {
+            style: {
+                x: labelLayout.x,
+                y: labelLayout.y
+            }
+        }, seriesModel, idx);
+        labelText.attr({
+            rotation: labelLayout.rotation,
+            origin: [labelLayout.x, labelLayout.y],
+            z2: 10
+        });
 
-    labelText.ignore = labelText.normalIgnore = !labelModel.get('show');
-    labelText.hoverIgnore = !labelHoverModel.get('show');
+        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');
 
-    labelLine.ignore = labelLine.normalIgnore = !labelLineModel.get('show');
-    labelLine.hoverIgnore = !labelLineHoverModel.get('show');
+        graphic.setLabelStyle(
+            labelText.style, labelText.hoverStyle = {}, labelModel, labelHoverModel,
+            {
+                labelFetcher: data.hostModel as FunnelSeriesModel,
+                labelDataIndex: idx,
+                defaultText: data.getName(idx),
+                autoColor: visualColor,
+                useInsideStyle: !!labelLayout.inside
+            },
+            {
+                textAlign: labelLayout.textAlign,
+                textVerticalAlign: labelLayout.verticalAlign
+            }
+        );
 
-    // Default use item visual color
-    labelLine.setStyle({
-        stroke: visualColor
-    });
-    labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());
+        labelText.ignore = (labelText as ExtendedDisplayable).normalIgnore = !labelModel.get('show');
+        (labelText as ExtendedDisplayable).hoverIgnore = !labelHoverModel.get('show');
 
-    labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();
-};
+        labelLine.ignore = (labelLine as ExtendedDisplayable).normalIgnore = !labelLineModel.get('show');
+        (labelLine as ExtendedDisplayable).hoverIgnore = !labelLineHoverModel.get('show');
 
-zrUtil.inherits(FunnelPiece, graphic.Group);
+        // Default use item visual color
+        labelLine.setStyle({
+            stroke: visualColor
+        });
+        labelLine.setStyle(labelLineModel.getModel('lineStyle').getLineStyle());
 
+        labelLine.hoverStyle = labelLineHoverModel.getModel('lineStyle').getLineStyle();
+    }
+}
 
-var FunnelView = ChartView.extend({
+class FunnelView extends ChartView {
+    static type = 'funnel' as const
+    type = FunnelView.type
 
-    type: 'funnel',
+    private _data: List
 
-    render: function (seriesModel, ecModel, api) {
+    render(seriesModel: FunnelSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
         var data = seriesModel.getData();
         var oldData = this._data;
 
@@ -198,28 +209,31 @@ var FunnelView = ChartView.extend({
                 group.add(funnelPiece);
             })
             .update(function (newIdx, oldIdx) {
-                var piePiece = oldData.getItemGraphicEl(oldIdx);
+                var piece = oldData.getItemGraphicEl(oldIdx) as FunnelPiece;
 
-                piePiece.updateData(data, newIdx);
+                piece.updateData(data, newIdx);
 
-                group.add(piePiece);
-                data.setItemGraphicEl(newIdx, piePiece);
+                group.add(piece);
+                data.setItemGraphicEl(newIdx, piece);
             })
             .remove(function (idx) {
-                var piePiece = oldData.getItemGraphicEl(idx);
-                group.remove(piePiece);
+                var piece = oldData.getItemGraphicEl(idx);
+                group.remove(piece);
             })
             .execute();
 
         this._data = data;
-    },
+    }
 
-    remove: function () {
+    remove() {
         this.group.removeAll();
         this._data = null;
-    },
+    }
+
+    dispose() {}
+}
+
+ChartView.registerClass(FunnelView);
 
-    dispose: function () {}
-});
 
 export default FunnelView;
\ No newline at end of file
diff --git a/src/chart/funnel/funnelLayout.ts b/src/chart/funnel/funnelLayout.ts
index 89b0992..6b4e0c6 100644
--- a/src/chart/funnel/funnelLayout.ts
+++ b/src/chart/funnel/funnelLayout.ts
@@ -17,12 +17,17 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import * as layout from '../../util/layout';
 import {parsePercent, linearMap} from '../../util/number';
+import FunnelSeriesModel, { FunnelSeriesOption } from './FunnelSeries';
+import ExtensionAPI from '../../ExtensionAPI';
+import List from '../../data/List';
+import Model from '../../model/Model';
+import GlobalModel from '../../model/Global';
+
+type FunnelDataItem = FunnelSeriesOption['data'][number] & object;
 
-function getViewRect(seriesModel, api) {
+function getViewRect(seriesModel: FunnelSeriesModel, api: ExtensionAPI) {
     return layout.getLayoutRect(
         seriesModel.getBoxLayoutParams(), {
             width: api.getWidth(),
@@ -31,7 +36,7 @@ function getViewRect(seriesModel, api) {
     );
 }
 
-function getSortedIndices(data, sort) {
+function getSortedIndices(data: List, sort: FunnelSeriesOption['sort']) {
     var valueDim = data.mapDimension('value');
     var valueArr = data.mapArray(valueDim, function (val) {
         return val;
@@ -54,9 +59,9 @@ function getSortedIndices(data, sort) {
     return indices;
 }
 
-function labelLayout(data) {
+function labelLayout(data: List) {
     data.each(function (idx) {
-        var itemModel = data.getItemModel(idx);
+        var itemModel = data.getItemModel(idx) as Model<FunnelDataItem>;
         var labelModel = itemModel.getModel('label');
         var labelPosition = labelModel.get('position');
 
@@ -172,8 +177,8 @@ function labelLayout(data) {
     });
 }
 
-export default function (ecModel, api, payload) {
-    ecModel.eachSeriesByType('funnel', function (seriesModel) {
+export default function (ecModel: GlobalModel, api: ExtensionAPI) {
+    ecModel.eachSeriesByType('funnel', function (seriesModel: FunnelSeriesModel) {
         var data = seriesModel.getData();
         var valueDim = data.mapDimension('value');
         var sort = seriesModel.get('sort');
@@ -200,9 +205,9 @@ export default function (ecModel, api, payload) {
 
         var y = viewRect.y;
 
-        var getLinePoints = function (idx, offY) {
+        var getLinePoints = function (idx: number, offY: number) {
             // End point index is data.count() and we assign it 0
-            var val = data.get(valueDim, idx) || 0;
+            var val = data.get(valueDim, idx) as number || 0;
             var itemWidth = linearMap(val, [min, max], sizeExtent, true);
             var x0;
             switch (funnelAlign) {
diff --git a/src/chart/gauge/GaugeSeries.ts b/src/chart/gauge/GaugeSeries.ts
index 1638dc5..b2ec67b 100644
--- a/src/chart/gauge/GaugeSeries.ts
+++ b/src/chart/gauge/GaugeSeries.ts
@@ -17,20 +17,111 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import createListSimply from '../helper/createListSimply';
 import SeriesModel from '../../model/Series';
+import {
+    SeriesOption,
+    CircleLayoutOptionMixin,
+    LineStyleOption,
+    ColorString,
+    LabelOption,
+    ItemStyleOption,
+    OptionDataValueNumeric
+} from '../../util/types';
+import GlobalModel from '../../model/Global';
+import List from '../../data/List';
 
-var GaugeSeries = SeriesModel.extend({
+// [percent, color]
+type GaugeColorStop = [number, ColorString];
 
-    type: 'series.gauge',
+interface LabelFormatter {
+    (value: number): string
+}
+export interface GaugeSeriesOption extends SeriesOption, CircleLayoutOptionMixin {
 
-    getInitialData: function (option, ecModel) {
-        return createListSimply(this, ['value']);
+    // override radius
+    radius?: number | string
+
+    startAngle?: number
+    endAngle?: number
+    clockwise?: boolean
+
+    min?: number
+    max?: number
+
+    splitNumber?: number
+
+    axisLine?: {
+        show?: boolean
+        lineStyle: Omit<LineStyleOption, 'color'> & {
+            color: GaugeColorStop[]
+        }
     },
 
-    defaultOption: {
+    splitLine?: {
+        show?: boolean
+        /**
+         * Can be percent
+         */
+        length?: number
+        lineStyle?: LineStyleOption
+    }
+
+    axisTick?: {
+        show?: boolean
+        splitNumber?: number
+        /**
+         * Can be percent
+         */
+        length?: number | string
+        lineStyle?: LineStyleOption
+    }
+
+    axisLabel?: LabelOption & {
+        formatter?: LabelFormatter | string
+    }
+
+    pointer?: {
+        show?: boolean
+        /**
+         * Can be percent
+         */
+        length?: number | string
+        width?: number
+    }
+    itemStyle?: ItemStyleOption
+
+    title?: LabelOption & {
+        /**
+         * [x, y] offset
+         */
+        offsetCenter?: (number | string)[]
+        formatter?: LabelFormatter | string
+    }
+    detail?: LabelOption & {
+        /**
+         * [x, y] offset
+         */
+        offsetCenter?: (number | string)[]
+        formatter?: LabelFormatter | string
+    }
+
+    data?: OptionDataValueNumeric | {
+        name?: string
+        value?: OptionDataValueNumeric
+    }
+}
+
+class GaugeSeriesModel extends SeriesModel<GaugeSeriesOption> {
+
+    static type = 'series.gauge' as const
+    type = GaugeSeriesModel.type
+
+    getInitialData(option: GaugeSeriesOption, ecModel: GlobalModel): List {
+        return createListSimply(this, ['value']);
+    }
+
+    static defaultOption: GaugeSeriesOption = {
         zlevel: 0,
         z: 2,
         // 默认全局居中
@@ -121,6 +212,9 @@ var GaugeSeries = SeriesModel.extend({
             fontSize: 30
         }
     }
-});
+}
+
+SeriesModel.registerClass(GaugeSeriesModel);
+
 
-export default GaugeSeries;
\ No newline at end of file
+export default GaugeSeriesModel;
\ No newline at end of file
diff --git a/src/chart/gauge/GaugeView.ts b/src/chart/gauge/GaugeView.ts
index aa520dc..56cf113 100644
--- a/src/chart/gauge/GaugeView.ts
+++ b/src/chart/gauge/GaugeView.ts
@@ -17,14 +17,23 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import PointerPath from './PointerPath';
 import * as graphic from '../../util/graphic';
 import ChartView from '../../view/Chart';
 import {parsePercent, round, linearMap} from '../../util/number';
+import GaugeSeriesModel from './GaugeSeries';
+import GlobalModel from '../../model/Global';
+import ExtensionAPI from '../../ExtensionAPI';
+import { ColorString } from '../../util/types';
+import List from '../../data/List';
+
+interface PosInfo {
+    cx: number
+    cy: number
+    r: number
+}
 
-function parsePosition(seriesModel, api) {
+function parsePosition(seriesModel: GaugeSeriesModel, api: ExtensionAPI): PosInfo {
     var center = seriesModel.get('center');
     var width = api.getWidth();
     var height = api.getHeight();
@@ -40,13 +49,14 @@ function parsePosition(seriesModel, api) {
     };
 }
 
-function formatLabel(label, labelFormatter) {
+function formatLabel(value: number, labelFormatter: string | ((value: number) => string)): string {
+    let label = value + '';
     if (labelFormatter) {
         if (typeof labelFormatter === 'string') {
-            label = labelFormatter.replace('{value}', label != null ? label : '');
+            label = labelFormatter.replace('{value}', value != null ? value + '' : '');
         }
         else if (typeof labelFormatter === 'function') {
-            label = labelFormatter(label);
+            label = labelFormatter(value);
         }
     }
 
@@ -55,25 +65,33 @@ function formatLabel(label, labelFormatter) {
 
 var PI2 = Math.PI * 2;
 
-var GaugeView = ChartView.extend({
+class GaugeView extends ChartView {
+    static type = 'gauge' as const
+    type = GaugeView.type
 
-    type: 'gauge',
+    private _data: List
 
-    render: function (seriesModel, ecModel, api) {
+    render(seriesModel: GaugeSeriesModel, ecModel: GlobalModel, api: ExtensionAPI) {
 
         this.group.removeAll();
 
-        var colorList = seriesModel.get('axisLine.lineStyle.color');
+        var colorList = seriesModel.get(['axisLine', 'lineStyle', 'color']);
         var posInfo = parsePosition(seriesModel, api);
 
         this._renderMain(
             seriesModel, ecModel, api, colorList, posInfo
         );
-    },
+    }
 
-    dispose: function () {},
+    dispose() {}
 
-    _renderMain: function (seriesModel, ecModel, api, colorList, posInfo) {
+    _renderMain(
+        seriesModel: GaugeSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        colorList: [number, ColorString][],
+        posInfo: PosInfo
+    ) {
         var group = this.group;
 
         var axisLineModel = seriesModel.getModel('axisLine');
@@ -121,7 +139,7 @@ var GaugeView = ChartView.extend({
             prevEndAngle = endAngle;
         }
 
-        var getColor = function (percent) {
+        var getColor = function (percent: number) {
             // Less than 0
             if (percent <= 0) {
                 return colorList[0][1];
@@ -159,11 +177,17 @@ var GaugeView = ChartView.extend({
         this._renderDetail(
             seriesModel, ecModel, api, getColor, posInfo
         );
-    },
+    }
 
-    _renderTicks: function (
-        seriesModel, ecModel, api, getColor, posInfo,
-        startAngle, endAngle, clockwise
+    _renderTicks(
+        seriesModel: GaugeSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        getColor: (percent: number) => ColorString,
+        posInfo: PosInfo,
+        startAngle: number,
+        endAngle: number,
+        clockwise: boolean
     ) {
         var group = this.group;
         var cx = posInfo.cx;
@@ -270,17 +294,23 @@ var GaugeView = ChartView.extend({
                 angle += step;
             }
         }
-    },
+    }
 
-    _renderPointer: function (
-        seriesModel, ecModel, api, getColor, posInfo,
-        startAngle, endAngle, clockwise
+    _renderPointer(
+        seriesModel: GaugeSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        getColor: (percent: number) => ColorString,
+        posInfo: PosInfo,
+        startAngle: number,
+        endAngle: number,
+        clockwise: boolean
     ) {
 
         var group = this.group;
         var oldData = this._data;
 
-        if (!seriesModel.get('pointer.show')) {
+        if (!seriesModel.get(['pointer', 'show'])) {
             // Remove old element
             oldData && oldData.eachItemGraphicEl(function (el) {
                 group.remove(el);
@@ -304,7 +334,7 @@ var GaugeView = ChartView.extend({
 
                 graphic.initProps(pointer, {
                     shape: {
-                        angle: linearMap(data.get(valueDim, idx), valueExtent, angleExtent, true)
+                        angle: linearMap(data.get(valueDim, idx) as number, valueExtent, angleExtent, true)
                     }
                 }, seriesModel);
 
@@ -312,11 +342,11 @@ var GaugeView = ChartView.extend({
                 data.setItemGraphicEl(idx, pointer);
             })
             .update(function (newIdx, oldIdx) {
-                var pointer = oldData.getItemGraphicEl(oldIdx);
+                var pointer = oldData.getItemGraphicEl(oldIdx) as PointerPath;
 
                 graphic.updateProps(pointer, {
                     shape: {
-                        angle: linearMap(data.get(valueDim, newIdx), valueExtent, angleExtent, true)
+                        angle: linearMap(data.get(valueDim, newIdx) as number, valueExtent, angleExtent, true)
                     }
                 }, seriesModel);
 
@@ -329,7 +359,7 @@ var GaugeView = ChartView.extend({
             })
             .execute();
 
-        data.eachItemGraphicEl(function (pointer, idx) {
+        data.eachItemGraphicEl(function (pointer: PointerPath, idx) {
             var itemModel = data.getItemModel(idx);
             var pointerModel = itemModel.getModel('pointer');
 
@@ -346,7 +376,7 @@ var GaugeView = ChartView.extend({
 
             if (pointer.style.fill === 'auto') {
                 pointer.setStyle('fill', getColor(
-                    linearMap(data.get(valueDim, idx), valueExtent, [0, 1], true)
+                    linearMap(data.get(valueDim, idx) as number, valueExtent, [0, 1], true)
                 ));
             }
 
@@ -356,10 +386,14 @@ var GaugeView = ChartView.extend({
         });
 
         this._data = data;
-    },
+    }
 
-    _renderTitle: function (
-        seriesModel, ecModel, api, getColor, posInfo
+    _renderTitle(
+        seriesModel: GaugeSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        getColor: (percent: number) => ColorString,
+        posInfo: PosInfo
     ) {
         var data = seriesModel.getData();
         var valueDim = data.mapDimension('value');
@@ -371,7 +405,7 @@ var GaugeView = ChartView.extend({
 
             var minVal = +seriesModel.get('min');
             var maxVal = +seriesModel.get('max');
-            var value = seriesModel.getData().get(valueDim, 0);
+            var value = seriesModel.getData().get(valueDim, 0) as number;
             var autoColor = getColor(
                 linearMap(value, [minVal, maxVal], [0, 1], true)
             );
@@ -388,10 +422,14 @@ var GaugeView = ChartView.extend({
                 }, {autoColor: autoColor, forceRich: true})
             }));
         }
-    },
+    }
 
-    _renderDetail: function (
-        seriesModel, ecModel, api, getColor, posInfo
+    _renderDetail(
+        seriesModel: GaugeSeriesModel,
+        ecModel: GlobalModel,
+        api: ExtensionAPI,
+        getColor: (percent: number) => ColorString,
+        posInfo: PosInfo
     ) {
         var detailModel = seriesModel.getModel('detail');
         var minVal = +seriesModel.get('min');
@@ -403,7 +441,7 @@ var GaugeView = ChartView.extend({
             var width = parsePercent(detailModel.get('width'), posInfo.r);
             var height = parsePercent(detailModel.get('height'), posInfo.r);
             var data = seriesModel.getData();
-            var value = data.get(data.mapDimension('value'), 0);
+            var value = data.get(data.mapDimension('value'), 0) as number;
             var autoColor = getColor(
                 linearMap(value, [minVal, maxVal], [0, 1], true)
             );
@@ -425,6 +463,6 @@ var GaugeView = ChartView.extend({
             }));
         }
     }
-});
+}
 
 export default GaugeView;
diff --git a/src/chart/gauge/PointerPath.ts b/src/chart/gauge/PointerPath.ts
index c541577..7c2ad62 100644
--- a/src/chart/gauge/PointerPath.ts
+++ b/src/chart/gauge/PointerPath.ts
@@ -17,27 +17,31 @@
 * under the License.
 */
 
-// @ts-nocheck
+import Path, { PathProps } from 'zrender/src/graphic/Path';
 
-import Path from 'zrender/src/graphic/Path';
+class PointerShape {
+    angle = 0
+    width = 10
+    r = 10
+    x = 0
+    y = 0
+}
 
-export default Path.extend({
+interface PointerPathProps extends PathProps {
+    shape?: Partial<PointerShape>
+}
 
-    type: 'echartsGaugePointer',
+export default class PointerPath extends Path<PointerPathProps> {
 
-    shape: {
-        angle: 0,
+    type = 'pointer'
 
-        width: 10,
+    shape: PointerShape
 
-        r: 10,
-
-        x: 0,
-
-        y: 0
-    },
+    constructor(opts?: PointerPathProps) {
+        super(opts, null, new PointerShape());
+    }
 
-    buildPath: function (ctx, shape) {
+    buildPath(ctx: CanvasRenderingContext2D, shape: PointerShape) {
         var mathCos = Math.cos;
         var mathSin = Math.sin;
 
@@ -62,6 +66,5 @@ export default Path.extend({
             shape.y - mathSin(angle) * width
         );
         ctx.lineTo(x, y);
-        return;
     }
-});
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/chart/pie/PieSeries.ts b/src/chart/pie/PieSeries.ts
index b384301..d3cb9d0 100644
--- a/src/chart/pie/PieSeries.ts
+++ b/src/chart/pie/PieSeries.ts
@@ -33,7 +33,8 @@ import {
     LabelLineOption,
     ItemStyleOption,
     LabelOption,
-    BoxLayoutOptionMixin
+    BoxLayoutOptionMixin,
+    OptionDataValueNumeric
 } from '../../util/types';
 import List from '../../data/List';
 
@@ -46,6 +47,10 @@ interface PieLabelOption extends LabelOption {
 }
 
 interface PieDataItem {
+    name?: string
+
+    value?: OptionDataValueNumeric
+
     itemStyle?: ItemStyleOption
     label?: PieLabelOption
     labelLine?: LabelLineOption
@@ -95,10 +100,10 @@ export interface PieSeriesOption extends
     animationType?: 'expansion' | 'scale'
     animationTypeUpdate?: 'transition' | 'expansion'
 
-    data?: number[] | PieDataItem[]
+    data?: OptionDataValueNumeric[] | PieDataItem[]
 }
 
-class PieSeries extends SeriesModel<PieSeriesOption> {
+class PieSeriesModel extends SeriesModel<PieSeriesOption> {
 
     static type = 'series.pie' as const;
 
@@ -281,9 +286,9 @@ class PieSeries extends SeriesModel<PieSeriesOption> {
 
 }
 
-interface PieSeries extends DataSelectableMixin<PieSeriesOption> {}
-zrUtil.mixin(PieSeries, DataSelectableMixin);
+interface PieSeriesModel extends DataSelectableMixin<PieSeriesOption> {}
+zrUtil.mixin(PieSeriesModel, DataSelectableMixin);
 
-SeriesModel.registerClass(PieSeries);
+SeriesModel.registerClass(PieSeriesModel);
 
-export default PieSeries;
+export default PieSeriesModel;
diff --git a/src/chart/pie/PieView.ts b/src/chart/pie/PieView.ts
index 60ae5d7..6ef91fd 100644
--- a/src/chart/pie/PieView.ts
+++ b/src/chart/pie/PieView.ts
@@ -26,14 +26,14 @@ 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 PieSeriesModel from './PieSeries';
 import { Dictionary } from 'zrender/src/core/types';
 import Element from 'zrender/src/Element';
 
 function updateDataSelected(
     this: PiePiece,
     uid: string,
-    seriesModel: PieSeries,
+    seriesModel: PieSeriesModel,
     hasAnimation: boolean,
     api: ExtensionAPI
 ): void {
@@ -120,7 +120,7 @@ class PiePiece extends graphic.Group {
         var labelLine = this.childAt(1) as PieceElementExtension;
         var labelText = this.childAt(2) as PieceElementExtension;
 
-        var seriesModel = data.hostModel as PieSeries;
+        var seriesModel = data.hostModel as PieSeriesModel;
         var itemModel = data.getItemModel(idx);
         var layout = data.getItemLayout(idx) as graphic.Sector['shape'];
         var sectorShape = zrUtil.extend({
@@ -293,7 +293,7 @@ class PiePiece extends graphic.Group {
             labelModel,
             labelHoverModel,
             {
-                labelFetcher: data.hostModel as PieSeries,
+                labelFetcher: data.hostModel as PieSeriesModel,
                 labelDataIndex: idx,
                 defaultText: labelLayout.text,
                 autoColor: visualColor,
@@ -345,7 +345,7 @@ class PieView extends ChartView {
         this._sectorGroup = sectorGroup;
     }
 
-    render(seriesModel: PieSeries, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload): void {
+    render(seriesModel: PieSeriesModel, ecModel: GlobalModel, api: ExtensionAPI, payload: Payload): void {
         if (payload && (payload.from === this.uid)) {
             return;
         }
@@ -433,7 +433,7 @@ class PieView extends ChartView {
         startAngle: number, clockwise: boolean,
         // @ts-ignore FIXME:TS make type in util.grpahic
         cb,
-        seriesModel: PieSeries, isFirstRender: boolean
+        seriesModel: PieSeriesModel, isFirstRender: boolean
     ): graphic.Sector {
         var clipPath = new graphic.Sector({
             shape: {
@@ -460,7 +460,7 @@ class PieView extends ChartView {
     /**
      * @implements
      */
-    containPoint = function (point: number[], seriesModel: PieSeries): boolean {
+    containPoint = function (point: number[], seriesModel: PieSeriesModel): boolean {
         var data = seriesModel.getData();
         var itemLayout = data.getItemLayout(0);
         if (itemLayout) {
diff --git a/src/chart/pie/labelLayout.ts b/src/chart/pie/labelLayout.ts
index 836e710..b9b7e84 100644
--- a/src/chart/pie/labelLayout.ts
+++ b/src/chart/pie/labelLayout.ts
@@ -21,7 +21,7 @@
 
 import * as textContain from 'zrender/src/contain/text';
 import {parsePercent} from '../../util/number';
-import PieSeries, { PieSeriesOption } from './PieSeries';
+import PieSeriesModel, { PieSeriesOption } from './PieSeries';
 import { VectorArray } from 'zrender/src/core/vector';
 import { ZRAlign, ZRVerticalAlign, ZRRectLike } from '../../util/types';
 
@@ -270,7 +270,7 @@ function isPositionCenter(layout: LabelLayout) {
 }
 
 export default function (
-    seriesModel: PieSeries,
+    seriesModel: PieSeriesModel,
     r: number,
     viewWidth: number,
     viewHeight: number,
diff --git a/src/chart/pie/pieLayout.ts b/src/chart/pie/pieLayout.ts
index a96306e..9692fc2 100644
--- a/src/chart/pie/pieLayout.ts
+++ b/src/chart/pie/pieLayout.ts
@@ -23,12 +23,12 @@ import labelLayout from './labelLayout';
 import * as zrUtil from 'zrender/src/core/util';
 import GlobalModel from '../../model/Global';
 import ExtensionAPI from '../../ExtensionAPI';
-import PieSeries from './PieSeries';
+import PieSeriesModel from './PieSeries';
 
 var PI2 = Math.PI * 2;
 var RADIAN = Math.PI / 180;
 
-function getViewRect(seriesModel: PieSeries, api: ExtensionAPI) {
+function getViewRect(seriesModel: PieSeriesModel, api: ExtensionAPI) {
     return layout.getLayoutRect(
         seriesModel.getBoxLayoutParams(), {
             width: api.getWidth(),
@@ -42,7 +42,7 @@ export default function (
     ecModel: GlobalModel,
     api: ExtensionAPI
 ) {
-    ecModel.eachSeriesByType(seriesType, function (seriesModel: PieSeries) {
+    ecModel.eachSeriesByType(seriesType, function (seriesModel: PieSeriesModel) {
         var data = seriesModel.getData();
         var valueDim = data.mapDimension('value');
         var viewRect = getViewRect(seriesModel, api);
diff --git a/src/component/axisPointer/AxisPointerModel.ts b/src/component/axisPointer/AxisPointerModel.ts
index 5afa5d6..dae81f0 100644
--- a/src/component/axisPointer/AxisPointerModel.ts
+++ b/src/component/axisPointer/AxisPointerModel.ts
@@ -26,7 +26,8 @@ import {
     LabelOption,
     ZREasing,
     ColorString,
-    ShadowOptionMixin
+    ShadowOptionMixin,
+    CallbackDataParams
 } from '../../util/types';
 
 interface AxisInfo {
@@ -61,6 +62,23 @@ interface AxisPointerLink {
     ): OptionDataValue
 }
 
+type LabelFormatterParmas = Pick<CallbackDataParams,
+    'componentType'
+    | 'componentSubType'
+    | 'componentIndex'
+    | 'seriesType'
+    | 'seriesIndex'
+    | 'seriesId'
+    | 'seriesName'
+    | 'name'
+    | 'dataIndex'
+    | 'data'
+    | 'dataType'
+    | 'value'
+    | 'dimensionNames'
+    | 'dimensionIndex'
+>
+
 export interface AxisPointerOption extends ComponentOption {
 
     show?: boolean | 'auto'
@@ -96,6 +114,10 @@ export interface AxisPointerOption extends ComponentOption {
     label?: LabelOption & {
         precision?: 'auto' | string
         margin?: number
+        /**
+         * String template include variable {value} or callback function
+         */
+        formatter?: string | ((params: LabelFormatterParmas) => string)
     }
     animation?: boolean | 'auto'
     animationDurationUpdate?: number
diff --git a/src/data/List.ts b/src/data/List.ts
index aef3324..12bfee8 100644
--- a/src/data/List.ts
+++ b/src/data/List.ts
@@ -1555,6 +1555,7 @@ class List <HostModel extends Model = Model> {
     /**
      * Get model of one data item.
      */
+    // TODO: Type of data item
     getItemModel(idx: number): Model {
         var hostModel = this.hostModel;
         var dataItem = this.getRawDataItem(idx) as ModelOption;
diff --git a/src/model/Model.ts b/src/model/Model.ts
index 9f2d70f..04cf072 100644
--- a/src/model/Model.ts
+++ b/src/model/Model.ts
@@ -31,8 +31,8 @@ import {
     CheckableConstructor
 } from '../util/clazz';
 
-import areaStyleMixin from './mixin/areaStyle';
-import textStyleMixin from './mixin/textStyle';
+import {AreaStyleMixin} from './mixin/areaStyle';
+import TextStyleMixin from './mixin/textStyle';
 import {LineStyleMixin} from './mixin/lineStyle';
 import {ItemStyleMixin} from './mixin/itemStyle';
 import GlobalModel from './Global';
@@ -263,10 +263,10 @@ type ModelConstructor = typeof Model
 enableClassExtend(Model as ModelConstructor);
 enableClassCheck(Model as ModelConstructor);
 
-interface Model extends LineStyleMixin, ItemStyleMixin, textStyleMixin {}
+interface Model extends LineStyleMixin, ItemStyleMixin, TextStyleMixin {}
 mixin(Model, LineStyleMixin);
 mixin(Model, ItemStyleMixin);
-mixin(Model, areaStyleMixin);
-mixin(Model, textStyleMixin);
+mixin(Model, AreaStyleMixin);
+mixin(Model, TextStyleMixin);
 
 export default Model;
diff --git a/src/model/mixin/areaStyle.ts b/src/model/mixin/areaStyle.ts
index 40caadf..4d1f63e 100644
--- a/src/model/mixin/areaStyle.ts
+++ b/src/model/mixin/areaStyle.ts
@@ -17,23 +17,32 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 import makeStyleMapper from './makeStyleMapper';
+import { StyleProps } from 'zrender/src/graphic/Style';
+import Model from '../Model';
+
+var getAreaStyle = makeStyleMapper([
+    ['fill', 'color'],
+    ['shadowBlur'],
+    ['shadowOffsetX'],
+    ['shadowOffsetY'],
+    ['opacity'],
+    ['shadowColor']
+]);
 
-var getAreaStyle = makeStyleMapper(
-    [
-        ['fill', 'color'],
-        ['shadowBlur'],
-        ['shadowOffsetX'],
-        ['shadowOffsetY'],
-        ['opacity'],
-        ['shadowColor']
-    ]
-);
+type AreaStyleProps = Pick<StyleProps,
+    'fill'
+    | 'shadowBlur'
+    | 'shadowOffsetX'
+    | 'shadowOffsetY'
+    | 'opacity'
+    | 'shadowColor'
+>
 
-export default {
-    getAreaStyle: function (excludes, includes) {
+class AreaStyleMixin {
+    getAreaStyle(this: Model, excludes?: string[], includes?: string[]): AreaStyleProps {
         return getAreaStyle(this, excludes, includes);
     }
-};
\ No newline at end of file
+};
+
+export {AreaStyleMixin};
diff --git a/src/model/mixin/itemStyle.ts b/src/model/mixin/itemStyle.ts
index ee31de2..ccf5fc5 100644
--- a/src/model/mixin/itemStyle.ts
+++ b/src/model/mixin/itemStyle.ts
@@ -21,7 +21,7 @@ import makeStyleMapper from './makeStyleMapper';
 import Model from '../Model';
 import { StyleProps } from 'zrender/src/graphic/Style';
 
-const STYLE_LIST = [
+var getItemStyle = makeStyleMapper([
     ['fill', 'color'],
     ['stroke', 'borderColor'],
     ['lineWidth', 'borderWidth'],
@@ -32,25 +32,31 @@ const STYLE_LIST = [
     ['shadowColor'],
     ['textPosition'],
     ['textAlign']
-] as const;
-var getItemStyle = makeStyleMapper(STYLE_LIST);
+]);
 
-interface ItemStyleMixin extends Pick<Model, 'get'> {}
-
-type ItemStyleProps = Pick<
-    StyleProps, typeof STYLE_LIST[number][0]
+type ItemStyleProps = Pick<StyleProps,
+    'fill'
+    | 'stroke'
+    | 'lineWidth'
+    | 'opacity'
+    | 'shadowBlur'
+    | 'shadowOffsetX'
+    | 'shadowOffsetY'
+    | 'shadowColor'
+    | 'textPosition'
+    | 'textAlign'
 >
 
 class ItemStyleMixin {
 
-    getItemStyle(excludes?: string[], includes?: string[]): ItemStyleProps {
+    getItemStyle(this: Model, excludes?: string[], includes?: string[]): ItemStyleProps {
         var style = getItemStyle(this, excludes, includes);
         var lineDash = this.getBorderLineDash();
         lineDash && ((style as any).lineDash = lineDash);
         return style;
     }
 
-    getBorderLineDash(): number[] {
+    getBorderLineDash(this: Model): number[] {
         var lineType = this.get('borderType');
         return (lineType === 'solid' || lineType == null) ? null
             : (lineType === 'dashed' ? [5, 5] : [1, 1]);
diff --git a/src/model/mixin/lineStyle.ts b/src/model/mixin/lineStyle.ts
index 3a0c8cb..cb28c3d 100644
--- a/src/model/mixin/lineStyle.ts
+++ b/src/model/mixin/lineStyle.ts
@@ -19,24 +19,31 @@
 
 import makeStyleMapper from './makeStyleMapper';
 import Model from '../Model';
+import { StyleProps } from 'zrender/src/graphic/Style';
 
-var getLineStyle = makeStyleMapper(
-    [
-        ['lineWidth', 'width'],
-        ['stroke', 'color'],
-        ['opacity'],
-        ['shadowBlur'],
-        ['shadowOffsetX'],
-        ['shadowOffsetY'],
-        ['shadowColor']
-    ]
-);
+var getLineStyle = makeStyleMapper([
+    ['lineWidth', 'width'],
+    ['stroke', 'color'],
+    ['opacity'],
+    ['shadowBlur'],
+    ['shadowOffsetX'],
+    ['shadowOffsetY'],
+    ['shadowColor']
+]);
 
-interface LineStyleMixin extends Pick<Model, 'get'> {}
+type LineStyleProps = Pick<StyleProps,
+    'lineWidth'
+    | 'stroke'
+    | 'opacity'
+    | 'shadowBlur'
+    | 'shadowOffsetX'
+    | 'shadowOffsetY'
+    | 'shadowColor'
+>
 
 class LineStyleMixin {
 
-    getLineStyle(excludes?: string[]) {
+    getLineStyle(this: Model, excludes?: string[]): LineStyleProps {
         var style = getLineStyle(this, excludes);
         // Always set lineDash whether dashed, otherwise we can not
         // erase the previous style when assigning to el.style.
@@ -44,7 +51,7 @@ class LineStyleMixin {
         return style;
     }
 
-    getLineDash(lineWidth?: number) {
+    getLineDash(this: Model, lineWidth?: number) {
         if (lineWidth == null) {
             lineWidth = 1;
         }
diff --git a/src/model/mixin/makeStyleMapper.ts b/src/model/mixin/makeStyleMapper.ts
index e7de475..ff1b2e3 100644
--- a/src/model/mixin/makeStyleMapper.ts
+++ b/src/model/mixin/makeStyleMapper.ts
@@ -17,21 +17,21 @@
 * under the License.
 */
 
-// @ts-nocheck
-
 // TODO Parse shadow style
 // TODO Only shallow path support
 import * as zrUtil from 'zrender/src/core/util';
+import Model from '../Model';
+import { Dictionary } from 'zrender/src/core/types';
 
-export default function (properties) {
+export default function (properties: readonly string[][]) {
     // Normalize
     for (var i = 0; i < properties.length; i++) {
         if (!properties[i][1]) {
             properties[i][1] = properties[i][0];
         }
     }
-    return function (model, excludes, includes?) {
-        var style = {};
+    return function (model: Model, excludes: string[], includes?: string[]) {
+        var style: Dictionary<any> = {};
         for (var i = 0; i < properties.length; i++) {
             var propName = properties[i][1];
             if ((excludes && zrUtil.indexOf(excludes, propName) >= 0)
diff --git a/src/model/mixin/textStyle.ts b/src/model/mixin/textStyle.ts
index 6235923..d350fe3 100644
--- a/src/model/mixin/textStyle.ts
+++ b/src/model/mixin/textStyle.ts
@@ -20,17 +20,15 @@
 import * as textContain from 'zrender/src/contain/text';
 import * as graphicUtil from '../../util/graphic';
 import Model from '../Model';
-import { LabelOption } from '../../util/types';
+import { LabelOption, ColorString } from '../../util/types';
 
 var PATH_COLOR = ['textStyle', 'color'] as const;
 
 class TextStyleMixin {
     /**
      * Get color property or get color from option.textStyle.color
-     * @param {boolean} [isEmphasis]
-     * @return {string}
      */
-    getTextColor(this: Model, isEmphasis?: boolean) {
+    getTextColor(this: Model, isEmphasis?: boolean): ColorString {
         var ecModel = this.ecModel;
         return this.getShallow('color')
             || (
diff --git a/src/util/types.ts b/src/util/types.ts
index 02a2464..90c6490 100644
--- a/src/util/types.ts
+++ b/src/util/types.ts
@@ -405,6 +405,10 @@ export type OptionDataItem =
     | {value: ArrayLike<OptionDataValue>}; // Only for `SOURCE_FORMAT_KEYED_ORIGINAL`
 export type OptionDataValue = string | number | Date;
 
+export type OptionDataValueNumeric = number | '-';
+export type OptionDataValueCategory = string;
+export type OptionDataValueDate = Date;
+
 // export type ModelOption = Dictionary<any> | any[] | string | number | boolean | ((...args: any) => any);
 export type ModelOption = any;
 export type ThemeOption = Dictionary<any>;
@@ -721,7 +725,9 @@ export interface LabelOption extends TextCommonOption {
     distance?: number
     rotate?: number | boolean
     offset?: number[]
-    formatter?: string | ((params: CallbackDataParams) => string)
+
+    // TODO: TYPE not all label support formatter
+    // formatter?: string | ((params: CallbackDataParams) => string)
 
     rich?: Dictionary<TextCommonOption>
 }


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