diff --git a/src/chart/line/LineView.js b/src/chart/line/LineView.js index 36102f33e0c78f1e2000916e021c9132c31541bd..0f19a7dde5461f2a3ef66cc52e8cccb0b8cced8d 100644 --- a/src/chart/line/LineView.js +++ b/src/chart/line/LineView.js @@ -53,7 +53,7 @@ define(function(require) { var coordinateSystem = seriesModel.coordinateSystem; var isCoordinateSystemPolar = coordinateSystem.type === 'polar'; - // TODO Update after animation + // FIXME Update after animation if ( isCoordinateSystemPolar && points.length > 2 @@ -66,10 +66,11 @@ define(function(require) { // Draw symbols, enable animation on the first draw var dataSymbol = this._dataSymbol; dataSymbol.z = seriesModel.get('z') + 1; - dataSymbol.updateData(data, !this._data); // Initialization animation if (!this._data) { + dataSymbol.updateData(data, false); + var polyline = new api.Polyline({ shape: { points: points @@ -96,9 +97,9 @@ define(function(require) { this._polyline = polyline; } else { + dataSymbol.updateData(data, false); // In the case data zoom triggerred refreshing frequently // Data may not change if line has a category axis. So it should animate nothing - if (! isPointsSame(this._pointsWithName, pointsWithName)) { this._updateAnimation(data, pointsWithName); } diff --git a/src/component/tooltip.js b/src/component/tooltip.js index 593a2e809c97608c47a6dbad70baf63232cf19d4..0571b654f0327322e2fdb0f764e3d35b08d00efe 100644 --- a/src/component/tooltip.js +++ b/src/component/tooltip.js @@ -7,6 +7,36 @@ define(function (require) { return coordName + axisType; } + function makeLineShape(x1, y1, x2, y2) { + return { + x1: x1, + y1: y1, + x2: x2, + y2: y2 + }; + } + + function makeRectShape(x, y, width, height) { + return { + x: x, + y: y, + width: width, + height: height + }; + } + + function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) { + return { + cx: cx, + cy: cy, + r0: r0, + r: r, + startAngle: startAngle, + endAngle: endAngle, + clockwise: true + }; + } + require('./tooltip/TooltipModel'); require('../echarts').extendComponentView({ @@ -69,41 +99,42 @@ define(function (require) { */ _showAxisTooltip: function (e) { var ecModel = this._ecModel; + var tooltipModel = this._tooltipModel; + var axisPointerModel = tooltipModel.getModel('axisPointer'); ecModel.eachSeries(function (seriesModel) { // Try show the axis pointer this.group.show(); - var coordinateSystem = seriesModel.coordinateSystem; + var coordSys = seriesModel.coordinateSystem; // If mouse position is not in the grid or polar var point = [e.offsetX, e.offsetY]; - if (coordinateSystem && ! coordinateSystem.containPoint(point)) { + if (coordSys && ! coordSys.containPoint(point)) { // Hide axis pointer this._hideAxisTooltip(); return; } - if (coordinateSystem.type === 'cartesian2d') { - this._showCartesianAxis(coordinateSystem, point); + if (coordSys.type === 'cartesian2d') { + this._showCartesianPointer(axisPointerModel, coordSys, point); } - else if (coordinateSystem.type === 'polar') { - this._showPolarAxis(coordinateSystem, point); + else if (coordSys.type === 'polar') { + this._showPolarPointer(axisPointerModel, coordSys, point); } }, this) }, /** * Show tooltip on axis of cartesian coordinate - * @param {Object} e + * @param {module:echarts/model/Model} axisPointerModel + * @param {module:echarts/coord/cartesian/Cartesian2D} cartesian + * @param {Array.} point + * @private */ - _showCartesianAxis: function (cartesian, point) { + _showCartesianPointer: function (axisPointerModel, cartesian, point) { var self = this; - var tooltipModel = this._tooltipModel; - - var axisPointerModel = tooltipModel.getModel('axisPointer'); - var cateogryAxis = cartesian.getAxesByScale('ordinal')[0]; var axisPointerType = axisPointerModel.get('type'); @@ -115,62 +146,164 @@ define(function (require) { point = cartesian.dataToPoint(value); } - if (axisPointerType === 'line') { + if (axisPointerType === 'cross') { + moveGridLine('x', point, cartesian.getAxis('y').getExtent()); + moveGridLine('y', point, cartesian.getAxis('x').getExtent()); + } + else { var axisType = axisPointerModel.get('axis'); if (axisType === 'auto') { axisType = (cateogryAxis && cateogryAxis.dim) || 'x'; } - var pointerAxis = cartesian.getAxis(axisType); - var otherAxis = cartesian.getOtherAxis(pointerAxis); + var otherAxis = cartesian.getAxis(axisType === 'x' ? 'y' : 'x'); var otherExtent = otherAxis.getExtent(); - moveLine(axisType, point, otherExtent); + if (cartesian.type === 'cartesian2d') { + (axisPointerType === 'line' ? moveGridLine : moveGridShadow)( + axisType, point, otherExtent + ); + } } - else if (axisPointerType === 'cross') { - moveLine('x', point, cartesian.getAxis('y').getExtent()); - moveLine('y', point, cartesian.getAxis('x').getExtent()); + + /** + * @inner + */ + function moveGridLine(axisType, point, otherExtent) { + var pointerEl = self._getPointerElement(cartesian, axisPointerModel, axisType) + var targetShape = axisType === 'x' + ? makeLineShape(point[0], otherExtent[0], point[0], otherExtent[1]) + : makeLineShape(otherExtent[0], point[1], otherExtent[1], point[1]); + + // pointerEl.animateTo({ + // shape: targetShape + // }, 100, 'cubicOut'); + pointerEl.attr({ + shape: targetShape + }); } - else if (axisPointerType === 'shadow') { + /** + * @inner + */ + function moveGridShadow(axisType, point, otherExtent) { + var axis = cartesian.getAxis(axisType); + var pointerEl = self._getPointerElement(cartesian, axisPointerModel, axisType); + var bandWidth = axis.getBandWidth(); + var extentSize = otherExtent[1] - otherExtent[0]; + var targetShape = axisType === 'x' + ? makeRectShape(point[0] - bandWidth / 2, otherExtent[0], bandWidth, extentSize) + : makeRectShape(otherExtent[0], point[1] - bandWidth / 2, extentSize, bandWidth); + + // FIXME 动画总是感觉不连贯 + // pointerEl.animateTo({ + // shape: targetShape + // }, 100, 'cubicOut'); + pointerEl.attr({ + shape: targetShape + }); } - function moveLine(axisType, point, otherExtent) { + }, + + /** + * Show tooltip on axis of polar coordinate + * @param {module:echarts/model/Model} axisPointerModel + * @param {module:echarts/coord/polar/Polar} polar + * @param {Array.} point + */ + _showPolarPointer: function (axisPointerModel, polar, point) { + var self = this; + + var axisPointerType = axisPointerModel.get('type'); + + var value = polar.pointToData(point); + var angleAxis = polar.getAngleAxis(); + var radiusAxis = polar.getRadiusAxis(); + + // Make sure point is discrete on cateogry axis + point = polar.dataToPoint(value); + + if (axisPointerType === 'cross') { + movePolarLine('angle', point, angleAxis.getExtent()); + movePolarLine('radius', point, radiusAxis.getExtent()); + } + else { + var axisType = axisPointerModel.get('axis'); + if (axisType === 'auto') { + axisType = radiusAxis.type === 'category' ? 'radius' : 'angle'; + } + + var otherAxis = polar.getAxis(axisType === 'radius' ? 'angle' : 'radius'); + var otherExtent = otherAxis.getExtent(); + + (axisPointerType === 'line' ? movePolarLine : movePolarShadow)( + axisType, point, otherExtent + ); + } + /** + * @inner + */ + function movePolarLine(axisType, point, otherExtent) { + var pointerEl = self._getPointerElement(polar, axisPointerModel, axisType); + + var mouseCoord = polar.pointToCoord(point); - var pointerEl = self._getPointerElement(cartesian, axisPointerModel, axisType) var targetShape; - if (axisType === 'x') { - targetShape = { - x1: point[0], - y1: otherExtent[0], - x2: point[0], - y2: otherExtent[1] - }; + + if (axisType === 'angle') { + var p1 = polar.coordToPoint([otherExtent[0], mouseCoord[1]]); + var p2 = polar.coordToPoint([otherExtent[1], mouseCoord[1]]); + targetShape = makeLineShape(p1[0], p1[1], p2[0], p2[1]); } else { targetShape = { - x1: otherExtent[0], - y1: point[1], - x2: otherExtent[1], - y2: point[1] + cx: polar.cx, + cy: polar.cy, + r: mouseCoord[0] }; } - // pointerEl.animateTo({ - // shape: targetShape - // }, 100, 'cubicOut'); pointerEl.attr({ shape: targetShape - }) + }); } - }, - /** - * Show tooltip on axis of polar coordinate - * @param {Object} e - */ - _showPolarAxis: function () { + /** + * @inner + */ + function movePolarShadow(axisType, point, otherExtent) { + var axis = polar.getAxis(axisType); + var pointerEl = self._getPointerElement(polar, axisPointerModel, axisType) + var bandWidth = axis.getBandWidth(); + + var mouseCoord = polar.pointToCoord(point); + var targetShape; + + var radian = Math.PI / 180; + + if (axisType === 'angle') { + targetShape = makeSectorShape( + polar.cx, polar.cy, + otherExtent[0], otherExtent[1], + (mouseCoord[1] - bandWidth / 2) * radian, + (mouseCoord[1] + bandWidth / 2) * radian + ); + } + else { + targetShape = makeSectorShape( + polar.cx, polar.cy, + mouseCoord[0] - bandWidth / 2, + mouseCoord[0] + bandWidth / 2, + 0, Math.PI * 2 + ); + } + + pointerEl.attr({ + shape: targetShape + }); + } }, /** @@ -180,9 +313,9 @@ define(function (require) { this.group.hide(); }, - _getPointerElement: function (coordSystem, pointerModel, axisType) { + _getPointerElement: function (coordSys, pointerModel, axisType) { var axisPointers = this._axisPointers; - var key = getAxisPointerKey(coordSystem.name, axisType); + var key = getAxisPointerKey(coordSys.name, axisType); if (axisPointers[key]) { return axisPointers[key]; } @@ -193,10 +326,12 @@ define(function (require) { var isShadow = pointerType === 'shadow'; var style = styleModel[isShadow ? 'getAreaStyle' : 'getLineStyle'](); - var elementType = axisType === 'radius' + var elementType = coordSys.type === 'polar' ? (isShadow ? 'Sector' : 'Circle') : (isShadow ? 'Rect' : 'Line'); + isShadow ? (style.stroke = null) : (style.fill = null); + var el = axisPointers[key] = new graphic[elementType]({ style: style, silent: true @@ -206,6 +341,10 @@ define(function (require) { return el; }, + _showSeriesTooltip: function (series, e) { + + }, + /** * Show tooltip on item * @param {module:echarts/model/Model} diff --git a/src/coord/polar/Polar.js b/src/coord/polar/Polar.js index 681ab4d7939b3db4af546d44eb26011b3c43b8de..a0472f45e7427c9732c2561c59829f318fe4c48c 100644 --- a/src/coord/polar/Polar.js +++ b/src/coord/polar/Polar.js @@ -116,7 +116,7 @@ define(function(require) { var coord = this.pointToCoord(point); return [ this._radiusAxis.radiusToData(coord[0]), - this._angleAxis.angleToData(coord[1]) / Math.PI * 180 + this._angleAxis.angleToData(coord[1]) ]; }, @@ -133,9 +133,15 @@ define(function(require) { dx /= radius; dy /= radius; - var angle = Math.atan2(dy, dx); + var radian = Math.atan2(dy, dx); - return [radius, angle]; + // Threshold to 0 - 360 + // FIXME Angle Extent ? + if (radian < 0) { + radian += Math.PI * 2; + } + + return [radius, radian / Math.PI * 180]; }, /** diff --git a/test/polarLine.html b/test/polarLine.html index 3d8dfd457aaf54abf82e1fda73e9e73c9ae039f8..c224b075207929ccd4ae11d5360010fb1975274e 100644 --- a/test/polarLine.html +++ b/test/polarLine.html @@ -18,7 +18,8 @@ 'echarts', 'echarts/chart/line', 'echarts/component/legend', - 'echarts/component/polar' + 'echarts/component/polar', + 'echarts/component/tooltip' ], function (echarts) { var chart = echarts.init(document.getElementById('main'), null, { @@ -41,6 +42,12 @@ legend: { data: ['line', 'line2', 'line3'] }, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'shadow' + } + }, polar: {}, angleAxis: { // data: ['类目1', '类目2', '类目3', '类目4', '类目5',]