Skip to content

Commit

Permalink
[dataZoom] Fix #4896 (enable toolbox data zoom control multiple axes)
Browse files Browse the repository at this point in the history
  • Loading branch information
100pah committed Jan 23, 2017
1 parent 6db590e commit 9cd054e
Show file tree
Hide file tree
Showing 16 changed files with 1,202 additions and 491 deletions.
5 changes: 2 additions & 3 deletions src/component/brush/BrushView.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ define(function (require) {
var zrUtil = require('zrender/core/util');
var BrushController = require('../helper/BrushController');
var echarts = require('../../echarts');
var brushHelper = require('../helper/brushHelper');

return echarts.extendComponentView({

Expand Down Expand Up @@ -74,7 +73,7 @@ define(function (require) {
_onBrush: function (areas, opt) {
var modelId = this.model.id;

brushHelper.parseOutputRanges(areas, this.model.coordInfoList, this.ecModel);
this.model.brushTargetManager.setOutputRanges(areas, this.ecModel);

// Action is not dispatched on drag end, because the drag end
// emits the same params with the last drag move event, and
Expand All @@ -93,7 +92,7 @@ define(function (require) {
function updateController(brushModel, ecModel, api, payload) {
// Do not update controller when drawing.
(!payload || payload.$from !== brushModel.id) && this._brushController
.setPanels(brushHelper.makePanelOpts(brushModel.coordInfoList))
.setPanels(brushModel.brushTargetManager.makePanelOpts())
.enableBrush(brushModel.brushOption)
.updateCovers(brushModel.areas.slice());
}
Expand Down
8 changes: 4 additions & 4 deletions src/component/brush/visualEncoding.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ define(function (require) {
var BoundingRect = require('zrender/core/BoundingRect');
var selector = require('./selector');
var throttle = require('../../util/throttle');
var brushHelper = require('../helper/brushHelper');
var BrushTargetManager = require('../helper/BrushTargetManager');

var STATE_LIST = ['inBrush', 'outOfBrush'];
var DISPATCH_METHOD = '__ecBrushSelect';
Expand All @@ -26,9 +26,9 @@ define(function (require) {
payload.key === 'brush' ? payload.brushOption : {brushType: false}
);

brushModel.coordInfoList = brushHelper.makeCoordInfoList(brushModel.option, ecModel);
var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel);

brushHelper.parseInputRanges(brushModel, ecModel);
brushTargetManager.setInputRanges(brushModel.areas, ecModel);
});
});

Expand Down Expand Up @@ -138,7 +138,7 @@ define(function (require) {

zrUtil.each(areas, function (area) {
selectorsByBrushType[area.brushType]
&& brushHelper.controlSeries(area, brushModel, seriesModel)
&& brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel)
&& rangeInfoList.push(area);
hasBrushExists |= brushed(rangeInfoList);
});
Expand Down
27 changes: 21 additions & 6 deletions src/component/dataZoom/AxisProxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ define(function(require) {
var dataExtent = this._dataExtent;
var axisModel = this.getAxisModel();
var scale = axisModel.axis.scale;
var rangePropMode = this._dataZoomModel.getRangePropMode();
var percentExtent = [0, 100];
var percentWindow = [
opt.start,
Expand All @@ -182,11 +183,19 @@ define(function(require) {
var boundValue = valueWindow[idx];
var boundPercent = percentWindow[idx];

// start/end has higher priority over startValue/endValue,
// because start/end can be consistent among different type
// of axis but startValue/endValue not.

if (boundPercent != null || boundValue == null) {
// Notice: dataZoom is based either on `percentProp` ('start', 'end') or
// on `valueProp` ('startValue', 'endValue'). The former one is suitable
// for cases that a dataZoom component controls multiple axes with different
// unit or extent, and the latter one is suitable for accurate zoom by pixel
// (e.g., in dataZoomSelect). `valueProp` can be calculated from `percentProp`,
// but it is awkward that `percentProp` can not be obtained from `valueProp`
// accurately (because all of values that are overflow the `dataExtent` will
// be calculated to percent '100%'). So we have to use
// `dataZoom.getRangePropMode()` to mark which prop is used.
// `rangePropMode` is updated only when setOption or dispatchAction, otherwise
// it remains its original value.

if (rangePropMode[idx] === 'percent') {
if (boundPercent == null) {
boundPercent = percentExtent[idx];
}
Expand All @@ -195,11 +204,15 @@ define(function(require) {
boundPercent, percentExtent, dataExtent, true
));
}
else { // boundPercent == null && boundValue != null
else {
// Calculating `percent` from `value` may be not accurate, because
// This calculation can not be inversed, because all of values that
// are overflow the `dataExtent` will be calculated to percent '100%'
boundPercent = numberUtil.linearMap(
boundValue, dataExtent, percentExtent, true
);
}

// valueWindow[idx] = round(boundValue);
// percentWindow[idx] = round(boundPercent);
valueWindow[idx] = boundValue;
Expand Down Expand Up @@ -228,7 +241,9 @@ define(function(require) {
this._dataExtent = calculateDataExtent(
this._dimName, this.getTargetSeriesModels()
);

var dataWindow = this.calculateDataWindow(dataZoomModel.option);

this._valueWindow = dataWindow.valueWindow;
this._percentWindow = dataWindow.percentWindow;

Expand Down
66 changes: 54 additions & 12 deletions src/component/dataZoom/DataZoomModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ define(function(require) {
*/
this._autoThrottle = true;

/**
* 'percent' or 'value'
* @private
*/
this._rangePropMode = ['percent', 'percent'];

var rawOption = retrieveRaw(option);

this.mergeDefaultAndTheme(option, ecModel);
Expand Down Expand Up @@ -115,8 +121,17 @@ define(function(require) {

this._setDefaultThrottle(rawOption);

processRangeProp('start', 'startValue', rawOption, thisOption);
processRangeProp('end', 'endValue', rawOption, thisOption);
updateRangeUse(this, rawOption);

each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
// start/end has higher priority over startValue/endValue if they
// both set, but we should make chart.setOption({endValue: 1000})
// effective, rather than chart.setOption({endValue: 1000, end: null}).
if (this._rangePropMode[index] === 'value') {
thisOption[names[0]] = null;
}
// Otherwise do nothing and use the merge result.
}, this);

this.textStyleModel = this.getModel('textStyle');

Expand Down Expand Up @@ -380,10 +395,25 @@ define(function(require) {
}, this);
},

/**
* @param {string} dimName
* @param {number} axisIndex
* @return {module:echarts/component/dataZoom/AxisProxy} If not found, return null/undefined.
*/
getAxisProxy: function (dimName, axisIndex) {
return this._axisProxies[dimName + '_' + axisIndex];
},

/**
* @param {string} dimName
* @param {number} axisIndex
* @return {module:echarts/model/Model} If not found, return null/undefined.
*/
getAxisModel: function (dimName, axisIndex) {
var axisProxy = this.getAxisProxy(dimName, axisIndex);
return axisProxy && axisProxy.getAxisModel();
},

/**
* If not specified, set to undefined.
*
Expand All @@ -393,14 +423,17 @@ define(function(require) {
* @param {number} [opt.end]
* @param {number} [opt.startValue]
* @param {number} [opt.endValue]
* @param {boolean} [ignoreUpdateRangeUsg=false]
*/
setRawRange: function (opt) {
setRawRange: function (opt, ignoreUpdateRangeUsg) {
each(['start', 'end', 'startValue', 'endValue'], function (name) {
// If any of those prop is null/undefined, we should alos set
// them, because only one pair between start/end and
// startValue/endValue can work.
this.option[name] = opt[name];
}, this);

!ignoreUpdateRangeUsg && updateRangeUse(this, opt);
},

/**
Expand Down Expand Up @@ -457,8 +490,14 @@ define(function(require) {
return axisProxies[key];
}
}
}
},

/**
* @return {Array.<string>}
*/
getRangePropMode: function () {
return this._rangePropMode.slice();
}
});

function retrieveRaw(option) {
Expand All @@ -472,14 +511,17 @@ define(function(require) {
return ret;
}

function processRangeProp(percentProp, valueProp, rawOption, thisOption) {
// start/end has higher priority over startValue/endValue,
// but we should make chart.setOption({endValue: 1000}) effective,
// rather than chart.setOption({endValue: 1000, end: null}).
if (rawOption[valueProp] != null && rawOption[percentProp] == null) {
thisOption[percentProp] = null;
}
// Otherwise do nothing and use the merge result.
function updateRangeUse(dataZoomModel, rawOption) {
each([['start', 'startValue'], ['end', 'endValue']], function (names, index) {
var rangePropMode = dataZoomModel._rangePropMode;
if (rawOption[names[0]] != null) {
rangePropMode[index] = 'percent';
}
else if (rawOption[names[1]] != null) {
rangePropMode[index] = 'value';
}
// else remain its original setting.
});
}

return DataZoomModel;
Expand Down
2 changes: 1 addition & 1 deletion src/component/dataZoom/dataZoomProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ define(function (require) {
end: percentRange[1],
startValue: valueRange[0],
endValue: valueRange[1]
});
}, true);
});
});

Expand Down
33 changes: 29 additions & 4 deletions src/component/helper/BrushController.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,17 @@ define(function (require) {

/**
* Only for drawing (after enabledBrush).
* 'line', 'rect', 'polygon' or false
* If passing false/null/undefined, disable brush.
* If passing 'auto', determined by panel.defaultBrushType
* @private
* @type {string}
*/
this._brushType;

/**
* Only for drawing (after enabledBrush).
*
* @private
* @type {Object}
*/
Expand Down Expand Up @@ -178,7 +182,9 @@ define(function (require) {
* If set to null/undefined/false, select disabled.
* @param {Object} brushOption
* @param {string|boolean} brushOption.brushType 'line', 'rect', 'polygon' or false
* If pass false/null/undefined, disable brush.
* If passing false/null/undefined, disable brush.
* If passing 'auto', determined by panel.defaultBrushType.
* ('auto' can not be used in global panel)
* @param {number} [brushOption.brushMode='single'] 'single' or 'multiple'
* @param {boolean} [brushOption.transformable=true]
* @param {boolean} [brushOption.removeOnClick=false]
Expand All @@ -201,7 +207,11 @@ define(function (require) {

/**
* @param {Array.<Object>} panelOpts If not pass, it is global brush.
* Each items: {panelId, rect}
* Each items: {
* panelId, // mandatory.
* rect, // mandatory.
* defaultBrushType // optional, only used when brushType is 'auto'.
* }
*/
setPanels: function (panelOpts) {
var oldPanels = this._panels || {};
Expand All @@ -227,6 +237,7 @@ define(function (require) {

panel.attr('shape', rect.plain());
panel.__brushPanelId = panelId;
panel.__defaultBrushType = panelOpt.defaultBrushType;
newPanels[panelId] = panel;
oldPanels[panelId] = null;
});
Expand Down Expand Up @@ -278,7 +289,7 @@ define(function (require) {
* {id: 'yy', brushType: 'rect', range: [[23, 44], [23, 54]]},
* ...
* ]
* `brushType` is required in each cover info.
* `brushType` is required in each cover info. (can not be 'auto')
* `id` is not mandatory.
* `brushStyle`, `transformable` is not mandatory, use DEFAULT_BRUSH_OPT by default.
* If brushOptionList is null/undefined, all covers removed.
Expand Down Expand Up @@ -764,13 +775,14 @@ define(function (require) {
if (panel && !creatingCover) {
thisBrushOption.brushMode === 'single' && clearCovers(controller);
var brushOption = zrUtil.clone(thisBrushOption);
brushOption.brushType = determineBrushType(brushOption.brushType, panel);
brushOption.panelId = panel === true ? null : panel.__brushPanelId;
creatingCover = controller._creatingCover = createCover(controller, brushOption);
controller._covers.push(creatingCover);
}

if (creatingCover) {
var coverRenderer = coverRenderers[controller._brushType];
var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)];
var coverBrushOption = creatingCover.__brushOption;

coverBrushOption.range = coverRenderer.getCreatingRange(
Expand Down Expand Up @@ -805,6 +817,19 @@ define(function (require) {
return eventParams;
}

function determineBrushType(brushType, panel) {
if (brushType === 'auto') {
if (__DEV__) {
zrUtil.assert(
panel && panel.__defaultBrushType,
'MUST have defaultBrushType when brushType is "atuo"'
);
}
return panel.__defaultBrushType;
}
return brushType;
}

var mouseHandlers = {

mousedown: function (e) {
Expand Down

0 comments on commit 9cd054e

Please sign in to comment.