提交 21a145f7 编写于 作者: 1 100pah

[dataZoom] Fix #4090 :enable dataZoom on polar

上级 0de7f3cd
......@@ -236,11 +236,13 @@ define(function (require) {
_updateController: function (seriesModel, api) {
var controller = this._controller;
var group = this.group;
controller.rectProvider = function () {
controller.setContainsPoint(function (x, y) {
var rect = group.getBoundingRect();
rect.applyTransform(group.transform);
return rect;
};
return rect.contain(x, y);
});
if (seriesModel.coordinateSystem.type !== 'view') {
controller.disable();
return;
......
......@@ -375,9 +375,9 @@
}
var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight());
controller.rectProvider = function () {
return rect;
};
controller.setContainsPoint(function (x, y) {
return rect.contain(x, y);
});
},
/**
......@@ -762,7 +762,7 @@
var text = nodeModel.get('name');
if (thisLayout.isLeafRoot) {
var iconChar = seriesModel.get('drillDownIcon', true);
text = iconChar ? iconChar + ' ' + text : test;
text = iconChar ? iconChar + ' ' + text : text;
}
setText(
......
......@@ -30,7 +30,6 @@ define(function(require) {
xAxisIndex: null, // Default the first horizontal category axis.
yAxisIndex: null, // Default the first vertical category axis.
filterMode: 'filter', // Possible values: 'filter' or 'empty'.
// 'filter': data items which are out of window will be removed.
// This option is applicable when filtering outliers.
......
......@@ -42,21 +42,30 @@ define(function (require) {
if (axisModel) {
axisModels.push(axisModel);
var coordSysName;
if (dimNames.axis === 'xAxis' || dimNames.axis === 'yAxis') {
var axisName = dimNames.axis;
if (axisName === 'xAxis' || axisName === 'yAxis') {
coordSysName = 'grid';
}
else {
// Polar
else if (axisName === 'angleAxis' || axisName === 'radiusAxis') {
coordSysName = 'polar';
}
var coordModel = ecModel.queryComponents({
mainType: coordSysName,
index: axisModel.get(coordSysName + 'Index'),
id: axisModel.get(coordSysName + 'Id')
})[0];
var coordModel = coordSysName
? ecModel.queryComponents({
mainType: coordSysName,
index: axisModel.get(coordSysName + 'Index'),
id: axisModel.get(coordSysName + 'Id')
})[0]
: null;
if (coordModel != null) {
save(coordModel, axisModel, coordSysName === 'grid' ? cartesians : polars, coordModel.componentIndex);
save(
coordModel,
axisModel,
coordSysName === 'grid' ? cartesians : polars,
coordModel.componentIndex
);
}
}
}, this);
......
......@@ -11,7 +11,8 @@ define(function(require) {
* @protected
*/
defaultOption: {
zoomLock: false // Whether disable zoom but only pan.
silent: false, // Whether disable this inside zoom.
zoomLock: false // Whether disable zoom but only pan.
}
});
});
\ No newline at end of file
......@@ -36,30 +36,36 @@ define(function (require) {
this._range = dataZoomModel.getPercentRange();
}
var targetInfo = this.getTargetInfo();
// Reset controllers.
var coordInfoList = this.getTargetInfo().cartesians;
var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) {
return roams.generateCoordId(coordInfo.model);
});
zrUtil.each(coordInfoList, function (coordInfo) {
var coordModel = coordInfo.model;
roams.register(
api,
{
coordId: roams.generateCoordId(coordModel),
allCoordIds: allCoordIds,
coordinateSystem: coordModel.coordinateSystem,
dataZoomId: dataZoomModel.id,
throttleRate: dataZoomModel.get('throttle', true),
panGetRange: bind(this._onPan, this, coordInfo),
zoomGetRange: bind(this._onZoom, this, coordInfo)
}
);
}, this);
zrUtil.each(['cartesians', 'polars'], function (coordSysName) {
var coordInfoList = targetInfo[coordSysName];
var allCoordIds = zrUtil.map(coordInfoList, function (coordInfo) {
return roams.generateCoordId(coordInfo.model);
});
zrUtil.each(coordInfoList, function (coordInfo) {
var coordModel = coordInfo.model;
var coordinateSystem = coordModel.coordinateSystem;
roams.register(
api,
{
coordId: roams.generateCoordId(coordModel),
allCoordIds: allCoordIds,
coordinateSystem: coordinateSystem,
containsPoint: bind(operations[coordSysName].containsPoint, this, coordinateSystem),
dataZoomId: dataZoomModel.id,
throttleRate: dataZoomModel.get('throttle', true),
panGetRange: bind(this._onPan, this, coordInfo, coordSysName),
zoomGetRange: bind(this._onZoom, this, coordInfo, coordSysName)
}
);
}, this);
// TODO
// polar支持
}, this);
},
/**
......@@ -74,100 +80,137 @@ define(function (require) {
/**
* @private
*/
_onPan: function (coordInfo, controller, dx, dy) {
return (
this._range = panCartesian(
[dx, dy], this._range, controller, coordInfo
)
);
},
/**
* @private
*/
_onZoom: function (coordInfo, controller, scale, mouseX, mouseY) {
var dataZoomModel = this.dataZoomModel;
if (dataZoomModel.option.zoomLock) {
_onPan: function (coordInfo, coordSysName, controller, dx, dy, oldX, oldY, newX, newY) {
if (this.dataZoomModel.option.silent) {
return this._range;
}
return (
this._range = scaleCartesian(
1 / scale, [mouseX, mouseY], this._range,
controller, coordInfo, dataZoomModel
)
);
}
var range = this._range.slice();
});
// Calculate transform by the first axis.
var axisModel = coordInfo.axisModels[0];
if (!axisModel) {
return;
}
function panCartesian(pixelDeltas, range, controller, coordInfo) {
range = range.slice();
var directionInfo = operations[coordSysName].getDirectionInfo(
[oldX, oldY], [newX, newY], axisModel, controller, coordInfo
);
// Calculate transform by the first axis.
var axisModel = coordInfo.axisModels[0];
if (!axisModel) {
return;
}
var percentDelta = directionInfo.signal
* (range[1] - range[0])
* directionInfo.pixel / directionInfo.pixelLength;
var directionInfo = getDirectionInfo(pixelDeltas, axisModel, controller);
sliderMove(percentDelta, range, [0, 100], 'rigid');
var percentDelta = directionInfo.signal
* (range[1] - range[0])
* directionInfo.pixel / directionInfo.pixelLength;
return (this._range = range);
},
sliderMove(
percentDelta,
range,
[0, 100],
'rigid'
);
/**
* @private
*/
_onZoom: function (coordInfo, coordSysName, controller, scale, mouseX, mouseY) {
var option = this.dataZoomModel.option;
return range;
}
if (option.silent || option.zoomLock) {
return this._range;
}
function scaleCartesian(scale, mousePoint, range, controller, coordInfo, dataZoomModel) {
range = range.slice();
var range = this._range.slice();
// Calculate transform by the first axis.
var axisModel = coordInfo.axisModels[0];
if (!axisModel) {
return;
}
// Calculate transform by the first axis.
var axisModel = coordInfo.axisModels[0];
if (!axisModel) {
return;
}
var directionInfo = getDirectionInfo(mousePoint, axisModel, controller);
var directionInfo = operations[coordSysName].getDirectionInfo(
null, [mouseX, mouseY], axisModel, controller, coordInfo
);
var mouse = directionInfo.pixel - directionInfo.pixelStart;
var percentPoint = mouse / directionInfo.pixelLength * (range[1] - range[0]) + range[0];
var percentPoint = (directionInfo.pixel - directionInfo.pixelStart) /
directionInfo.pixelLength * (range[1] - range[0]) + range[0];
scale = Math.max(scale, 0);
range[0] = (range[0] - percentPoint) * scale + percentPoint;
range[1] = (range[1] - percentPoint) * scale + percentPoint;
scale = Math.max(1 / scale, 0);
range[0] = (range[0] - percentPoint) * scale + percentPoint;
range[1] = (range[1] - percentPoint) * scale + percentPoint;
return (this._range = fixRange(range));
}
return fixRange(range);
}
});
function getDirectionInfo(xy, axisModel, controller) {
var axis = axisModel.axis;
var rect = controller.rectProvider();
var ret = {};
var operations = {
cartesians: {
getDirectionInfo: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
var axis = axisModel.axis;
var ret = {};
var rect = coordInfo.model.coordinateSystem.getRect();
oldPoint = oldPoint || [0, 0];
if (axis.dim === 'x') {
ret.pixel = newPoint[0] - oldPoint[0];
ret.pixelLength = rect.width;
ret.pixelStart = rect.x;
ret.signal = axis.inverse ? 1 : -1;
}
else { // axis.dim === 'y'
ret.pixel = newPoint[1] - oldPoint[1];
ret.pixelLength = rect.height;
ret.pixelStart = rect.y;
ret.signal = axis.inverse ? -1 : 1;
}
return ret;
},
containsPoint: function (coordinateSystem, x, y) {
return coordinateSystem.getRect().contain(x, y);
}
},
if (axis.dim === 'x') {
ret.pixel = xy[0];
ret.pixelLength = rect.width;
ret.pixelStart = rect.x;
ret.signal = axis.inverse ? 1 : -1;
}
else { // axis.dim === 'y'
ret.pixel = xy[1];
ret.pixelLength = rect.height;
ret.pixelStart = rect.y;
ret.signal = axis.inverse ? -1 : 1;
polars: {
getDirectionInfo: function (oldPoint, newPoint, axisModel, controller, coordInfo) {
var axis = axisModel.axis;
var ret = {};
var polar = coordInfo.model.coordinateSystem;
var radiusExtent = polar.getRadiusAxis().getExtent();
var angleExtent = polar.getAngleAxis().getExtent();
oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0];
newPoint = polar.pointToCoord(newPoint);
if (axisModel.mainType === 'radiusAxis') {
ret.pixel = newPoint[0] - oldPoint[0];
// ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]);
// ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]);
ret.pixelLength = radiusExtent[1] - radiusExtent[0];
ret.pixelStart = radiusExtent[0];
ret.signal = axis.inverse ? 1 : -1;
}
else { // 'angleAxis'
ret.pixel = newPoint[1] - oldPoint[1];
// ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]);
// ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]);
ret.pixelLength = angleExtent[1] - angleExtent[0];
ret.pixelStart = angleExtent[0];
ret.signal = axis.inverse ? -1 : 1;
}
return ret;
},
containsPoint: function (coordinateSystem, x, y) {
var radius = coordinateSystem.getRadiusAxis().getExtent()[1];
var cx = coordinateSystem.cx;
var cy = coordinateSystem.cy;
return Math.pow(x - cx, 2) + Math.pow(y - cy, 2) <= Math.pow(radius, 2);
}
}
return ret;
}
};
function fixRange(range) {
// Clamp, using !(<= or >=) to handle NaN.
......
......@@ -23,7 +23,7 @@ define(function(require) {
* @param {module:echarts/ExtensionAPI} api
* @param {Object} dataZoomInfo
* @param {string} dataZoomInfo.coordId
* @param {Object} dataZoomInfo.coordinateSystem
* @param {Function} dataZoomInfo.containsPoint
* @param {Array.<string>} dataZoomInfo.allCoordIds
* @param {string} dataZoomInfo.dataZoomId
* @param {number} dataZoomInfo.throttleRate
......@@ -62,10 +62,7 @@ define(function(require) {
}
// Consider resize, area should be always updated.
var rect = dataZoomInfo.coordinateSystem.getRect().clone();
record.controller.rectProvider = function () {
return rect;
};
record.controller.setContainsPoint(dataZoomInfo.containsPoint);
// Update throttle.
throttle.createOrUpdate(
......@@ -150,9 +147,9 @@ define(function(require) {
});
}
function onPan(record, dx, dy) {
function onPan(record, dx, dy, oldX, oldY, newX, newY) {
wrapAndDispatch(record, function (info) {
return info.panGetRange(record.controller, dx, dy);
return info.panGetRange(record.controller, dx, dy, oldX, oldY, newX, newY);
});
}
......
......@@ -285,9 +285,9 @@ define(function (require) {
}
}, this);
controller.rectProvider = function () {
return geo.getViewRectAfterRoam();
};
controller.setContainsPoint(function (x, y) {
return geo.getViewRectAfterRoam().contain(x, y);
});
}
};
......
......@@ -16,8 +16,8 @@ define(function (require) {
var x = e.offsetX;
var y = e.offsetY;
var rect = this.rectProvider && this.rectProvider();
if (rect && rect.contain(x, y)) {
if (this.containsPoint && this.containsPoint(x, y)) {
this._x = x;
this._y = y;
this._dragging = true;
......@@ -40,8 +40,11 @@ define(function (require) {
var x = e.offsetX;
var y = e.offsetY;
var dx = x - this._x;
var dy = y - this._y;
var oldX = this._x;
var oldY = this._y;
var dx = x - oldX;
var dy = y - oldY;
this._x = x;
this._y = y;
......@@ -56,7 +59,7 @@ define(function (require) {
}
eventTool.stop(e.event);
this.trigger('pan', dx, dy);
this.trigger('pan', dx, dy, oldX, oldY, x, y);
}
}
......@@ -81,9 +84,7 @@ define(function (require) {
}
function zoom(e, zoomDelta, zoomX, zoomY) {
var rect = this.rectProvider && this.rectProvider();
if (rect && rect.contain(zoomX, zoomY)) {
if (this.containsPoint && this.containsPoint(zoomX, zoomY)) {
// When mouse is out of roamController rect,
// default befavoius should be be disabled, otherwise
// page sliding is disabled, contrary to expectation.
......@@ -128,9 +129,8 @@ define(function (require) {
*
* @param {module:zrender/zrender~ZRender} zr
* @param {module:zrender/Element} target
* @param {Function} [rectProvider]
*/
function RoamController(zr, target, rectProvider) {
function RoamController(zr, target) {
/**
* @type {module:zrender/Element}
......@@ -140,7 +140,7 @@ define(function (require) {
/**
* @type {Function}
*/
this.rectProvider = rectProvider;
this.containsPoint;
/**
* { min: 1, max: 2 }
......@@ -167,6 +167,15 @@ define(function (require) {
Eventful.call(this);
/**
* @param {Function} containsPoint
* input: x, y
* output: boolean
*/
this.setContainsPoint = function (containsPoint) {
this.containsPoint = containsPoint;
};
/**
* Notice: only enable needed types. For example, if 'zoom'
* is not needed, 'zoom' should not be enabled, otherwise
......
define(function (require) {
return {
/**
* @public
* @return {Array.<number|string|Date>}
*/
getMin: function () {
var option = this.option;
return option.rangeStart != null ? option.rangeStart : option.min;
},
/**
* @public
* @return {Array.<number|string|Date>}
*/
getMax: function () {
var option = this.option;
return option.rangeEnd != null ? option.rangeEnd : option.max;
},
/**
* @public
* @return {boolean}
*/
getNeedCrossZero: function () {
var option = this.option;
return (option.rangeStart != null || option.rangeEnd != null)
? false : !option.scale;
},
/**
* @public
* @param {number} rangeStart
* @param {number} rangeEnd
*/
setRange: function (rangeStart, rangeEnd) {
this.option.rangeStart = rangeStart;
this.option.rangeEnd = rangeEnd;
},
/**
* @public
*/
resetRange: function () {
// rangeStart and rangeEnd is readonly.
this.option.rangeStart = this.option.rangeEnd = null;
}
};
});
\ No newline at end of file
......@@ -20,7 +20,7 @@ define(function(require) {
*/
init: function () {
AxisModel.superApply(this, 'init', arguments);
this._resetRange();
this.resetRange();
},
/**
......@@ -28,7 +28,7 @@ define(function(require) {
*/
mergeOption: function () {
AxisModel.superApply(this, 'mergeOption', arguments);
this._resetRange();
this.resetRange();
},
/**
......@@ -36,45 +36,7 @@ define(function(require) {
*/
restoreData: function () {
AxisModel.superApply(this, 'restoreData', arguments);
this._resetRange();
},
/**
* @public
* @param {number} rangeStart
* @param {number} rangeEnd
*/
setRange: function (rangeStart, rangeEnd) {
this.option.rangeStart = rangeStart;
this.option.rangeEnd = rangeEnd;
},
/**
* @public
* @return {Array.<number|string|Date>}
*/
getMin: function () {
var option = this.option;
return option.rangeStart != null ? option.rangeStart : option.min;
},
/**
* @public
* @return {Array.<number|string|Date>}
*/
getMax: function () {
var option = this.option;
return option.rangeEnd != null ? option.rangeEnd : option.max;
},
/**
* @public
* @return {boolean}
*/
getNeedCrossZero: function () {
var option = this.option;
return (option.rangeStart != null || option.rangeEnd != null)
? false : !option.scale;
this.resetRange();
},
/**
......@@ -86,14 +48,6 @@ define(function(require) {
index: this.get('gridIndex'),
id: this.get('gridId')
})[0];
},
/**
* @private
*/
_resetRange: function () {
// rangeStart and rangeEnd is readonly.
this.option.rangeStart = this.option.rangeEnd = null;
}
});
......@@ -104,6 +58,7 @@ define(function(require) {
}
zrUtil.merge(AxisModel.prototype, require('../axisModelCommonMixin'));
zrUtil.merge(AxisModel.prototype, require('../axisModelZoomMixin'));
var extraOption = {
// gridIndex: 0,
......
......@@ -7,14 +7,18 @@ define(function(require) {
var axisModelCreator = require('../axisModelCreator');
var PolarAxisModel = ComponentModel.extend({
type: 'polarAxis',
/**
* @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis}
*/
axis: null
});
zrUtil.merge(PolarAxisModel.prototype, require('../axisModelCommonMixin'));
zrUtil.merge(PolarAxisModel.prototype, require('../axisModelZoomMixin'));
var polarAxisDefaultExtendedOption = {
angle: {
......
......@@ -3,14 +3,26 @@
<meta charset="utf-8">
<script src="esl.js"></script>
<script src="config.js"></script>
<script src="lib/jquery.min.js"></script>
</head>
<body>
<style>
html, body, #main {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
height: 600px;
}
.operations {
margin-top: 10px;
margin-bottom: 30px;
}
</style>
<div class="operations">
<input type="radio" name="inside" value="radius"/> inside zoom radius
<input type="radio" name="inside" value="angle" checked="checked"/> inside zoom angle
<input type="radio" name="inside" value="all"/> inside zoom all
</div>
<div id="main"></div>
<script>
......@@ -51,11 +63,13 @@
},
dataZoom: [
{
id: 'slider-v',
show: true,
orient: 'vertical',
angleAxisIndex: [0]
},
{
id: 'slider-h',
show: true,
orient: 'horizontal',
radiusAxisIndex: [0]
......@@ -89,8 +103,77 @@
data: data3
}]
});
var radioOption = {
radius: {
dataZoom: [
{
silent: true,
id: 'inside-a',
type: 'inside',
angleAxisIndex: 0
},
{
silent: false,
id: 'inside-r',
type: 'inside',
radiusAxisIndex: 0
}
]
},
angle: {
dataZoom: [
{
silent: false,
id: 'inside-a',
type: 'inside',
angleAxisIndex: 0
},
{
silent: true,
id: 'inside-r',
type: 'inside',
radiusAxisIndex: 0
}
]
},
all: {
dataZoom: [
{
silent: false,
id: 'inside-a',
type: 'inside',
angleAxisIndex: [0]
},
{
silent: false,
id: 'inside-r',
type: 'inside',
radiusAxisIndex: [0]
}
]
}
};
initRadio();
chart.setOption(radioOption.angle);
function initRadio() {
$('.operations').on('click', function () {
$('.operations input').each(function (idx, el) {
if (el.checked) {
chart.setOption(radioOption[el.getAttribute('value')]);
}
});
});
}
})
</script>
</body>
</html>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册