You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@echarts.apache.org by su...@apache.org on 2020/07/17 11:39:11 UTC
[incubator-echarts] 12/16: fix: (1) Inside dataZoom can not dispose
when grid removed. (2) uniform the reference between components.
This is an automated email from the ASF dual-hosted git repository.
sushuang pushed a commit to branch remove-component
in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit f5a9667d8e234299b5eef35089015200d0456fdb
Author: 100pah <su...@gmail.com>
AuthorDate: Thu Jul 16 19:00:06 2020 +0800
fix: (1) Inside dataZoom can not dispose when grid removed. (2) uniform the reference between components.
---
src/chart/themeRiver/ThemeRiverSeries.ts | 8 +-
src/component/dataZoom/AxisProxy.ts | 18 +-
src/component/dataZoom/DataZoomModel.ts | 15 +-
src/component/dataZoom/DataZoomView.ts | 70 --------
src/component/dataZoom/InsideZoomView.ts | 128 +++++++-------
src/component/dataZoom/SliderZoomView.ts | 91 ++++------
src/component/dataZoom/helper.ts | 88 ++++++++--
src/component/dataZoom/roams.ts | 265 +++++++++++++++++------------
src/component/toolbox/feature/DataZoom.ts | 6 +-
src/component/toolbox/feature/MagicType.ts | 7 +-
src/coord/axisModelCommonMixin.ts | 1 -
src/coord/cartesian/AxisModel.ts | 7 +-
src/coord/cartesian/Grid.ts | 6 +-
src/coord/cartesian/cartesianAxisHelper.ts | 5 +-
src/coord/geo/Geo.ts | 6 +-
src/coord/parallel/parallelCreator.ts | 9 +-
src/coord/polar/AxisModel.ts | 7 +-
src/coord/polar/polarCreator.ts | 9 +-
src/coord/single/singleCreator.ts | 9 +-
src/model/Component.ts | 6 +-
src/model/referHelper.ts | 11 +-
src/util/model.ts | 38 +++--
test/dataZoom-feature.html | 2 +-
test/option-replaceMerge.html | 123 +++++++------
24 files changed, 494 insertions(+), 441 deletions(-)
diff --git a/src/chart/themeRiver/ThemeRiverSeries.ts b/src/chart/themeRiver/ThemeRiverSeries.ts
index 3f0cc49..50c310b 100644
--- a/src/chart/themeRiver/ThemeRiverSeries.ts
+++ b/src/chart/themeRiver/ThemeRiverSeries.ts
@@ -22,7 +22,7 @@ import createDimensions from '../../data/helper/createDimensions';
import {getDimensionTypeByAxis} from '../../data/helper/dimensionHelper';
import List from '../../data/List';
import * as zrUtil from 'zrender/src/core/util';
-import {groupData} from '../../util/model';
+import {groupData, SINGLE_REFERRING} from '../../util/model';
import {encodeHTML} from '../../util/format';
import LegendVisualProvider from '../../visual/LegendVisualProvider';
import {
@@ -172,11 +172,7 @@ class ThemeRiverSeriesModel extends SeriesModel<ThemeRiverSeriesOption> {
*/
getInitialData(option: ThemeRiverSeriesOption, ecModel: GlobalModel): List {
- const singleAxisModel = ecModel.queryComponents({
- mainType: 'singleAxis',
- index: this.get('singleAxisIndex'),
- id: this.get('singleAxisId')
- })[0];
+ const singleAxisModel = this.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];
const axisType = singleAxisModel.get('type');
diff --git a/src/component/dataZoom/AxisProxy.ts b/src/component/dataZoom/AxisProxy.ts
index 196c71d..f34a08b 100644
--- a/src/component/dataZoom/AxisProxy.ts
+++ b/src/component/dataZoom/AxisProxy.ts
@@ -19,7 +19,6 @@
import * as zrUtil from 'zrender/src/core/util';
import * as numberUtil from '../../util/number';
-import * as helper from './helper';
import sliderMove from '../helper/sliderMove';
import GlobalModel from '../../model/Global';
import SeriesModel from '../../model/Series';
@@ -30,6 +29,8 @@ import DataZoomModel from './DataZoomModel';
import { AxisBaseModel } from '../../coord/AxisBaseModel';
import { unionAxisExtentFromData } from '../../coord/axisHelper';
import { ensureScaleRawExtentInfo } from '../../coord/scaleRawExtentInfo';
+import { getAxisMainType, isCoordSupported, DataZoomAxisDimension } from './helper';
+import { SINGLE_REFERRING } from '../../util/model';
const each = zrUtil.each;
const asc = numberUtil.asc;
@@ -54,7 +55,7 @@ class AxisProxy {
ecModel: GlobalModel;
- private _dimName: string;
+ private _dimName: DataZoomAxisDimension;
private _axisIndex: number;
private _valueWindow: [number, number];
@@ -66,7 +67,12 @@ class AxisProxy {
private _dataZoomModel: DataZoomModel;
- constructor(dimName: string, axisIndex: number, dataZoomModel: DataZoomModel, ecModel: GlobalModel) {
+ constructor(
+ dimName: DataZoomAxisDimension,
+ axisIndex: number,
+ dataZoomModel: DataZoomModel,
+ ecModel: GlobalModel
+ ) {
this._dimName = dimName;
this._axisIndex = axisIndex;
@@ -107,9 +113,9 @@ class AxisProxy {
const seriesModels: SeriesModel[] = [];
this.ecModel.eachSeries(function (seriesModel) {
- if (helper.isCoordSupported(seriesModel.get('coordinateSystem'))) {
- const axisMainType = helper.getAxisMainType(this._dimName);
- const axisModel = seriesModel.getReferringComponents(axisMainType, true).models[0];
+ if (isCoordSupported(seriesModel)) {
+ const axisMainType = getAxisMainType(this._dimName);
+ const axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0];
if (axisModel && this._axisIndex === axisModel.componentIndex) {
seriesModels.push(seriesModel);
}
diff --git a/src/component/dataZoom/DataZoomModel.ts b/src/component/dataZoom/DataZoomModel.ts
index db5c440..38aa4e7 100644
--- a/src/component/dataZoom/DataZoomModel.ts
+++ b/src/component/dataZoom/DataZoomModel.ts
@@ -34,6 +34,7 @@ import {
} from './helper';
import SingleAxisModel from '../../coord/single/AxisModel';
import { __DEV__ } from '../../config';
+import { MULTIPLE_REFERRING, SINGLE_REFERRING } from '../../util/model';
export interface DataZoomOption extends ComponentOption {
@@ -170,6 +171,8 @@ class DataZoomModel<Opts extends DataZoomOption = DataZoomOption> extends Compon
private _targetAxisInfoMap: DataZoomTargetAxisInfoMap;
+ private _noTarget: boolean;
+
/**
* It is `[rangeModeForMin, rangeModeForMax]`.
* The optional values for `rangeMode`:
@@ -274,13 +277,15 @@ class DataZoomModel<Opts extends DataZoomOption = DataZoomOption> extends Compon
this._orient = optionOrient || 'horizontal';
this._fillAutoTargetAxisByOrient(targetAxisIndexMap, this._orient);
}
+
+ this._noTarget = !targetAxisIndexMap.keys().length;
}
private _fillSpecifiedTargetAxis(targetAxisIndexMap: DataZoomTargetAxisInfoMap): boolean {
let hasAxisSpecified = false;
each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) {
- const refering = this.getReferringComponents(getAxisMainType(axisDim), false);
+ const refering = this.getReferringComponents(getAxisMainType(axisDim), MULTIPLE_REFERRING);
// When user set axisIndex as a empty array, we think that user specify axisIndex
// but do not want use auto mode. Because empty array may be encountered when
// some error occured.
@@ -331,10 +336,10 @@ class DataZoomModel<Opts extends DataZoomOption = DataZoomOption> extends Compon
// Find parallel axes in the same grid.
if (axisDim === 'x' || axisDim === 'y') {
- const gridModel = axisModel.getReferringComponents('grid', true).models[0];
+ const gridModel = axisModel.getReferringComponents('grid', SINGLE_REFERRING).models[0];
gridModel && each(axisModels, function (axModel) {
if (axisModel.componentIndex !== axModel.componentIndex
- && gridModel === axModel.getReferringComponents('grid', true).models[0]
+ && gridModel === axModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]
) {
axisInfo.add(axModel.componentIndex);
}
@@ -408,6 +413,10 @@ class DataZoomModel<Opts extends DataZoomOption = DataZoomOption> extends Compon
});
}
+ noTarget(): boolean {
+ return this._noTarget;
+ }
+
getFirstTargetAxisModel(): AxisBaseModel {
let firstAxisModel: AxisBaseModel;
this.eachTargetAxis(function (axisDim, axisIndex) {
diff --git a/src/component/dataZoom/DataZoomView.ts b/src/component/dataZoom/DataZoomView.ts
index 8f9b285..2a96a35 100644
--- a/src/component/dataZoom/DataZoomView.ts
+++ b/src/component/dataZoom/DataZoomView.ts
@@ -21,16 +21,7 @@ import ComponentView from '../../view/Component';
import DataZoomModel from './DataZoomModel';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
-import { AxisBaseModel } from '../../coord/AxisBaseModel';
-import { Dictionary } from '../../util/types';
-import { CoordinateSystemHostModel } from '../../coord/CoordinateSystem';
-import { getAxisMainType } from './helper';
-export interface CoordInfo {
- model: CoordinateSystemHostModel
- axisModels: AxisBaseModel[]
- coordIndex: number
-}
class DataZoomView extends ComponentView {
static type = 'dataZoom';
@@ -46,67 +37,6 @@ class DataZoomView extends ComponentView {
this.api = api;
}
- /**
- * Find the first target coordinate system.
- *
- * @protected
- * @return {Object} {
- * grid: [
- * {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
- * {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
- * ...
- * ], // cartesians must not be null/undefined.
- * polar: [
- * {model: coord0, axisModels: [axis4], coordIndex: 0},
- * ...
- * ], // polars must not be null/undefined.
- * singleAxis: [
- * {model: coord0, axisModels: [], coordIndex: 0}
- * ]
- */
- getTargetCoordInfo() {
- const dataZoomModel = this.dataZoomModel;
- const ecModel = this.ecModel;
- const coordSysLists: Dictionary<CoordInfo[]> = {};
-
- dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
- const axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex) as AxisBaseModel;
- if (axisModel) {
- const coordModel = axisModel.getCoordSysModel();
- coordModel && save(
- coordModel,
- axisModel,
- coordSysLists[coordModel.mainType] || (coordSysLists[coordModel.mainType] = []),
- coordModel.componentIndex
- );
- }
- }, this);
-
- function save(
- coordModel: CoordinateSystemHostModel,
- axisModel: AxisBaseModel,
- store: CoordInfo[],
- coordIndex: number
- ) {
- let item;
- for (let i = 0; i < store.length; i++) {
- if (store[i].model === coordModel) {
- item = store[i];
- break;
- }
- }
- if (!item) {
- store.push(item = {
- model: coordModel,
- axisModels: [],
- coordIndex: coordIndex
- });
- }
- item.axisModels.push(axisModel);
- }
-
- return coordSysLists;
- }
}
ComponentView.registerClass(DataZoomView);
diff --git a/src/component/dataZoom/InsideZoomView.ts b/src/component/dataZoom/InsideZoomView.ts
index 41f99e7..878fef2 100644
--- a/src/component/dataZoom/InsideZoomView.ts
+++ b/src/component/dataZoom/InsideZoomView.ts
@@ -17,22 +17,21 @@
* under the License.
*/
-import DataZoomView, {CoordInfo} from './DataZoomView';
+import DataZoomView from './DataZoomView';
import sliderMove from '../helper/sliderMove';
import * as roams from './roams';
import InsideZoomModel from './InsideZoomModel';
import GlobalModel from '../../model/Global';
import ExtensionAPI from '../../ExtensionAPI';
import ComponentView from '../../view/Component';
-import { each, map, bind } from 'zrender/src/core/util';
+import { bind } from 'zrender/src/core/util';
import RoamController, {RoamEventParams} from '../helper/RoamController';
import { AxisBaseModel } from '../../coord/AxisBaseModel';
import Polar from '../../coord/polar/Polar';
import SingleAxis from '../../coord/single/SingleAxis';
+import { DataZoomCoordSysMainType, DataZoomReferCoordSysInfo } from './helper';
-type SupportedCoordSysName = 'polar' | 'grid' | 'singleAxis';
-
class InsideZoomView extends DataZoomView {
static type = 'dataZoom.inside';
type = 'dataZoom.inside';
@@ -43,86 +42,71 @@ class InsideZoomView extends DataZoomView {
*/
range: number[];
- /**
- * @override
- */
- render(dataZoomModel: InsideZoomModel, ecModel: GlobalModel, api: ExtensionAPI, payload: any) {
+ render(dataZoomModel: InsideZoomModel, ecModel: GlobalModel, api: ExtensionAPI) {
super.render.apply(this, arguments as any);
+ if (dataZoomModel.noTarget()) {
+ this._clear();
+ return;
+ }
+
// Hence the `throttle` util ensures to preserve command order,
// here simply updating range all the time will not cause missing
// any of the the roam change.
this.range = dataZoomModel.getPercentRange();
// Reset controllers.
- each(this.getTargetCoordInfo(), function (coordInfoList, coordSysName: SupportedCoordSysName) {
-
- const allCoordIds = map(coordInfoList, function (coordInfo) {
- return roams.generateCoordId(coordInfo.model);
- });
-
- each(coordInfoList, function (coordInfo) {
- const coordModel = coordInfo.model;
-
- roams.register(
- api,
- {
- coordId: roams.generateCoordId(coordModel),
- allCoordIds: allCoordIds,
- containsPoint(e, x, y) {
- return coordModel.coordinateSystem.containPoint([x, y]);
- },
- dataZoomId: dataZoomModel.id,
- dataZoomModel: dataZoomModel,
- getRange: {
- pan: bind(roamHandlers.pan, this, coordInfo, coordSysName),
- zoom: bind(roamHandlers.zoom, this, coordInfo, coordSysName),
- scrollMove: bind(roamHandlers.scrollMove, this, coordInfo, coordSysName)
- }
- }
- );
- }, this);
-
- }, this);
+ roams.setViewInfoToCoordSysRecord(
+ api,
+ dataZoomModel,
+ {
+ pan: bind(getRangeHandlers.pan, this),
+ zoom: bind(getRangeHandlers.zoom, this),
+ scrollMove: bind(getRangeHandlers.scrollMove, this)
+ }
+ );
}
- /**
- * @override
- */
dispose() {
- roams.unregister(this.api, this.dataZoomModel.id);
+ this._clear();
super.dispose.apply(this, arguments as any);
+ }
+
+ private _clear() {
+ roams.disposeCoordSysRecordIfNeeded(this.api, this.dataZoomModel as InsideZoomModel);
this.range = null;
}
}
-interface RoamHandler<T extends RoamEventParams['zoom'] | RoamEventParams['scrollMove'] | RoamEventParams['pan']> {
+interface DataZoomGetRangeHandler<
+ T extends RoamEventParams['zoom'] | RoamEventParams['scrollMove'] | RoamEventParams['pan']
+> {
(
- coordInfo: CoordInfo,
- coordSysName: SupportedCoordSysName,
+ coordSysInfo: DataZoomReferCoordSysInfo,
+ coordSysMainType: DataZoomCoordSysMainType,
controller: RoamController,
e: T
): [number, number]
}
-const roamHandlers: {
- pan: RoamHandler<RoamEventParams['pan']>
- zoom: RoamHandler<RoamEventParams['zoom']>
- scrollMove: RoamHandler<RoamEventParams['scrollMove']>
+const getRangeHandlers: {
+ pan: DataZoomGetRangeHandler<RoamEventParams['pan']>
+ zoom: DataZoomGetRangeHandler<RoamEventParams['zoom']>
+ scrollMove: DataZoomGetRangeHandler<RoamEventParams['scrollMove']>
} & ThisType<InsideZoomView> = {
- zoom(coordInfo, coordSysName, controller, e: RoamEventParams['zoom']) {
+ zoom(coordSysInfo, coordSysMainType, controller, e: RoamEventParams['zoom']) {
const lastRange = this.range;
const range = lastRange.slice() as [number, number];
// Calculate transform by the first axis.
- const axisModel = coordInfo.axisModels[0];
+ const axisModel = coordSysInfo.axisModels[0];
if (!axisModel) {
return;
}
- const directionInfo = getDirectionInfo[coordSysName](
- null, [e.originX, e.originY], axisModel, controller, coordInfo
+ const directionInfo = getDirectionInfo[coordSysMainType](
+ null, [e.originX, e.originY], axisModel, controller, coordSysInfo
);
const percentPoint = (
directionInfo.signal > 0
@@ -146,9 +130,9 @@ const roamHandlers: {
}
},
- pan: makeMover(function (range, axisModel, coordInfo, coordSysName, controller, e: RoamEventParams['pan']) {
- const directionInfo = getDirectionInfo[coordSysName](
- [e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordInfo
+ pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e: RoamEventParams['pan']) {
+ const directionInfo = getDirectionInfo[coordSysMainType](
+ [e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordSysInfo
);
return directionInfo.signal
@@ -157,29 +141,31 @@ const roamHandlers: {
}),
scrollMove: makeMover(
- function (range, axisModel, coordInfo, coordSysName, controller, e: RoamEventParams['scrollMove']
+ function (range, axisModel, coordSysInfo, coordSysMainType, controller, e: RoamEventParams['scrollMove']
) {
- const directionInfo = getDirectionInfo[coordSysName](
- [0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordInfo
+ const directionInfo = getDirectionInfo[coordSysMainType](
+ [0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordSysInfo
);
return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta;
})
};
+export type DataZoomGetRangeHandlers = typeof getRangeHandlers;
+
function makeMover(
getPercentDelta: (
range: [number, number],
axisModel: AxisBaseModel,
- coordInfo: CoordInfo,
- coordSysName: SupportedCoordSysName,
+ coordSysInfo: DataZoomReferCoordSysInfo,
+ coordSysMainType: DataZoomCoordSysMainType,
controller: RoamController,
e: RoamEventParams['scrollMove']| RoamEventParams['pan']
) => number
) {
return function (
this: InsideZoomView,
- coordInfo: CoordInfo,
- coordSysName: SupportedCoordSysName,
+ coordSysInfo: DataZoomReferCoordSysInfo,
+ coordSysMainType: DataZoomCoordSysMainType,
controller: RoamController,
e: RoamEventParams['scrollMove']| RoamEventParams['pan']
): [number, number] {
@@ -187,13 +173,13 @@ function makeMover(
const range = lastRange.slice() as [number, number];
// Calculate transform by the first axis.
- const axisModel = coordInfo.axisModels[0];
+ const axisModel = coordSysInfo.axisModels[0];
if (!axisModel) {
return;
}
const percentDelta = getPercentDelta(
- range, axisModel, coordInfo, coordSysName, controller, e
+ range, axisModel, coordSysInfo, coordSysMainType, controller, e
);
sliderMove(percentDelta, range, [0, 100], 'all');
@@ -218,16 +204,16 @@ interface GetDirectionInfo {
newPoint: number[],
axisModel: AxisBaseModel,
controller: RoamController,
- coordInfo: CoordInfo
+ coordSysInfo: DataZoomReferCoordSysInfo
): DirectionInfo
}
const getDirectionInfo: Record<'grid' | 'polar' | 'singleAxis', GetDirectionInfo> = {
- grid(oldPoint, newPoint, axisModel, controller, coordInfo) {
+ grid(oldPoint, newPoint, axisModel, controller, coordSysInfo) {
const axis = axisModel.axis;
const ret = {} as DirectionInfo;
- const rect = coordInfo.model.coordinateSystem.getRect();
+ const rect = coordSysInfo.model.coordinateSystem.getRect();
oldPoint = oldPoint || [0, 0];
if (axis.dim === 'x') {
@@ -246,10 +232,10 @@ const getDirectionInfo: Record<'grid' | 'polar' | 'singleAxis', GetDirectionInfo
return ret;
},
- polar(oldPoint, newPoint, axisModel, controller, coordInfo) {
+ polar(oldPoint, newPoint, axisModel, controller, coordSysInfo) {
const axis = axisModel.axis;
const ret = {} as DirectionInfo;
- const polar = coordInfo.model.coordinateSystem as Polar;
+ const polar = coordSysInfo.model.coordinateSystem as Polar;
const radiusExtent = polar.getRadiusAxis().getExtent();
const angleExtent = polar.getAngleAxis().getExtent();
@@ -276,9 +262,9 @@ const getDirectionInfo: Record<'grid' | 'polar' | 'singleAxis', GetDirectionInfo
return ret;
},
- singleAxis(oldPoint, newPoint, axisModel, controller, coordInfo) {
+ singleAxis(oldPoint, newPoint, axisModel, controller, coordSysInfo) {
const axis = axisModel.axis as SingleAxis;
- const rect = coordInfo.model.coordinateSystem.getRect();
+ const rect = coordSysInfo.model.coordinateSystem.getRect();
const ret = {} as DirectionInfo;
oldPoint = oldPoint || [0, 0];
diff --git a/src/component/dataZoom/SliderZoomView.ts b/src/component/dataZoom/SliderZoomView.ts
index 1b47172..addd2c5 100644
--- a/src/component/dataZoom/SliderZoomView.ts
+++ b/src/component/dataZoom/SliderZoomView.ts
@@ -36,7 +36,7 @@ import { RectLike } from 'zrender/src/core/BoundingRect';
import Axis from '../../coord/Axis';
import SeriesModel from '../../model/Series';
import { AxisBaseModel } from '../../coord/AxisBaseModel';
-import { getAxisMainType } from './helper';
+import { getAxisMainType, collectReferCoordSysModelInfo } from './helper';
const Rect = graphic.Rect;
@@ -99,10 +99,6 @@ class SliderZoomView extends DataZoomView {
this.api = api;
}
-
- /**
- * @override
- */
render(
dataZoomModel: SliderZoomModel,
ecModel: GlobalModel,
@@ -117,13 +113,19 @@ class SliderZoomView extends DataZoomView {
throttle.createOrUpdate(
this,
'_dispatchZoomAction',
- this.dataZoomModel.get('throttle'),
+ dataZoomModel.get('throttle'),
'fixRate'
);
this._orient = dataZoomModel.getOrient();
- if (this.dataZoomModel.get('show') === false) {
+ if (dataZoomModel.get('show') === false) {
+ this.group.removeAll();
+ return;
+ }
+
+ if (dataZoomModel.noTarget()) {
+ this._clear();
this.group.removeAll();
return;
}
@@ -138,22 +140,16 @@ class SliderZoomView extends DataZoomView {
this._updateView();
}
- /**
- * @override
- */
- remove() {
- throttle.clear(this, '_dispatchZoomAction');
- }
-
- /**
- * @override
- */
dispose() {
+ this._clear();
super.dispose.apply(this, arguments as any);
+ }
+
+ private _clear() {
throttle.clear(this, '_dispatchZoomAction');
}
- _buildView() {
+ private _buildView() {
const thisGroup = this.group;
thisGroup.removeAll();
@@ -174,10 +170,7 @@ class SliderZoomView extends DataZoomView {
this._positionGroup();
}
- /**
- * @private
- */
- _resetLocation() {
+ private _resetLocation() {
const dataZoomModel = this.dataZoomModel;
const api = this.api;
@@ -223,10 +216,7 @@ class SliderZoomView extends DataZoomView {
this._orient === VERTICAL && this._size.reverse();
}
- /**
- * @private
- */
- _positionGroup() {
+ private _positionGroup() {
const thisGroup = this.group;
const location = this._location;
const orient = this._orient;
@@ -257,14 +247,11 @@ class SliderZoomView extends DataZoomView {
thisGroup.markRedraw();
}
- /**
- * @private
- */
- _getViewExtent() {
+ private _getViewExtent() {
return [0, this._size[0]];
}
- _renderBackground() {
+ private _renderBackground() {
const dataZoomModel = this.dataZoomModel;
const size = this._size;
const barGroup = this._displayables.barGroup;
@@ -293,7 +280,7 @@ class SliderZoomView extends DataZoomView {
}));
}
- _renderDataShadow() {
+ private _renderDataShadow() {
const info = this._dataShadowInfo = this._prepareDataShadowInfo();
if (!info) {
@@ -383,7 +370,7 @@ class SliderZoomView extends DataZoomView {
}));
}
- _prepareDataShadowInfo() {
+ private _prepareDataShadowInfo() {
const dataZoomModel = this.dataZoomModel;
const showDataShadow = dataZoomModel.get('showDataShadow');
@@ -440,7 +427,7 @@ class SliderZoomView extends DataZoomView {
return result;
}
- _renderHandle() {
+ private _renderHandle() {
const displaybles = this._displayables;
const handles: [graphic.Path, graphic.Path] = displaybles.handles = [null, null];
const handleLabels: [graphic.Text, graphic.Text] = displaybles.handleLabels = [null, null];
@@ -594,10 +581,7 @@ class SliderZoomView extends DataZoomView {
this._updateDataInfo(nonRealtime);
}
- /**
- * @private
- */
- _updateDataInfo(nonRealtime?: boolean) {
+ private _updateDataInfo(nonRealtime?: boolean) {
const dataZoomModel = this.dataZoomModel;
const displaybles = this._displayables;
const handleLabels = displaybles.handleLabels;
@@ -660,7 +644,7 @@ class SliderZoomView extends DataZoomView {
}
}
- _formatLabel(value: ParsedValue, axis: Axis) {
+ private _formatLabel(value: ParsedValue, axis: Axis) {
const dataZoomModel = this.dataZoomModel;
const labelFormatter = dataZoomModel.get('labelFormatter');
@@ -685,10 +669,9 @@ class SliderZoomView extends DataZoomView {
}
/**
- * @private
* @param showOrHide true: show, false: hide
*/
- _showDataInfo(showOrHide?: boolean) {
+ private _showDataInfo(showOrHide?: boolean) {
// Always show when drgging.
showOrHide = this._dragging || showOrHide;
@@ -697,7 +680,7 @@ class SliderZoomView extends DataZoomView {
handleLabels[1].attr('invisible', !showOrHide);
}
- _onDragMove(handleIndex: 0 | 1 | 'all', dx: number, dy: number, event: ZRElementEvent) {
+ private _onDragMove(handleIndex: 0 | 1 | 'all', dx: number, dy: number, event: ZRElementEvent) {
this._dragging = true;
// For mobile device, prevent screen slider on the button.
@@ -718,7 +701,7 @@ class SliderZoomView extends DataZoomView {
changed && realtime && this._dispatchZoomAction();
}
- _onDragEnd() {
+ private _onDragEnd() {
this._dragging = false;
this._showDataInfo(false);
@@ -728,7 +711,7 @@ class SliderZoomView extends DataZoomView {
!realtime && this._dispatchZoomAction();
}
- _onClickPanelClick(e: ZRElementEvent) {
+ private _onClickPanelClick(e: ZRElementEvent) {
const size = this._size;
const localPoint = this._displayables.barGroup.transformCoordToLocal(e.offsetX, e.offsetY);
@@ -747,8 +730,8 @@ class SliderZoomView extends DataZoomView {
}
/**
- * This action will be throttled.
* @private
+ * This action will be throttled.
*/
_dispatchZoomAction() {
const range = this._range;
@@ -762,18 +745,16 @@ class SliderZoomView extends DataZoomView {
});
}
- /**
- * @private
- */
- _findCoordRect() {
+ private _findCoordRect() {
// Find the grid coresponding to the first axis referred by dataZoom.
let rect: RectLike;
- each(this.getTargetCoordInfo(), function (coordInfoList) {
- if (!rect && coordInfoList.length) {
- const coordSys = coordInfoList[0].model.coordinateSystem;
- rect = coordSys.getRect && coordSys.getRect();
- }
- });
+ const coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList;
+
+ if (!rect && coordSysInfoList.length) {
+ const coordSys = coordSysInfoList[0].model.coordinateSystem;
+ rect = coordSys.getRect && coordSys.getRect();
+ }
+
if (!rect) {
const width = this.api.getWidth();
const height = this.api.getHeight();
diff --git a/src/component/dataZoom/helper.ts b/src/component/dataZoom/helper.ts
index 7def11e..ef739b1 100644
--- a/src/component/dataZoom/helper.ts
+++ b/src/component/dataZoom/helper.ts
@@ -17,19 +17,31 @@
* under the License.
*/
-import { Payload, DimensionName } from '../../util/types';
+import { Payload } from '../../util/types';
import GlobalModel from '../../model/Global';
import DataZoomModel from './DataZoomModel';
-import { indexOf, createHashMap, assert } from 'zrender/src/core/util';
+import { indexOf, createHashMap, assert, HashMap } from 'zrender/src/core/util';
import { __DEV__ } from '../../config';
+import SeriesModel from '../../model/Series';
+import { CoordinateSystemHostModel } from '../../coord/CoordinateSystem';
+import { AxisBaseModel } from '../../coord/AxisBaseModel';
export interface DataZoomPayloadBatchItem {
- dataZoomId: string
- start?: number
- end?: number
- startValue?: number
- endValue?: number
+ dataZoomId: string;
+ start?: number;
+ end?: number;
+ startValue?: number;
+ endValue?: number;
+}
+
+export interface DataZoomReferCoordSysInfo {
+ model: CoordinateSystemHostModel;
+ // Notice: if two dataZooms refer the same coordinamte system model,
+ // (1) The axis they refered may different
+ // (2) The sequence the axisModels matters, may different in
+ // different dataZooms.
+ axisModels: AxisBaseModel[];
}
export const DATA_ZOOM_AXIS_DIMENSIONS = [
@@ -43,13 +55,15 @@ type DataZoomAxisIndexPropName =
'xAxisIndex' | 'yAxisIndex' | 'radiusAxisIndex' | 'angleAxisIndex' | 'singleAxisIndex';
type DataZoomAxisIdPropName =
'xAxisId' | 'yAxisId' | 'radiusAxisId' | 'angleAxisId' | 'singleAxisId';
+export type DataZoomCoordSysMainType = 'polar' | 'grid' | 'singleAxis';
// Supported coords.
// FIXME: polar has been broken (but rarely used).
-const COORDS = ['cartesian2d', 'polar', 'singleAxis'] as const;
+const SERIES_COORDS = ['cartesian2d', 'polar', 'singleAxis'] as const;
-export function isCoordSupported(coordType: string) {
- return indexOf(COORDS, coordType) >= 0;
+export function isCoordSupported(seriesModel: SeriesModel): boolean {
+ const coordType = seriesModel.get('coordinateSystem');
+ return indexOf(SERIES_COORDS, coordType) >= 0;
}
export function getAxisMainType(axisDim: DataZoomAxisDimension): DataZoomAxisMainType {
@@ -138,3 +152,57 @@ export function findEffectedDataZooms(ecModel: GlobalModel, payload: Payload): D
return effectedModels;
}
+
+/**
+ * Find the first target coordinate system.
+ * Available after model built.
+ *
+ * @return Like {
+ * grid: [
+ * {model: coord0, axisModels: [axis1, axis3], coordIndex: 1},
+ * {model: coord1, axisModels: [axis0, axis2], coordIndex: 0},
+ * ...
+ * ], // cartesians must not be null/undefined.
+ * polar: [
+ * {model: coord0, axisModels: [axis4], coordIndex: 0},
+ * ...
+ * ], // polars must not be null/undefined.
+ * singleAxis: [
+ * {model: coord0, axisModels: [], coordIndex: 0}
+ * ]
+ * }
+ */
+export function collectReferCoordSysModelInfo(dataZoomModel: DataZoomModel): {
+ infoList: DataZoomReferCoordSysInfo[];
+ // Key: coordSysModel.uid
+ infoMap: HashMap<DataZoomReferCoordSysInfo, string>;
+} {
+ const ecModel = dataZoomModel.ecModel;
+ const coordSysInfoWrap = {
+ infoList: [] as DataZoomReferCoordSysInfo[],
+ infoMap: createHashMap<DataZoomReferCoordSysInfo, string>()
+ };
+
+ dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) {
+ const axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex) as AxisBaseModel;
+ if (!axisModel) {
+ return;
+ }
+ const coordSysModel = axisModel.getCoordSysModel();
+ if (!coordSysModel) {
+ return;
+ }
+
+ const coordSysUid = coordSysModel.uid;
+ let coordSysInfo = coordSysInfoWrap.infoMap.get(coordSysUid);
+ if (!coordSysInfo) {
+ coordSysInfo = { model: coordSysModel, axisModels: [] };
+ coordSysInfoWrap.infoList.push(coordSysInfo);
+ coordSysInfoWrap.infoMap.set(coordSysUid, coordSysInfo);
+ }
+
+ coordSysInfo.axisModels.push(axisModel);
+ });
+
+ return coordSysInfoWrap;
+}
diff --git a/src/component/dataZoom/roams.ts b/src/component/dataZoom/roams.ts
index 05524c9..7686d56 100644
--- a/src/component/dataZoom/roams.ts
+++ b/src/component/dataZoom/roams.ts
@@ -23,156 +23,205 @@
// pan or zoom, only dispatch one action for those data zoom
// components.
-import RoamController, { RoamType, RoamEventParams } from '../../component/helper/RoamController';
+import * as echarts from '../../echarts';
+import RoamController, { RoamType } from '../../component/helper/RoamController';
import * as throttleUtil from '../../util/throttle';
import { makeInner } from '../../util/model';
import { Dictionary, ZRElementEvent } from '../../util/types';
import ExtensionAPI from '../../ExtensionAPI';
import InsideZoomModel from './InsideZoomModel';
-import { each, indexOf, curry, Curry1 } from 'zrender/src/core/util';
-import ComponentModel from '../../model/Component';
-import { DataZoomPayloadBatchItem } from './helper';
+import { each, curry, Curry1, HashMap, createHashMap } from 'zrender/src/core/util';
+import {
+ DataZoomPayloadBatchItem, collectReferCoordSysModelInfo,
+ DataZoomCoordSysMainType, DataZoomReferCoordSysInfo
+} from './helper';
+import GlobalModel from '../../model/Global';
+import { CoordinateSystemHostModel } from '../../coord/CoordinateSystem';
+import { DataZoomGetRangeHandlers } from './InsideZoomView';
+
interface DataZoomInfo {
- coordId: string
- containsPoint: (e: ZRElementEvent, x: number, y: number) => boolean
- allCoordIds: string[]
- dataZoomId: string
- getRange: {
- pan: (controller: RoamController, e: RoamEventParams['pan']) => [number, number]
- zoom: (controller: RoamController, e: RoamEventParams['zoom']) => [number, number]
- scrollMove: (controller: RoamController, e: RoamEventParams['scrollMove']) => [number, number]
- }
- dataZoomModel: InsideZoomModel
-}
-interface Record {
- // key is dataZoomId
- dataZoomInfos: Dictionary<DataZoomInfo>
- count: number
- coordId: string
- controller: RoamController
- dispatchAction: Curry1<typeof dispatchAction, ExtensionAPI>
+ getRange: DataZoomGetRangeHandlers;
+ model: InsideZoomModel;
+ dzReferCoordSysInfo: DataZoomReferCoordSysInfo
}
-interface PayloadBatch {
- dataZoomId: string
+interface CoordSysRecord {
+ // key: dataZoom.uid
+ dataZoomInfoMap: HashMap<DataZoomInfo, string>;
+ model: CoordinateSystemHostModel,
+ // count: number
+ // coordId: string
+ controller: RoamController;
+ containsPoint: (e: ZRElementEvent, x: number, y: number) => boolean;
+ dispatchAction: Curry1<typeof dispatchAction, ExtensionAPI>;
}
-type Store = Dictionary<Record>;
-const inner = makeInner<Store, ExtensionAPI>();
+const inner = makeInner<{
+ // key: coordSysModel.uid
+ coordSysRecordMap: HashMap<CoordSysRecord, string>;
+}, ExtensionAPI>();
-export function register(api: ExtensionAPI, dataZoomInfo: DataZoomInfo) {
- const store = inner(api);
- const theDataZoomId = dataZoomInfo.dataZoomId;
- const theCoordId = dataZoomInfo.coordId;
- // Do clean when a dataZoom changes its target coordnate system.
- // Avoid memory leak, dispose all not-used-registered.
- each(store, function (record, coordId) {
- const dataZoomInfos = record.dataZoomInfos;
- if (dataZoomInfos[theDataZoomId]
- && indexOf(dataZoomInfo.allCoordIds, theCoordId) < 0
- ) {
- delete dataZoomInfos[theDataZoomId];
- record.count--;
- }
- });
+echarts.registerProcessor(echarts.PRIORITY.PROCESSOR.FILTER, function (ecModel: GlobalModel, api: ExtensionAPI): void {
+ const apiInner = inner(api);
+ const coordSysRecordMap = apiInner.coordSysRecordMap
+ || (apiInner.coordSysRecordMap = createHashMap<CoordSysRecord, string>());
- cleanStore(store);
-
- let record = store[theCoordId];
- // Create if needed.
- if (!record) {
- record = store[theCoordId] = {
- coordId: theCoordId,
- dataZoomInfos: {},
- count: 0,
- controller: null,
- dispatchAction: curry(dispatchAction, api)
- };
- record.controller = createController(api, record);
- }
+ coordSysRecordMap.each(function (coordSysRecord) {
+ // `coordSysRecordMap` always exists (becuase it hold the `roam controller`, which should
+ // better not re-create each time), but clear `dataZoomInfoMap` each round of the workflow.
+ coordSysRecord.dataZoomInfoMap = null;
+ });
- // Update reference of dataZoom.
- !(record.dataZoomInfos[theDataZoomId]) && record.count++;
- record.dataZoomInfos[theDataZoomId] = dataZoomInfo;
+ ecModel.eachComponent(
+ { mainType: 'dataZoom', subType: 'inside' },
+ function (dataZoomModel: InsideZoomModel) {
+ const dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel);
- const controllerParams = mergeControllerParams(record.dataZoomInfos);
- record.controller.enable(controllerParams.controlType, controllerParams.opt);
+ each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) {
- // Consider resize, area should be always updated.
- record.controller.setPointerChecker(dataZoomInfo.containsPoint);
+ const coordSysUid = dzCoordSysInfo.model.uid;
+ const coordSysRecord = coordSysRecordMap.get(coordSysUid)
+ || coordSysRecordMap.set(coordSysUid, createCoordSysRecord(api, dzCoordSysInfo.model));
- // Update throttle.
- throttleUtil.createOrUpdate(
- record,
- 'dispatchAction',
- dataZoomInfo.dataZoomModel.get('throttle', true),
- 'fixRate'
+ const dataZoomInfoMap = coordSysRecord.dataZoomInfoMap
+ || (coordSysRecord.dataZoomInfoMap = createHashMap<DataZoomInfo, string>());
+ // Notice these props might be changed each time for a single dataZoomModel.
+ dataZoomInfoMap.set(dataZoomModel.uid, {
+ dzReferCoordSysInfo: dzCoordSysInfo,
+ model: dataZoomModel,
+ getRange: null
+ });
+ });
+ }
);
-}
-export function unregister(api: ExtensionAPI, dataZoomId: string) {
- const store = inner(api);
+ // (1) Merge dataZoom settings for each coord sys and set to the roam controller.
+ // (2) Clear coord sys if not refered by any dataZoom.
+ coordSysRecordMap.each(function (coordSysRecord) {
+ const controller = coordSysRecord.controller;
+ let firstDzInfo: DataZoomInfo;
+ const dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;
+
+ if (dataZoomInfoMap) {
+ const firstDzKey = dataZoomInfoMap.keys()[0];
+ if (firstDzKey != null) {
+ firstDzInfo = dataZoomInfoMap.get(firstDzKey);
+ }
+ }
+
+ if (!firstDzInfo) {
+ disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
+ return;
+ }
+
+ const controllerParams = mergeControllerParams(dataZoomInfoMap);
+ controller.enable(controllerParams.controlType, controllerParams.opt);
+
+ controller.setPointerChecker(coordSysRecord.containsPoint);
+
+ throttleUtil.createOrUpdate(
+ coordSysRecord,
+ 'dispatchAction',
+ firstDzInfo.model.get('throttle', true),
+ 'fixRate'
+ );
+ });
+
+});
+
- each(store, function (record) {
- record.controller.dispose();
- const dataZoomInfos = record.dataZoomInfos;
- if (dataZoomInfos[dataZoomId]) {
- delete dataZoomInfos[dataZoomId];
- record.count--;
+export function setViewInfoToCoordSysRecord(
+ api: ExtensionAPI,
+ dataZoomModel: InsideZoomModel,
+ getRange: DataZoomGetRangeHandlers
+): void {
+ inner(api).coordSysRecordMap.each(function (coordSysRecord) {
+ const dzInfo = coordSysRecord.dataZoomInfoMap.get(dataZoomModel.uid);
+ if (dzInfo) {
+ dzInfo.getRange = getRange;
}
});
+}
- cleanStore(store);
+export function disposeCoordSysRecordIfNeeded(api: ExtensionAPI, dataZoomModel: InsideZoomModel) {
+ const coordSysRecordMap = inner(api).coordSysRecordMap;
+ const coordSysKeyArr = coordSysRecordMap.keys();
+ for (let i = 0; i < coordSysKeyArr.length; i++) {
+ const coordSysKey = coordSysKeyArr[i];
+ const coordSysRecord = coordSysRecordMap.get(coordSysKey);
+ const dataZoomInfoMap = coordSysRecord.dataZoomInfoMap;
+ if (dataZoomInfoMap) {
+ const dzUid = dataZoomModel.uid;
+ const dzInfo = dataZoomInfoMap.get(dzUid);
+ if (dzInfo) {
+ dataZoomInfoMap.removeKey(dzUid);
+ if (!dataZoomInfoMap.keys().length) {
+ disposeCoordSysRecord(coordSysRecordMap, coordSysRecord);
+ }
+ }
+ }
+ }
}
-/**
- * @public
- */
-export function generateCoordId(coordModel: ComponentModel) {
- return coordModel.type + '\0_' + coordModel.id;
+function disposeCoordSysRecord(
+ coordSysRecordMap: HashMap<CoordSysRecord, string>,
+ coordSysRecord: CoordSysRecord
+): void {
+ if (coordSysRecord) {
+ coordSysRecordMap.removeKey(coordSysRecord.model.uid);
+ const controller = coordSysRecord.controller;
+ controller && controller.dispose();
+ }
}
-function createController(api: ExtensionAPI, newRecord: Record) {
- const controller = new RoamController(api.getZr());
+function createCoordSysRecord(api: ExtensionAPI, coordSysModel: CoordinateSystemHostModel): CoordSysRecord {
+ // These init props will never change after record created.
+ const coordSysRecord: CoordSysRecord = {
+ model: coordSysModel,
+ containsPoint: curry(containsPoint, coordSysModel),
+ dispatchAction: curry(dispatchAction, api),
+ dataZoomInfoMap: null,
+ controller: null
+ };
+
+ // Must not do anything depends on coordSysRecord outside the event handler here,
+ // because coordSysRecord not completed yet.
+ const controller = coordSysRecord.controller = new RoamController(api.getZr());
each(['pan', 'zoom', 'scrollMove'] as const, function (eventName) {
controller.on(eventName, function (event) {
const batch: DataZoomPayloadBatchItem[] = [];
- each(newRecord.dataZoomInfos, function (info) {
+ coordSysRecord.dataZoomInfoMap.each(function (dzInfo) {
// Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove,
// moveOnMouseWheel, ...) enabled.
- if (!event.isAvailableBehavior(info.dataZoomModel.option)) {
+ if (!event.isAvailableBehavior(dzInfo.model.option)) {
return;
}
- const method = (info.getRange || {} as DataZoomInfo['getRange'])[eventName];
- const range = method && method(newRecord.controller, event as any);
+ const method = (dzInfo.getRange || {} as DataZoomGetRangeHandlers)[eventName];
+ const range = method && method(
+ dzInfo.dzReferCoordSysInfo,
+ coordSysRecord.model.mainType as DataZoomCoordSysMainType,
+ coordSysRecord.controller,
+ event as any
+ );
- !(info.dataZoomModel as InsideZoomModel).get('disabled', true) && range && batch.push({
- dataZoomId: info.dataZoomId,
+ !dzInfo.model.get('disabled', true) && range && batch.push({
+ dataZoomId: dzInfo.model.id,
start: range[0],
end: range[1]
});
});
- batch.length && newRecord.dispatchAction(batch);
+ batch.length && coordSysRecord.dispatchAction(batch);
});
});
- return controller;
-}
-
-function cleanStore(store: Store) {
- each(store, function (record, coordId) {
- if (!record.count) {
- record.controller.dispose();
- delete store[coordId];
- }
- });
+ return coordSysRecord;
}
/**
@@ -185,10 +234,16 @@ function dispatchAction(api: ExtensionAPI, batch: DataZoomPayloadBatchItem[]) {
});
}
+function containsPoint(
+ coordSysModel: CoordinateSystemHostModel, e: ZRElementEvent, x: number, y: number
+): boolean {
+ return coordSysModel.coordinateSystem.containPoint([x, y]);
+}
+
/**
* Merge roamController settings when multiple dataZooms share one roamController.
*/
-function mergeControllerParams(dataZoomInfos: Dictionary<DataZoomInfo>) {
+function mergeControllerParams(dataZoomInfoMap: HashMap<{ model: InsideZoomModel }>) {
let controlType: RoamType;
// DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated
// as string, it is probably revert to reserved word by compress tool. See #7411.
@@ -201,8 +256,8 @@ function mergeControllerParams(dataZoomInfos: Dictionary<DataZoomInfo>) {
};
let preventDefaultMouseMove = true;
- each(dataZoomInfos, function (dataZoomInfo) {
- const dataZoomModel = dataZoomInfo.dataZoomModel as InsideZoomModel;
+ dataZoomInfoMap.each(function (dataZoomInfo) {
+ const dataZoomModel = dataZoomInfo.model;
const oneType = dataZoomModel.get('disabled', true)
? false
: dataZoomModel.get('zoomLock', true)
diff --git a/src/component/toolbox/feature/DataZoom.ts b/src/component/toolbox/feature/DataZoom.ts
index 1e11ed2..a69b92f 100644
--- a/src/component/toolbox/feature/DataZoom.ts
+++ b/src/component/toolbox/feature/DataZoom.ts
@@ -40,16 +40,14 @@ import Cartesian2D from '../../../coord/cartesian/Cartesian2D';
import CartesianAxisModel from '../../../coord/cartesian/AxisModel';
import DataZoomModel from '../../dataZoom/DataZoomModel';
import {
- DataZoomPayloadBatchItem, DataZoomAxisDimension, getAxisIndexPropName,
- getAxisIdPropName, getAxisMainType
+ DataZoomPayloadBatchItem, DataZoomAxisDimension
} from '../../dataZoom/helper';
import {
ModelFinderObject, ModelFinderIndexQuery, makeInternalComponentId,
- queryReferringComponents, ModelFinderIdQuery, parseFinder
+ ModelFinderIdQuery, parseFinder
} from '../../../util/model';
import ToolboxModel from '../ToolboxModel';
import { registerInternalOptionCreator } from '../../../model/internalComponentCreator';
-import Model from '../../../model/Model';
import ComponentModel from '../../../model/Component';
diff --git a/src/component/toolbox/feature/MagicType.ts b/src/component/toolbox/feature/MagicType.ts
index 2dfd038..b5b3e0f 100644
--- a/src/component/toolbox/feature/MagicType.ts
+++ b/src/component/toolbox/feature/MagicType.ts
@@ -25,6 +25,7 @@ import { SeriesOption, ECUnitOption } from '../../../util/types';
import GlobalModel from '../../../model/Global';
import ExtensionAPI from '../../../ExtensionAPI';
import SeriesModel from '../../../model/Series';
+import { SINGLE_REFERRING } from '../../../util/model';
const magicTypeLang = lang.toolbox.magicType;
const INNER_STACK_KEYWORD = '__ec_magicType_stack__' as const;
@@ -117,11 +118,7 @@ class MagicType extends ToolboxFeature<ToolboxMagicTypeFeatureOption> {
if (categoryAxis) {
const axisDim = categoryAxis.dim;
const axisType = axisDim + 'Axis';
- const axisModel = ecModel.queryComponents({
- mainType: axisType,
- index: seriesModel.get(name + 'Index' as any),
- id: seriesModel.get(name + 'Id' as any)
- })[0];
+ const axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];
const axisIndex = axisModel.componentIndex;
newOption[axisType] = newOption[axisType] || [];
diff --git a/src/coord/axisModelCommonMixin.ts b/src/coord/axisModelCommonMixin.ts
index c1c458f..4550618 100644
--- a/src/coord/axisModelCommonMixin.ts
+++ b/src/coord/axisModelCommonMixin.ts
@@ -17,7 +17,6 @@
* under the License.
*/
-import * as zrUtil from 'zrender/src/core/util';
import Model from '../model/Model';
import Axis from './Axis';
import { AxisBaseOption } from './axisCommonTypes';
diff --git a/src/coord/cartesian/AxisModel.ts b/src/coord/cartesian/AxisModel.ts
index 1d4a6d0..9a21401 100644
--- a/src/coord/cartesian/AxisModel.ts
+++ b/src/coord/cartesian/AxisModel.ts
@@ -26,6 +26,7 @@ import { AxisBaseOption } from '../axisCommonTypes';
import GridModel from './GridModel';
import { AxisBaseModel } from '../AxisBaseModel';
import {OrdinalSortInfo} from '../../util/types';
+import { SINGLE_REFERRING } from '../../util/model';
export type CartesianAxisPosition = 'top' | 'bottom' | 'left' | 'right';
@@ -50,11 +51,7 @@ class CartesianAxisModel extends ComponentModel<CartesianAxisOption>
axis: Axis2D;
getCoordSysModel(): GridModel {
- return this.ecModel.queryComponents({
- mainType: 'grid',
- index: this.option.gridIndex,
- id: this.option.gridId
- })[0] as GridModel;
+ return this.getReferringComponents('grid', SINGLE_REFERRING).models[0] as GridModel;
}
}
diff --git a/src/coord/cartesian/Grid.ts b/src/coord/cartesian/Grid.ts
index 91e540b..ceb2787 100644
--- a/src/coord/cartesian/Grid.ts
+++ b/src/coord/cartesian/Grid.ts
@@ -36,7 +36,7 @@ import {
import Cartesian2D, {cartesian2DDimensions} from './Cartesian2D';
import Axis2D from './Axis2D';
import CoordinateSystemManager from '../../CoordinateSystem';
-import {ParsedModelFinder} from '../../util/model';
+import {ParsedModelFinder, SINGLE_REFERRING} from '../../util/model';
// Depends on GridModel, AxisModel, which performs preprocess.
import GridModel from './GridModel';
@@ -254,9 +254,9 @@ class Grid implements CoordinateSystemMaster {
} {
const seriesModel = finder.seriesModel;
const xAxisModel = finder.xAxisModel
- || (seriesModel && seriesModel.getReferringComponents('xAxis', true).models[0]);
+ || (seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0]);
const yAxisModel = finder.yAxisModel
- || (seriesModel && seriesModel.getReferringComponents('yAxis', true).models[0]);
+ || (seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0]);
const gridModel = finder.gridModel;
const coordsList = this._coordsList;
let cartesian: Cartesian2D;
diff --git a/src/coord/cartesian/cartesianAxisHelper.ts b/src/coord/cartesian/cartesianAxisHelper.ts
index badc476..1d66179 100644
--- a/src/coord/cartesian/cartesianAxisHelper.ts
+++ b/src/coord/cartesian/cartesianAxisHelper.ts
@@ -23,6 +23,7 @@ import GridModel from './GridModel';
import CartesianAxisModel from './AxisModel';
import SeriesModel from '../../model/Series';
import { __DEV__ } from '../../config';
+import { SINGLE_REFERRING } from '../../util/model';
interface CartesianAxisLayout {
position: [number, number];
@@ -112,7 +113,9 @@ export function findAxisModels(seriesModel: SeriesModel): {
} as ReturnType<typeof findAxisModels>;
zrUtil.each(axisModelMap, function (v, key) {
const axisType = key.replace(/Model$/, '');
- const axisModel = seriesModel.getReferringComponents(axisType, true).models[0] as CartesianAxisModel;
+ const axisModel = seriesModel.getReferringComponents(
+ axisType, SINGLE_REFERRING
+ ).models[0] as CartesianAxisModel;
if (__DEV__) {
if (!axisModel) {
diff --git a/src/coord/geo/Geo.ts b/src/coord/geo/Geo.ts
index df84083..c5e0630 100644
--- a/src/coord/geo/Geo.ts
+++ b/src/coord/geo/Geo.ts
@@ -24,7 +24,7 @@ import geoSourceManager from './geoSourceManager';
import Region from './Region';
import { NameMap } from './geoTypes';
import GlobalModel from '../../model/Global';
-import { ParsedModelFinder } from '../../util/model';
+import { ParsedModelFinder, SINGLE_REFERRING } from '../../util/model';
import GeoModel from './GeoModel';
import { resizeGeoType } from './geoCreator';
@@ -173,7 +173,9 @@ function getCoordSys(finder: ParsedModelFinder): Geo {
: seriesModel
? (
seriesModel.coordinateSystem as Geo // For map series.
- || ((seriesModel.getReferringComponents('geo', true).models[0] || {}) as GeoModel).coordinateSystem
+ || (
+ (seriesModel.getReferringComponents('geo', SINGLE_REFERRING).models[0] || {}
+ ) as GeoModel).coordinateSystem
)
: null;
}
diff --git a/src/coord/parallel/parallelCreator.ts b/src/coord/parallel/parallelCreator.ts
index b2c9e78..ba747ad 100644
--- a/src/coord/parallel/parallelCreator.ts
+++ b/src/coord/parallel/parallelCreator.ts
@@ -29,6 +29,7 @@ import ParallelModel from './ParallelModel';
import { CoordinateSystemMaster } from '../CoordinateSystem';
import ParallelSeriesModel from '../../chart/parallel/ParallelSeries';
import CoordinateSystemManager from '../../CoordinateSystem';
+import { SINGLE_REFERRING } from '../../util/model';
function create(ecModel: GlobalModel, api: ExtensionAPI): CoordinateSystemMaster[] {
const coordSysList: CoordinateSystemMaster[] = [];
@@ -48,11 +49,9 @@ function create(ecModel: GlobalModel, api: ExtensionAPI): CoordinateSystemMaster
// Inject the coordinateSystems into seriesModel
ecModel.eachSeries(function (seriesModel) {
if ((seriesModel as ParallelSeriesModel).get('coordinateSystem') === 'parallel') {
- const parallelModel = ecModel.queryComponents({
- mainType: 'parallel',
- index: (seriesModel as ParallelSeriesModel).get('parallelIndex'),
- id: (seriesModel as ParallelSeriesModel).get('parallelId')
- })[0] as ParallelModel;
+ const parallelModel = seriesModel.getReferringComponents(
+ 'parallel', SINGLE_REFERRING
+ ).models[0] as ParallelModel;
seriesModel.coordinateSystem = parallelModel.coordinateSystem;
}
});
diff --git a/src/coord/polar/AxisModel.ts b/src/coord/polar/AxisModel.ts
index 84efdd4..d2acf4d 100644
--- a/src/coord/polar/AxisModel.ts
+++ b/src/coord/polar/AxisModel.ts
@@ -25,6 +25,7 @@ import { AxisBaseOption } from '../axisCommonTypes';
import AngleAxis from './AngleAxis';
import RadiusAxis from './RadiusAxis';
import { AxisBaseModel } from '../AxisBaseModel';
+import { SINGLE_REFERRING } from '../../util/model';
export interface AngleAxisOption extends AxisBaseOption {
/**
@@ -66,11 +67,7 @@ class PolarAxisModel<T extends PolarAxisOption = PolarAxisOption> extends Compon
axis: AngleAxis | RadiusAxis;
getCoordSysModel(): ComponentModel {
- return this.ecModel.queryComponents({
- mainType: 'polar',
- index: this.option.polarIndex,
- id: this.option.polarId
- })[0];
+ return this.getReferringComponents('polar', SINGLE_REFERRING).models[0];
}
}
diff --git a/src/coord/polar/polarCreator.ts b/src/coord/polar/polarCreator.ts
index 04789dd..4c807c3 100644
--- a/src/coord/polar/polarCreator.ts
+++ b/src/coord/polar/polarCreator.ts
@@ -39,6 +39,7 @@ import AngleAxis from './AngleAxis';
import { PolarAxisModel, AngleAxisModel, RadiusAxisModel } from './AxisModel';
import SeriesModel from '../../model/Series';
import { SeriesOption } from '../../util/types';
+import { SINGLE_REFERRING } from '../../util/model';
/**
* Resize method bound to the polar
@@ -164,11 +165,9 @@ const polarCreator = {
polarId?: string
}>) {
if (seriesModel.get('coordinateSystem') === 'polar') {
- const polarModel = ecModel.queryComponents({
- mainType: 'polar',
- index: seriesModel.get('polarIndex'),
- id: seriesModel.get('polarId')
- })[0] as PolarModel;
+ const polarModel = seriesModel.getReferringComponents(
+ 'polar', SINGLE_REFERRING
+ ).models[0] as PolarModel;
if (__DEV__) {
if (!polarModel) {
diff --git a/src/coord/single/singleCreator.ts b/src/coord/single/singleCreator.ts
index 6f58e1f..ba432cf 100644
--- a/src/coord/single/singleCreator.ts
+++ b/src/coord/single/singleCreator.ts
@@ -28,6 +28,7 @@ import ExtensionAPI from '../../ExtensionAPI';
import SingleAxisModel from './AxisModel';
import SeriesModel from '../../model/Series';
import { SeriesOption } from '../../util/types';
+import { SINGLE_REFERRING } from '../../util/model';
/**
* Create single coordinate system and inject it into seriesModel.
@@ -50,11 +51,9 @@ function create(ecModel: GlobalModel, api: ExtensionAPI) {
singleAxisId?: string
}>) {
if (seriesModel.get('coordinateSystem') === 'singleAxis') {
- const singleAxisModel = ecModel.queryComponents({
- mainType: 'singleAxis',
- index: seriesModel.get('singleAxisIndex'),
- id: seriesModel.get('singleAxisId')
- })[0] as SingleAxisModel;
+ const singleAxisModel = seriesModel.getReferringComponents(
+ 'singleAxis', SINGLE_REFERRING
+ ).models[0] as SingleAxisModel;
seriesModel.coordinateSystem = singleAxisModel && singleAxisModel.coordinateSystem;
}
});
diff --git a/src/model/Component.ts b/src/model/Component.ts
index f3bfc6d..f03a0e5 100644
--- a/src/model/Component.ts
+++ b/src/model/Component.ts
@@ -29,7 +29,7 @@ import {
ClassManager,
mountExtend
} from '../util/clazz';
-import {makeInner, ModelFinderIndexQuery, queryReferringComponents, ModelFinderIdQuery} from '../util/model';
+import {makeInner, ModelFinderIndexQuery, queryReferringComponents, ModelFinderIdQuery, QueryReferringOpt} from '../util/model';
import * as layout from '../util/layout';
import GlobalModel from './Global';
import {
@@ -276,7 +276,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
* If axis index / axis id not specified, use the first target as default.
* In other cases like dataZoom refer axis, if not specified, measn no refer.
*/
- getReferringComponents(mainType: ComponentMainType, useDefault: boolean): {
+ getReferringComponents(mainType: ComponentMainType, opt: QueryReferringOpt): {
// Always be array rather than null/undefined, which is convenient to use.
models: ComponentModel[];
// Whether target compoent specified
@@ -292,7 +292,7 @@ class ComponentModel<Opt extends ComponentOption = ComponentOption> extends Mode
index: this.get(indexKey, true) as unknown as ModelFinderIndexQuery,
id: this.get(idKey, true) as unknown as ModelFinderIdQuery
},
- useDefault
+ opt
);
}
diff --git a/src/model/referHelper.ts b/src/model/referHelper.ts
index 0f6d46c..03500f9 100644
--- a/src/model/referHelper.ts
+++ b/src/model/referHelper.ts
@@ -32,6 +32,7 @@ import SeriesModel from './Series';
import type PolarModel from '../coord/polar/PolarModel';
import type { SeriesOption, SeriesOnCartesianOptionMixin } from '../util/types';
import type { AxisBaseModel } from '../coord/AxisBaseModel';
+import { SINGLE_REFERRING } from '../util/model';
/**
* @class
@@ -94,8 +95,8 @@ const fetchers: Record<SupportedCoordSys, Fetcher> = {
cartesian2d: function (
seriesModel: SeriesModel<SeriesOption & SeriesOnCartesianOptionMixin>, result, axisMap, categoryAxisMap
) {
- const xAxisModel = seriesModel.getReferringComponents('xAxis', true).models[0] as AxisBaseModel;
- const yAxisModel = seriesModel.getReferringComponents('yAxis', true).models[0] as AxisBaseModel;
+ const xAxisModel = seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0] as AxisBaseModel;
+ const yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0] as AxisBaseModel;
if (__DEV__) {
if (!xAxisModel) {
@@ -129,7 +130,9 @@ const fetchers: Record<SupportedCoordSys, Fetcher> = {
},
singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
- const singleAxisModel = seriesModel.getReferringComponents('singleAxis', true).models[0] as AxisBaseModel;
+ const singleAxisModel = seriesModel.getReferringComponents(
+ 'singleAxis', SINGLE_REFERRING
+ ).models[0] as AxisBaseModel;
if (__DEV__) {
if (!singleAxisModel) {
@@ -147,7 +150,7 @@ const fetchers: Record<SupportedCoordSys, Fetcher> = {
},
polar: function (seriesModel, result, axisMap, categoryAxisMap) {
- const polarModel = seriesModel.getReferringComponents('polar', true).models[0] as PolarModel;
+ const polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0] as PolarModel;
const radiusAxisModel = polarModel.findAxisModel('radiusAxis');
const angleAxisModel = polarModel.findAxisModel('angleAxis');
diff --git a/src/util/model.ts b/src/util/model.ts
index 8247a49..6225339 100644
--- a/src/util/model.ts
+++ b/src/util/model.ts
@@ -744,7 +744,7 @@ export function parseFinder(
}
const defaultMainType = opt ? opt.defaultMainType : null;
- const queryOptionMap = createHashMap<QueryReferringComponentsOption, ComponentMainType>();
+ const queryOptionMap = createHashMap<QueryReferringOption, ComponentMainType>();
const result = {} as ParsedModelFinder;
each(finder, function (value, key) {
@@ -756,7 +756,7 @@ export function parseFinder(
const parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
const mainType = parsedKey[1];
- const queryType = (parsedKey[2] || '').toLowerCase() as keyof QueryReferringComponentsOption;
+ const queryType = (parsedKey[2] || '').toLowerCase() as keyof QueryReferringOption;
if (
!mainType
@@ -776,7 +776,11 @@ export function parseFinder(
ecModel,
mainType,
queryOption,
- mainType === defaultMainType
+ {
+ useDefault: mainType === defaultMainType,
+ enableAll: true,
+ enableNone: true
+ }
);
result[mainType + 'Models'] = queryResult.models;
result[mainType + 'Model'] = queryResult.models[0];
@@ -785,26 +789,38 @@ export function parseFinder(
return result;
}
-type QueryReferringComponentsOption = {
+type QueryReferringOption = {
index?: ModelFinderIndexQuery,
id?: ModelFinderIdQuery,
name?: ModelFinderNameQuery,
};
+export const SINGLE_REFERRING: QueryReferringOpt = { useDefault: true, enableAll: false, enableNone: false };
+export const MULTIPLE_REFERRING: QueryReferringOpt = { useDefault: false, enableAll: true, enableNone: true };
+
+export type QueryReferringOpt = {
+ // Whether to use the first componet as the default if none of index/id/name are specified.
+ useDefault: boolean;
+ // Whether to enable `'all'` on index option.
+ enableAll: boolean;
+ // Whether to enable `'none'`/`false` on index option.
+ enableNone: boolean;
+};
+
export function queryReferringComponents(
ecModel: GlobalModel,
mainType: ComponentMainType,
- option: QueryReferringComponentsOption,
- useDefault?: boolean
+ userOption: QueryReferringOption,
+ opt: QueryReferringOpt
): {
// Always be array rather than null/undefined, which is convenient to use.
models: ComponentModel[];
// Whether there is indexOption/id/name specified
specified: boolean;
} {
- let indexOption = option.index;
- let idOption = option.id;
- let nameOption = option.name;
+ let indexOption = userOption.index;
+ let idOption = userOption.id;
+ let nameOption = userOption.name;
const result = {
models: null as ComponentModel[],
@@ -815,12 +831,13 @@ export function queryReferringComponents(
// Use the first as default if `useDefault`.
let firstCmpt;
result.models = (
- useDefault && (firstCmpt = ecModel.getComponent(mainType))
+ opt.useDefault && (firstCmpt = ecModel.getComponent(mainType))
) ? [firstCmpt] : [];
return result;
}
if (indexOption === 'none' || indexOption === false) {
+ assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.');
result.models = [];
return result;
}
@@ -828,6 +845,7 @@ export function queryReferringComponents(
// `queryComponents` will return all components if
// both all of index/id/name are null/undefined.
if (indexOption === 'all') {
+ assert(opt.enableAll, '`"all"` is not a valid value on index option.');
indexOption = idOption = nameOption = null;
}
result.models = ecModel.queryComponents({
diff --git a/test/dataZoom-feature.html b/test/dataZoom-feature.html
index 520ce6e..9d42ccc 100644
--- a/test/dataZoom-feature.html
+++ b/test/dataZoom-feature.html
@@ -93,7 +93,7 @@ under the License.
var chart = testHelper.create(echarts, 'refer_by_id', {
title: [
'refer axis by id',
- 'Two grids, dataZoom should refer to the second grid',
+ 'Two grids, dataZoom should **only refer to the bottom grid**',
],
option: option,
height: 300,
diff --git a/test/option-replaceMerge.html b/test/option-replaceMerge.html
index 1c8ff5f..0ed8388 100644
--- a/test/option-replaceMerge.html
+++ b/test/option-replaceMerge.html
@@ -920,72 +920,78 @@ under the License.
<script>
require(['echarts'], function (echarts) {
- var option;
+ function makePartialOption() {
+ return {
+ grid: [{
+ bottom: '60%'
+ }, {
+ id: 'gb',
+ top: '60%'
+ }],
+ xAxis: [{
+ type: 'category'
+ }, {
+ type: 'category'
+ }, {
+ id: 'xb0',
+ type: 'category',
+ gridIndex: 1
+ }, {
+ id: 'xb1',
+ type: 'category',
+ gridIndex: 1
+ }],
+ yAxis: [{
- option = {
- // toolbox: {
- // left: 'center',
- // feature: {
- // dataZoom: {}
- // }
- // },
- grid: [{
- bottom: '60%'
- }, {
- id: 'gb',
- top: '60%'
- }],
- xAxis: [{
- type: 'category'
- }, {
- type: 'category'
- }, {
- id: 'xb0',
- type: 'category',
- gridIndex: 1
- }, {
- id: 'xb1',
- type: 'category',
- gridIndex: 1
- }],
- yAxis: [{
+ }, {
+ id: 'yb',
+ gridIndex: 1
+ }],
+ series: [{
+ type: 'line',
+ data: [[11, 22], [33, 44]]
+ }, {
+ type: 'line',
+ xAxisIndex: 1,
+ data: [[11111, 52], [21133, 74]]
+ }, {
+ id: 'sb0',
+ type: 'line',
+ xAxisIndex: 2,
+ yAxisIndex: 1,
+ data: [[23, 432], [54, 552]]
+ }, {
+ id: 'sb1',
+ type: 'line',
+ xAxisIndex: 3,
+ yAxisIndex: 1,
+ data: [[222233, 1432], [111154, 1552]]
+ }]
+ };
+ }
- }, {
- id: 'yb',
- gridIndex: 1
- }],
+ var option = echarts.util.extend(makePartialOption(), {
+ toolbox: {
+ left: 'center',
+ feature: {
+ dataZoom: {}
+ }
+ },
dataZoom: [{
- type: 'slider'
- }, {
- type: 'inside'
- }],
- series: [{
- type: 'line',
- data: [[11, 22], [33, 44]]
- }, {
- type: 'line',
- xAxisIndex: 1,
- data: [[11111, 52], [21133, 74]]
- }, {
- id: 'sb0',
- type: 'line',
- xAxisIndex: 2,
- yAxisIndex: 1,
- data: [[23, 432], [54, 552]]
+ type: 'slider',
+ xAxisIndex: 'all'
}, {
- id: 'sb1',
- type: 'line',
- xAxisIndex: 3,
- yAxisIndex: 1,
- data: [[222233, 1432], [111154, 1552]]
+ type: 'inside',
+ xAxisIndex: 'all'
}]
- };
+ });
var chart = testHelper.create(echarts, 'main_replaceMerge_if_not_declared_in_option', {
title: [
+ 'DataZoom controlls all of the axes.',
'Click btn "remove all grids".',
'Should no error.',
- 'Click btn "addback the first grid".',
+ 'Click btn "addback".',
'Functionalities should be OK.'
],
option: option,
@@ -997,6 +1003,11 @@ under the License.
// Not declared in option
}, { replaceMerge: ['grid', 'xAxis', 'yAxis', 'series'] });
}
+ }, {
+ text: 'addback',
+ onclick: function () {
+ chart.setOption(makePartialOption());
+ }
}]
});
});
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@echarts.apache.org
For additional commands, e-mail: commits-help@echarts.apache.org