diff --git a/src/chart/helper/createListSimply.ts b/src/chart/helper/createListSimply.ts index c3f7be2c245a93fdcf82c6e32e426fdb591b7690..92c66125f6da7447ca7ae17a4889145f8fb91c94 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.} opt opt or coordDimensions - * The options in opt, see `echarts/data/helper/createDimensions` - * @param {Array.} [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 6bc864b6a4ab79eb9189901a5d13e1fc381a2b0a..a1f4b8c61cf2a4ea86c286d22fe9297b47aa1099 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 1a1697b25289e31d0c4a4d02c0e547c642ee7f06..8d445237a2cd27c3dffd0e923d1f076b05c5fef2 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 68d1f92a04cff66062d8cbbad99a91e3c6853bee..1d9c350fbbb49937a5c004c8b60dfd7e96bc83f8 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, // 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 7f4db3d0f55319b287477007ad4e4c69cd677b0e..9ca7a61eb2b2afc633dc8468fce873336ce9790d 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 {}; + +class DataSelectableMixin { + + private _targetList: SelectableTarget[]; + + // Key: target.name + private _selectTargetMap: zrUtil.HashMap; -export default { /** - * @param {Array.} 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 341c422cac8c8feea66c2199a2c48f73d79f68bc..4f9361cf3cae2a00dc3d59697be9c66d0527a11a 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 f9d7ac1ee9f51ad519c71a6295d6dde0ec32f616..7344dbe65efea3df053d2b8fa0c8b841c8fc0a5d 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( - 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 e159c7782939423875c3aa166c38ee9b0ee74549..ae187f3a51180731d8818d26578b367345d6e5d5 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 | 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.} [opt.coordDimensions=[]] - * @param {number} [opt.dimensionsCount] - * @param {string} [opt.generateCoord] - * @param {string} [opt.generateCoordCount] - * @param {Array.} [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.} 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 1db36ed0d85f5739482e557814ae885590383f6a..7a3fb17a71faa7c1fe80ab365fa2e96997f43ef7 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 32fc419d74915d6d8eb1093c508e52c2660ef531..57dbdc2780f989f9eb6631401cab074e396a0922 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 0a5ebebde3bbd227b324083daf4bca3add15bc7b..2e38e1fff023173096449d1ea0ea0af34dfb6496 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 41eb447411f5a0f83263309925277bd19997012e..b4d3a0516798595fc0fbafaa6edce71540783db0 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 3f7e32d9cf270531181c71bd9131e44f802e3aee..f65cebcf0bc7d6058cfd491734279b75b89a4a57 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 0f64d530ac133b6b4305372974eb5334f4f8ea12..4191a1a5e0ffdd7f67e98eff6754ca6e9527181a 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 b53daf15bd09c493e5cbb3ae5061ca42b9945ff0..3e721590e3c32c639b5dd48cd82e7beec29a4509 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 {} 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 c337cb863e47bfd62b08ef8407e604c1fc770c4c..3c3b28343b7dbb41408203546e7e69037cf8bd63 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 8875635d2cd0f928644c2f3b27bf8ede9586b6f4..570315296bd39e3d81d65afea5ec694f2fe87806 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 {} + +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 1925d57798e22669e01a92b6ca50652c60fe289f..3a0c8cb6cefeaf8428e5945b10ef803281eed4d6 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 {} + +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 319cd38bcf3f49d793f4e8018430f4e5ce387326..e7de4754ecae685b49df15aeba293dd8f4cb240a 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 de45dd5c12d3c66fd760b9b573e0d86d51715e81..619b041cdf1b4b00b7ab5327e99776c411e317c6 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 1064c2d789c81684c464a730642ee33c5f825e6d..a7cd84aeaed90d635ee2b4b655242f97666dffcf 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 ccac59b32d8f76a2120d2f09ccf402e1a93047f5..f6a3ee002222e1e3cee7908ed5c70a122ea9e75e 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(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 3809873c0329b210255f988eeffcb4a516667a7d..9eba1412c5c9e765ee628520536531b85730b8ef 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}; // 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[] | string | number | boolean | ((...args: any) => any); export type ModelOption = any; export type ThemeOption = Dictionary; -export type DisplayStatus = 'normal' | 'emphasis'; -export type DisplayStatusHostOption = { +export type DisplayState = 'normal' | 'emphasis'; +export type DisplayStateHostOption = { emphasis?: Dictionary, [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 87ace50014cdef128ec1c42cafb5ea3c496123d4..0e2ac7e90326175f3bf69bdd08a888eee985304d 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 5cbf95519a30abb4f9a8536f2b2a20f294770725..0417ccd4de1993dde93a4227c01f6890e0f9ed6c 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 9f4663e8d64ec46ea1f69005298222150105a0a1..e3b87780ec75dd3e967cdaae41b027669209d120 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;