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