diff --git a/src/chart/bar/BarView.js b/src/chart/bar/BarView.js index 9a84999a37bbc5e9225b70ec2596d97929233921..870ca2a3f3e859a15cd78e39b65cbca3e630442f 100644 --- a/src/chart/bar/BarView.js +++ b/src/chart/bar/BarView.js @@ -1,5 +1,9 @@ define(function (require) { + 'use strict'; + + var zrUtil = require('zrender/core/util'); + return require('../../echarts').extendChartView({ type: 'bar', @@ -26,18 +30,19 @@ define(function (require) { } var layout = dataItem.layout; - var normalItemStyle = dataItem.getModel('itemStyle.normal'); var rect = new api.Rect({ shape: { x: layout.x, y: layout.y + layout.height, width: layout.width }, - style: { - fill: dataItem.getVisual('color'), - stroke: normalItemStyle.get('borderColor'), - lineWidth: normalItemStyle.get('borderWidth') - } + style: zrUtil.merge( + dataItem.getModel('itemStyle.normal').getItemStyle(), + { + fill: dataItem.getVisual('color') + }, + true, false + ) }); dataItem.__el = rect; diff --git a/src/chart/line/LineView.js b/src/chart/line/LineView.js index 227e84efd53d47d11fa55d19cc1bb41bad55722c..47788189b9e0702342db78ee242765766f2a7b47 100644 --- a/src/chart/line/LineView.js +++ b/src/chart/line/LineView.js @@ -2,19 +2,14 @@ define(function(require) { 'use strict'; + var zrUtil = require('zrender/core/util'); + return require('../../echarts').extendChartView({ type: 'line', render: function (seriesModel, ecModel, api) { - if (seriesModel.coordinateSystem.type === 'cartesian2d') { - this._renderCartesian(seriesModel, ecModel, api); - } - }, - - _renderCartesian: function (seriesModel, ecModel, api) { - var data = seriesModel.getData(); var lineStyleNormalModel = seriesModel.getModel('itemStyle.normal.lineStyle'); @@ -24,43 +19,35 @@ define(function(require) { return [layout.x, layout.y]; } }); + var coordinateSystem = seriesModel.coordinateSystem; + var isCoordinateSystemPolar = coordinateSystem.type === 'polar'; + + // if (isCoordinateSystemPolar && points.length > 2) { + // // Close polyline + // points.push(Array.prototype.slice.call(points[0])); + // } + // Initialization animation if (!this._data) { - var cartesian = seriesModel.coordinateSystem; - var xAxis = cartesian.getAxis('x'); - var yAxis = cartesian.getAxis('y'); - var xExtent = xAxis.getExtent(); - var yExtent = yAxis.getExtent(); - - var clipPath = new api.Rect({ - shape: { - x: xExtent[0], - y: yExtent[0], - width: 0, - height: yExtent[1] - yExtent[0] - } - }); + var clipPath = isCoordinateSystemPolar + ? this._createPolarClipShape(coordinateSystem, api) + : this._createGridClipShape(coordinateSystem, api); this.group.setClipPath(clipPath); - clipPath.animateShape() - .when(1500, { - x: xExtent[0], - y: yExtent[0], - width: xExtent[1] - xExtent[0], - height: yExtent[1] - yExtent[0] - }) - .start(); - var polyline = new api.Polyline({ shape: { points: points }, - style: { - stroke: seriesModel.getVisual('color'), - lineWidth: lineStyleNormalModel.get('width') - } + style: zrUtil.merge( + lineStyleNormalModel.getLineStyle(), + { + stroke: seriesModel.getVisual('color') + }, + true, false + ) }); + this.group.add(polyline); this._polyline = polyline; @@ -73,9 +60,65 @@ define(function(require) { // .start('cubicOut'); this._polyline.shape.points = points; this._polyline.dirty(true); + + // Add back + this.group.add(this._polyline); } this._data = data; + }, + + _createGridClipShape: function (cartesian, api) { + var xAxis = cartesian.getAxis('x'); + var yAxis = cartesian.getAxis('y'); + var xExtent = xAxis.getExtent(); + var yExtent = yAxis.getExtent(); + + var clipPath = new api.Rect({ + shape: { + x: xExtent[0], + y: yExtent[0], + width: 0, + height: yExtent[1] - yExtent[0] + } + }); + + clipPath.animateTo({ + shape: { + x: xExtent[0], + y: yExtent[0], + width: xExtent[1] - xExtent[0], + height: yExtent[1] - yExtent[0] + } + }, 1500); + + return clipPath; + }, + + _createPolarClipShape: function (polar, api) { + // var angleAxis = polar.getAngleAxis(); + var radiusAxis = polar.getRadiusAxis(); + + var radiusExtent = radiusAxis.getExtent(); + + var clipPath = new api.Sector({ + shape: { + cx: polar.cx, + cy: polar.cy, + r0: radiusExtent[0], + r: radiusExtent[1], + startAngle: 0, + endAngle: 0 + } + }); + + clipPath.animateTo({ + shape: { + endAngle: Math.PI * 2 + } + }, 1500); + + return clipPath; } }); }); \ No newline at end of file diff --git a/src/chart/scatter/ScatterView.js b/src/chart/scatter/ScatterView.js index 01315be4144628aa665643c20815318440420931..63f8b892887b7787918c4e4dce24176bab3b3c9c 100644 --- a/src/chart/scatter/ScatterView.js +++ b/src/chart/scatter/ScatterView.js @@ -1,5 +1,7 @@ define(function (require) { + var zrUtil = require('zrender/core/util'); + require('../../echarts').extendChartView({ type: 'scatter', @@ -31,9 +33,13 @@ define(function (require) { symbolShape.scale = [0.1, 0.1]; symbolShape.position = [layout.x, layout.y]; - symbolShape.style.set({ - fill: dataItem.getVisual('color') - }); + symbolShape.style.set(zrUtil.merge( + dataItem.getModel('itemStyle.normal').getItemStyle(), + { + fill: dataItem.getVisual('color') + }, + true, false + )); symbolShape.animateTo({ scale: [symbolSize, symbolSize] diff --git a/src/chart/scatter/scatterVisual.js b/src/chart/scatter/scatterVisual.js index 8f54be4495f1c2c9b373f71e481ae83397f94788..f9dec896b434a6e60aaad5750cca3b984b7264d4 100644 --- a/src/chart/scatter/scatterVisual.js +++ b/src/chart/scatter/scatterVisual.js @@ -3,7 +3,7 @@ define(function (require) { require('../../echarts').registerVisualCoding(function (ecModel) { ecModel.eachSeriesByType('scatter', function (scatterSeries) { - var symbolType = scatterSeries.get('symbol'); + var symbolType = scatterSeries.get('symbol') || 'circle'; var symbolSize = scatterSeries.get('symbolSize'); scatterSeries.setVisual({ legendSymbol: symbolType, @@ -15,8 +15,18 @@ define(function (require) { data.each(function (dataItem) { var symbolType = dataItem.get('symbol'); var symbolSize = dataItem.get('symbolSize'); - if (symbolType && symbolType !== 'none') { - scatterSeries.setVisual({ + if (typeof symbolSize === 'function') { + dataItem.setVisual({ + symbol: symbolType, + symbolSize: symbolSize([ + dataItem.getX(), + dataItem.getY(), + dataItem.getValue() + ]) + }); + } + else if (symbolType && symbolType !== 'none') { + dataItem.setVisual({ symbol: symbolType, symbolSize: symbolSize }); diff --git a/src/component/angleAxis.js b/src/component/angleAxis.js index 0ee91e1b4b212301d9ed1e17869dc6fb40379a22..8a52eaf6268dea41b7bf9655c741666b18c53e16 100644 --- a/src/component/angleAxis.js +++ b/src/component/angleAxis.js @@ -6,25 +6,24 @@ define(function(require) { var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea']; - var lineStart = []; - var lineEnd = []; - var lineDirection = []; - var center = []; - function getLineShape(cx, cy, r0, r, radian) { - center[0] = cx; - center[1] = cy; + function getPointOnAxisLine(cx, cy, r, radian) { + var dx = r * Math.cos(radian); + var dy = r * Math.sin(radian); - lineDirection[0] = Math.cos(radian); - lineDirection[1] = Math.sin(radian); + return [cx + dx, cy + dy]; + } + + function getAxisLineShape(cx, cy, r0, r, angle) { + var radian = angle / 180 * Math.PI; - vector.scaleAndAdd(lineStart, center, lineDirection, r0); - vector.scaleAndAdd(lineEnd, center, lineDirection, r); + var start = getPointOnAxisLine(cx, cy, r0, radian); + var end = getPointOnAxisLine(cx, cy, r, radian); return { - x1: lineStart[0], - y1: lineStart[1], - x2: lineEnd[0], - y2: lineEnd[1] + x1: start[0], + y1: start[1], + x2: end[0], + y2: end[1] }; } @@ -45,6 +44,12 @@ define(function(require) { var cy = polar.cy; var radiusExtent = polar.getRadiusAxis().getExtent(); var ticksAngles = angleAxis.getTicksPositions(); + + if (angleAxis.type !== 'category') { + // Remove the last tick which will overlap the first tick + ticksAngles.pop(); + } + zrUtil.each(elementList, function (name) { if (angleAxisModel.get(name +'.show')) { this['_' + name](angleAxisModel, ticksAngles, radiusExtent, cx, cy, api); @@ -58,17 +63,17 @@ define(function(require) { _axisLine: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle'); - var arc = new api.Arc({ + var circle = new api.Circle({ shape: { - x: cx, - y: cy, - r0: radiusExtent[0], + cx: cx, + cy: cy, r: radiusExtent[1] }, style: lineStyleModel.getLineStyle() }); + circle.style.fill = null; - this.group.add(arc); + this.group.add(circle); }, /** @@ -81,19 +86,53 @@ define(function(require) { var lines = zrUtil.map(ticksAngles, function (tickAngle) { return new api.Line({ - shape: getLineShape(cx, cy, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle) + shape: getAxisLineShape(cx, cy, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle) }); }); this.group.add(api.mergePath( - lines, tickModel.getModel('lineStyle').getLineStyle()) - ); + lines, { + style: tickModel.getModel('lineStyle').getLineStyle() + } + )); }, /** * @private */ _axisLabel: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + var axis = angleAxisModel.axis; + + var labelModel = angleAxisModel.getModel('axisLabel'); + var textStyleModel = labelModel.getModel('textStyle'); + + var labels = angleAxisModel.formatLabels(axis.scale.getTicksLabels()); + var labelMargin = labelModel.get('margin'); + var labelsAngles = axis.getLabelsPositions(); + + // Use length of ticksAngles because it may remove the last tick to avoid overlapping + for (var i = 0; i < ticksAngles.length; i++) { + var tickAngle = labelsAngles[i] * Math.PI / 180; + var r = radiusExtent[1]; + var p = getPointOnAxisLine(cx, cy, r + labelMargin, tickAngle); + + var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3 + ? 'center' : (p[0] > cx ? 'left' : 'right'); + var labelTextBaseline = Math.abs(p[1] - cy) / r < 0.3 + ? 'middle' : (p[1] > cy ? 'top' : 'bottom'); + + this.group.add(new api.Text({ + style: { + x: p[0], + y: p[1], + text: labels[i], + textAlign: labelTextAlign, + textBaseline: labelTextBaseline, + font: textStyleModel.getFont() + }, + silent: true + })) + } }, /** @@ -114,7 +153,7 @@ define(function(require) { var colorIndex = (lineCount++) % lineColors.length; splitLines[colorIndex] = splitLines[colorIndex] || []; splitLines[colorIndex].push(new api.Line({ - shape: getLineShape(cx, cy, radiusExtent[0], radiusExtent[1], tickAngle) + shape: getAxisLineShape(cx, cy, radiusExtent[0], radiusExtent[1], ticksAngles[i]) })) } diff --git a/src/component/axis.js b/src/component/axis.js index cbce013d4ba8bc835620e1245536d45eba4a74ef..ba18c7c7e76f73370fc605a6dbfe5c28c35f9b28 100644 --- a/src/component/axis.js +++ b/src/component/axis.js @@ -208,6 +208,7 @@ define(function(require) { var gridRect = gridModel.coordinateSystem.getRect(); var ticks = axis.scale.getTicks(); + var labels = axisModel.formatLabels(axis.scale.getTicksLabels()); var labelMargin = labelModel.get('margin'); var labelRotate = labelModel.get('rotate'); var labelInterval = labelModel.get('interval') || 0; @@ -216,16 +217,6 @@ define(function(require) { var textSpaceTakenRect; var needsCheckTextSpace; - var labels; - if (axis.scale.type === 'ordinal') { - labels = zrUtil.map(ticks, axis.scale.getItem, axis.scale); - } - else { - labels = ticks.slice(); - } - - labels = axisModel.formatLabels(labels); - for (var i = 0; i < ticks.length; i++) { // Default is false showList[i] = false; diff --git a/src/component/polar.js b/src/component/polar.js index 4902a3bf21df6414b048acc9e14cf213303b0e72..0b4d2db6976b543d73339765b2cb120b2f33503e 100644 --- a/src/component/polar.js +++ b/src/component/polar.js @@ -1,8 +1,7 @@ define(function(require) { 'use strict'; - require('../coord/polar/Polar'); - + require('../coord/polar/polarCreator'); require('./angleAxis'); require('./radiusAxis'); diff --git a/src/component/radiusAxis.js b/src/component/radiusAxis.js index fee55045c32dc99305b04686ecbccf68e5f1eb20..a37128bab3c694fd71eaaa34efb178a0a688e2c8 100644 --- a/src/component/radiusAxis.js +++ b/src/component/radiusAxis.js @@ -1,10 +1,209 @@ -define(function (require) { +define(function(require) { + 'use strict'; + + var zrUtil = require('zrender/core/util'); + var vector = require('zrender/core/vector'); + + var elementList = ['splitLine', 'splitArea', 'axisLine', 'axisTick', 'axisLabel']; + + function getPointOnAxisLine(cx, cy, r, radian) { + var dx = r * Math.cos(radian); + var dy = r * Math.sin(radian); + + return [cx + dx, cy + dy]; + } + + function getAxisLineShape(radiusAxisModel, cx, cy) { + + var radiusAxis = radiusAxisModel.axis; + var radius = radiusAxis.getExtent(); + + var axisAngle = radiusAxisModel.get('axisAngle'); + + var radian = axisAngle / 180 * Math.PI; + + var start = getPointOnAxisLine(cx, cy, radius[0], radian); + var end = getPointOnAxisLine(cx, cy, radius[1], radian); + + return { + x1: start[0], + y1: start[1], + x2: end[0], + y2: end[1] + }; + } + + require('../coord/polar/polarCreator'); require('../echarts').extendComponentView({ type: 'radiusAxis', render: function (radiusAxisModel, ecModel, api) { + this.group.clear(); + + var polarModel = ecModel.getComponent('polar', radiusAxisModel.get('polarIndex')); + var radiusAxis = radiusAxisModel.axis; + var polar = polarModel.coordinateSystem; + var cx = polar.cx; + var cy = polar.cy; + var angleExtent = polar.getAngleAxis().getExtent(); + var ticksPositions = radiusAxis.getTicksPositions(); + zrUtil.each(elementList, function (name) { + if (radiusAxisModel.get(name +'.show')) { + this['_' + name](radiusAxisModel, ticksPositions, angleExtent, cx, cy, api); + } + }, this); + + var z = radiusAxisModel.get('z'); + this.group.eachChild(function (child) { + child.z = z; + }); + }, + + /** + * @private + */ + _axisLine: function (radiusAxisModel, ticksPositions, angleExtent, cx, cy, api) { + var arc = new api.Line({ + shape: getAxisLineShape(radiusAxisModel, cx, cy), + style: radiusAxisModel.getModel('axisLine.lineStyle').getLineStyle() + }); + + this.group.add(arc); + }, + + /** + * @private + */ + _axisTick: function (radiusAxisModel, ticksPositions, angleExtent, cx, cy, api) { + var tickModel = radiusAxisModel.getModel('axisTick'); + + var lineShape = getAxisLineShape(radiusAxisModel, cx, cy); + var start = [lineShape.x1, lineShape.y1]; + var end = [lineShape.x2, lineShape.y2]; + + var len = vector.dist(end, start); + var direction = [ + end[1] - start[1], + start[0] - end[0] + ]; + vector.normalize(direction, direction); + + var p1 = []; + var p2 = []; + var tickLen = tickModel.get('length'); + var lines = zrUtil.map(ticksPositions, function (tickPosition) { + // Get point on axis + vector.lerp(p1, start, end, tickPosition / len); + vector.scaleAndAdd(p2, p1, direction, tickLen); + return new api.Line({ + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + } + }); + }); + this.group.add(api.mergePath( + lines, { + style: tickModel.getModel('lineStyle').getLineStyle(), + silent: true + } + )); + }, + + /** + * @private + */ + _axisLabel: function (radiusAxisModel, ticksPositions, angleExtent, cx, cy, api) { + var axis = radiusAxisModel.axis; + var labelModel = radiusAxisModel.getModel('axisLabel'); + var textStyleModel = labelModel.getModel('textStyle'); + + var labels = radiusAxisModel.formatLabels(axis.scale.getTicksLabels()); + + var lineShape = getAxisLineShape(radiusAxisModel, cx, cy); + var start = [lineShape.x1, lineShape.y1]; + var end = [lineShape.x2, lineShape.y2]; + + var len = vector.dist(end, start); + var direction = [ + start[1] - end[1], + end[0] - start[0] + ]; + vector.normalize(direction, direction); + + var p = []; + var labelMargin = labelModel.get('margin'); + var labelsPositions = axis.getLabelsPositions(); + + // FIXME Text align and text baseline when axis angle is 90 degree + for (var i = 0; i < labelsPositions.length; i++) { + // Get point on axis + vector.lerp(p, start, end, labelsPositions[i] / len); + vector.scaleAndAdd(p, p, direction, labelMargin); + this.group.add(new api.Text({ + style: { + x: p[0], + y: p[1], + text: labels[i], + textAlign: 'center', + textBaseline: 'top', + font: textStyleModel.getFont() + }, + silent: true + })); + }; + }, + + /** + * @private + */ + _splitLine: function (radiusAxisModel, ticksPositions, angleExtent, cx, cy, api) { + var splitLineModel = radiusAxisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + var lineWidth = lineStyleModel.get('width'); + var lineCount = 0; + + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + + var splitLines = []; + + for (var i = 0; i < ticksPositions.length; i++) { + var colorIndex = (lineCount++) % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new api.Circle({ + shape: { + cx: cx, + cy: cy, + r: ticksPositions[i] + }, + silent: true + })) + } + + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitLines.length; i++) { + this.group.add(api.mergePath(splitLines[i], { + style: { + stroke: lineColors[i % lineColors.length], + lineType: lineStyleModel.getLineDash(), + lineWidth: lineWidth, + fill: null + }, + silent: true + })); + } + }, + + /** + * @private + */ + _splitArea: function (radiusAxisModel, ticksPositions, angleExtent, cx, cy, api) { } }); diff --git a/src/coord/Axis.js b/src/coord/Axis.js index 9da61f9b028c8e95e7d5b6abeb33a8c636130034..eb95b71db187d96159684e1df0fac6a2ef2c95a0 100644 --- a/src/coord/Axis.js +++ b/src/coord/Axis.js @@ -87,7 +87,7 @@ define(function (require) { data = this.scale.normalize(data); var extent = this.getExtent(); - if (this.onBand && this.scale.type === 'ordinal') { + if (this.onBand) { fixExtentWithBands(extent, this.scale.getExtentSize()); } @@ -103,7 +103,7 @@ define(function (require) { unmapData: function (mapped, clamp) { var extent = this.getExtent(); - if (this.onBand && this.scale.type === 'ordinal') { + if (this.onBand) { fixExtentWithBands(extent, this.scale.getExtentSize()); } @@ -115,20 +115,39 @@ define(function (require) { * @return {Array.} */ getTicksPositions: function () { - var ticks = this.scale.getTicks(); - if (this.onBand && this.scale.type === 'ordinal') { + if (this.onBand) { var bands = this.getBands(); - var ret = []; + var positions = []; for (var i = 0; i < bands.length; i++) { - ret.push(bands[i][0]); + positions.push(bands[i][0]); } if (bands[i - 1]) { - ret.push(bands[i - 1][1]); + positions.push(bands[i - 1][1]); } - return ret; + return positions; } else { - return zrUtil.map(ticks, this.mapData, this); + return zrUtil.map(this.scale.getTicks(), this.mapData, this); + } + }, + + /** + * Positions of labels are on the ticks or on the middle of bands + * @return {Array.} + */ + getLabelsPositions: function () { + if (this.onBand) { + var bands = this.getBands(); + var positions = []; + var band; + for (var i = 0; i < bands.length; i++) { + band = bands[i]; + positions.push((band[0] + band[1]) / 2); + } + return positions; + } + else { + return zrUtil.map(this.scale.getTicks(), this.mapData, this); } }, diff --git a/src/coord/cartesian/Grid.js b/src/coord/cartesian/Grid.js index df98593021334cfc24b16a763f144ce3b528d711..0ed8f2755d1041ddddd1da30f18b3908c72bc16e 100644 --- a/src/coord/cartesian/Grid.js +++ b/src/coord/cartesian/Grid.js @@ -197,7 +197,7 @@ define(function(require, factory) { xAxisModel.get('type'), xAxisPosition ); - axisX.onBand = xAxisModel.get('boundaryGap'); + axisX.onBand = xAxisModel.get('boundaryGap') && axisX.type === 'category'; axisX.inverse = xAxisModel.get('inverse'); // Inject axis into axisModel diff --git a/src/coord/polar/AngleAxis.js b/src/coord/polar/AngleAxis.js index 6ef659cc4329f0429703516845fd25c7ec10b2ca..63f62d1793ac0d1a2ef12df92eb4b001fed7324b 100644 --- a/src/coord/polar/AngleAxis.js +++ b/src/coord/polar/AngleAxis.js @@ -6,7 +6,7 @@ define(function(require) { function AngleAxis(scale, angleExtent) { - angleExtent = angleExtent || [0, Math.PI * 2]; + angleExtent = angleExtent || [0, 360]; Axis.call(this, 'angle', scale, angleExtent); diff --git a/src/coord/polar/AxisModel.js b/src/coord/polar/AxisModel.js index b4acf4643b89d97397665055ab67901e14334604..cfef1f3d2b55ba10ab06aca81a1384f1356245e2 100644 --- a/src/coord/polar/AxisModel.js +++ b/src/coord/polar/AxisModel.js @@ -25,7 +25,6 @@ define(function(require) { zrUtil.merge(PolarAxisModel.prototype, require('../axisModelCommonMixin')); - // Radius axis PolarAxisModel.extend({ @@ -37,11 +36,18 @@ define(function(require) { axis: null, init: function (axisOption, parentModel, ecModel) { - axisOption.type = axisOption.type || 'value'; - - axisOption.polarIndex = axisOption.polarIndex || 0; + zrUtil.merge(axisOption, this.defaultOption, false); mergeDefault(axisOption, ecModel); + }, + + defaultOption: { + + type: 'value', + + polarIndex: 0, + + axisAngle: 0 } }); @@ -56,11 +62,22 @@ define(function(require) { axis: null, init: function (axisOption, parentModel, ecModel) { - axisOption.type = axisOption.type || 'category'; - - axisOption.polarIndex = axisOption.polarIndex || 0; + zrUtil.merge(axisOption, this.defaultOption, false); mergeDefault(axisOption, ecModel); + }, + + defaultOption: { + + type: 'category', + + polarIndex: 0, + + clockWise: true, + + axisLabel: { + rotate: false + } } }); }); \ No newline at end of file diff --git a/src/coord/polar/Polar.js b/src/coord/polar/Polar.js index b5af6c012f765011b47b8f90c70205fee2743e35..5b9efbba56d79874e1027ba45759a57f63cc56b0 100644 --- a/src/coord/polar/Polar.js +++ b/src/coord/polar/Polar.js @@ -86,10 +86,10 @@ define(function(require) { */ dataToCoord: function (data) { var radius = this._radiusAxis.dataToRadius(data[0]); - var angle = this._angleAxis.dataToAngle(data[1]); + var radian = this._angleAxis.dataToAngle(data[1]) / 180 * Math.PI; - var x = Math.cos(angle) * radius + this.cx; - var y = Math.sin(angle) * radius + this.cy; + var x = Math.cos(radian) * radius + this.cx; + var y = Math.sin(radian) * radius + this.cy; return [x, y]; }, @@ -111,7 +111,7 @@ define(function(require) { return [ this._radiusAxis.radiusToData(radius), - this._angleAxis.angleToData(angle) + this._angleAxis.angleToData(angle) / Math.PI * 180 ]; } } diff --git a/src/coord/polar/PolarModel.js b/src/coord/polar/PolarModel.js index 05562b863f8df909f79c906e1f9347d43218c77d..fcdbe96418c94cc905ebc6ecf874811bfd8047fb 100644 --- a/src/coord/polar/PolarModel.js +++ b/src/coord/polar/PolarModel.js @@ -23,7 +23,7 @@ define(function (require) { center: ['50%', '50%'], - radius: ['0%', '75%'] + radius: ['0%', '80%'] } }); }); \ No newline at end of file diff --git a/src/coord/polar/polarCreator.js b/src/coord/polar/polarCreator.js index ebc47fdee089de0323401c38ba65bf1c4472d657..bcf75523a714c5774467999c5bf1f3cef5f91174 100644 --- a/src/coord/polar/polarCreator.js +++ b/src/coord/polar/polarCreator.js @@ -5,10 +5,10 @@ define(function (require) { var IntervalScale = require('../../scale/Interval'); var OrdinalScale = require('../../scale/Ordinal'); var numberUtil = require('../../util/number'); + var zrUtil = require('zrender/core/util'); - // 依赖 PolarModel, AxisModel 做预处理 + // 依赖 PolarModel 做预处理 require('./PolarModel'); - require('./AxisModel'); /** * Retrieve angle axis or radius axis belongs to the given polar @@ -49,7 +49,7 @@ define(function (require) { this.cy = parsePercent(center[1], height); var radiusAxis = this.getRadiusAxis(); - var size = Math.min(width, height); + var size = Math.min(width, height) / 2; radiusAxis.setExtent( parsePercent(radius[0], size), parsePercent(radius[1], size) @@ -79,7 +79,7 @@ define(function (require) { function setAxis(axis, axisModel) { axis.type = axisModel.get('type'); axis.scale = createScaleByModel(axisModel); - axis.onBand = axisModel.get('boundaryGap'); + axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category'; axis.inverse = axisModel.get('inverse'); // Inject axis instance @@ -116,6 +116,12 @@ define(function (require) { } } }); + + zrUtil.each(polarList, function (polar) { + // PENDING + polar.getAngleAxis().scale.niceExtent(12); + polar.getRadiusAxis().scale.niceExtent(5); + }); } var polarCreator = { @@ -136,6 +142,11 @@ define(function (require) { setAxis(radiusAxis, radiusAxisModel); setAxis(angleAxis, angleAxisModel); + if (angleAxis.type === 'category' && ! angleAxis.onBand) { + var angle = 360 - 360 / (angleAxis.scale.getExtentSize() + 1); + angleAxis.setExtent(0, angle); + } + polar.resize(polarModel, api); polarList.push(polar); diff --git a/src/data/List.js b/src/data/List.js index 84c6f8af00c9e925004ab2abdbd25e8280bd8486..4d2af6760609d1b3e26f6fa78dd606beb611ac80 100644 --- a/src/data/List.js +++ b/src/data/List.js @@ -327,7 +327,7 @@ define(function(require) { } } else if (coordinateSystem === 'polar') { - function axisFinder(axisModel) { + var axisFinder = function (axisModel) { return axisModel.get('polarIndex') === polarIndex; } var polarIndex = seriesModel.get('polarIndex') || 0; diff --git a/src/model/mixin/areaStyle.js b/src/model/mixin/areaStyle.js index 420274089f0cf927046561fe63611df002d03d3e..df674e443097db68db9c3690683ccc99e08f97d2 100644 --- a/src/model/mixin/areaStyle.js +++ b/src/model/mixin/areaStyle.js @@ -1,11 +1,13 @@ define({ getAreaStyle: function () { - return { - fill: this.get('color'), - shadowBlur: this.get('shadowBlur'), - shadowOffsetX: this.get('shadowOffsetX'), - shadowOffsetY: this.get('shadowOffsetY'), - shadowColor: this.get('shadowColor') - }; + return require('./makeStyleMapper')( + [ + ['fill', 'color'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ] + ); } }); \ No newline at end of file diff --git a/src/model/mixin/itemStyle.js b/src/model/mixin/itemStyle.js index 4b5fe6226ef42e29562a45e380787872bb485e78..7524e7ba38aa302e86825f8d6623c1696804d4df 100644 --- a/src/model/mixin/itemStyle.js +++ b/src/model/mixin/itemStyle.js @@ -1,14 +1,16 @@ -define({ - getItemStyle: function () { - return { - fill: this.get('color'), - stroke: this.get('borderColor'), - lineWidth: this.get('borderWidth'), - - shadowBlur: this.get('shadowBlur'), - shadowOffsetX: this.get('shadowOffsetX'), - shadowOffsetY: this.get('shadowOffsetY'), - shadowColor: this.get('shadowColor') - }; - } +define(function (require) { + return { + getItemStyle: require('./makeStyleMapper')( + [ + ['fill', 'color'], + ['stroke', 'borderColor'], + ['lineWidth', 'borderWidth'], + ['opacity'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ] + ) + }; }); \ No newline at end of file diff --git a/src/model/mixin/lineStyle.js b/src/model/mixin/lineStyle.js index f28431551f4014c1ac32fd4f6ef63a3cb863692b..ee2e7f924c9885c06cdff7a9d15684bf533a84a0 100644 --- a/src/model/mixin/lineStyle.js +++ b/src/model/mixin/lineStyle.js @@ -1,19 +1,26 @@ -define({ - getLineStyle: function () { - return { - lineWidth: this.get('width'), - stroke: this.get('color'), - lineDash: this.getLineDash(), - shadowBlur: this.get('shadowBlur'), - shadowOffsetX: this.get('shadowOffsetX'), - shadowOffsetY: this.get('shadowOffsetY'), - shadowColor: this.get('shadowColor') - }; - }, +define(function (require) { + var getLineStyle = require('./makeStyleMapper')( + [ + ['lineWidth', 'width'], + ['stroke', 'color'], + ['opacity'], + ['shadowBlur'], + ['shadowOffsetX'], + ['shadowOffsetY'], + ['shadowColor'] + ] + ); + return { + getLineStyle: function () { + var style = getLineStyle.call(this); + style.lineDash = this.getLineDash(); + return style; + }, - getLineDash: function () { - var type = this.get('type'); - return type === 'solid' ? null - : (type === 'dashed' ? [5, 5] : [1, 1]); - } + getLineDash: function () { + var type = this.get('type'); + return (type === 'solid' || type == null) ? null + : (type === 'dashed' ? [5, 5] : [1, 1]); + } + }; }); \ No newline at end of file diff --git a/src/model/mixin/makeStyleMapper.js b/src/model/mixin/makeStyleMapper.js new file mode 100644 index 0000000000000000000000000000000000000000..0b8a4a3ad366a433012852ce676bbc95cf26338b --- /dev/null +++ b/src/model/mixin/makeStyleMapper.js @@ -0,0 +1,20 @@ +define(function () { + return function (properties) { + // Normalize + for (var i = 0; i < properties.length; i++) { + if (! properties[i][1]) { + properties[i][1] = properties[i][0]; + } + } + return function () { + var obj = {}; + for (var i = 0; i < properties.length; i++) { + var val = this.get(properties[i][1]); + if (val != null) { + obj[properties[i][0]] = val; + } + } + return obj; + } + } +}); \ No newline at end of file diff --git a/src/scale/Interval.js b/src/scale/Interval.js index bf36ae3d3df3349382462f29587d1dbbad9daaca..eacbacfd86fd4a9d117c0600f35d68a3a88e6f32 100644 --- a/src/scale/Interval.js +++ b/src/scale/Interval.js @@ -144,6 +144,18 @@ define(function (require) { return ticks; }, + /** + * @return {Array.} + */ + getTicksLabels: function () { + var labels = []; + var ticks = this.getTicks(); + for (var i = 0; i < ticks.length; i++) { + labels.push(ticks[i].toString()); + } + return labels; + }, + /** * Update interval and extent of intervals for nice ticks * Algorithm from d3.js @@ -165,9 +177,12 @@ define(function (require) { if (err <= .15) { interval *= 10; } - else if (err <= .35) { + else if (err <= .3) { interval *= 5; } + else if (err <= .5) { + interval *= 3; + } else if (err <= .75) { interval *= 2; } @@ -182,9 +197,10 @@ define(function (require) { /** * Nice extent. + * @param {number} [approxTickNum = 10] Given approx tick number */ - niceExtent: function () { - this.niceTicks(); + niceExtent: function (approxTickNum) { + this.niceTicks(approxTickNum); var extent = this._extent; var interval = this._interval; diff --git a/src/scale/Ordinal.js b/src/scale/Ordinal.js index 67284f4459505dc279a12f15100d9b3d321b60a4..200a684221b7b5599dde5701ee6734576ddf858b 100644 --- a/src/scale/Ordinal.js +++ b/src/scale/Ordinal.js @@ -73,8 +73,8 @@ define(function (require) { */ setExtent: function (start, end) { var thisExtent = this._extent; - thisExtent[0] = start; - thisExtent[1] = end; + thisExtent[0] = Math.max(start, 0); + thisExtent[1] = Math.min(end, this._list.length - 1); }, /** @@ -93,6 +93,21 @@ define(function (require) { return ticks; }, + /** + * @return {Array.} + */ + getTicksLabels: function () { + var labels = []; + var extent = this._extent; + var rank = extent[0]; + + while (rank <= extent[1]) { + labels.push(this._list[rank]); + rank++; + } + return labels; + }, + /** * @return {number} */ @@ -103,7 +118,7 @@ define(function (require) { /** * Get item on rank n */ - getItem: function (n) { + getLabel: function (n) { return this._list[n]; }, diff --git a/src/util/number.js b/src/util/number.js index dc073f6357155b6149873b1823fa49791b6de0c4..2c33440af57926f192bbfb27d9cbc0d1f889d703 100644 --- a/src/util/number.js +++ b/src/util/number.js @@ -106,7 +106,7 @@ define(function (require) { */ function round(x) { // PENDING - return +(+x).toFixed(10); + return +(+x).toFixed(12); } return { diff --git a/src/util/symbol.js b/src/util/symbol.js index 0ca1a8528599c977eea7ee49a0ea7eefdda50d23..ad144a5a8c5e216114a624becfc046f7b32b5235 100644 --- a/src/util/symbol.js +++ b/src/util/symbol.js @@ -68,11 +68,13 @@ define(function(require) { }); }, - circle: function (x, y, size) { + circle: function (x, y, w, h) { + // Put circle in the center of square + var size = Math.min(w, h); return new graphic.Circle({ shape: { - cx: x + size / 2, - cy: y + size / 2, + cx: x + w / 2, + cy: y + h / 2, r: size / 2 } }); diff --git a/test/polarLine.html b/test/polarLine.html new file mode 100644 index 0000000000000000000000000000000000000000..fb564ba9701551c361ad68cead367c2c47e1a228 --- /dev/null +++ b/test/polarLine.html @@ -0,0 +1,72 @@ + + + + + + + + +
+ + + \ No newline at end of file diff --git a/test/polarLine2.html b/test/polarLine2.html new file mode 100644 index 0000000000000000000000000000000000000000..f9377b6c0e80c5fd873b03235400dc8c1586ebfb --- /dev/null +++ b/test/polarLine2.html @@ -0,0 +1,55 @@ + + + + + + + + +
+ + + \ No newline at end of file diff --git a/test/polar.html b/test/polarScatter.html similarity index 86% rename from test/polar.html rename to test/polarScatter.html index fdb9d840c3b052bda93d1cf39e3aad837d3efad0..2fc8c542e4b13eb2d44b1b51c489b9747ae17f45 100644 --- a/test/polar.html +++ b/test/polarScatter.html @@ -29,10 +29,10 @@ var data2 = []; var data3 = []; - for (var i = 0; i < 20; i++) { - data1.push([Math.random() * 1, Math.random() * Math.PI * 2]); - data2.push([Math.random() * 5, Math.random() * Math.PI * 2]); - data3.push([Math.random() * 10, Math.random() * Math.PI * 2]); + for (var i = 0; i < 100; i++) { + data1.push([Math.random() * 5, Math.random() * 360]); + data2.push([Math.random() * 5, Math.random() * 360]); + data3.push([Math.random() * 10, Math.random() * 360]); } chart.setOption({ @@ -46,25 +46,25 @@ type: 'value' }, radiusAxis: { - + axisAngle: 0 }, series: [{ coordinateSystem: 'polar', name: 'scatter', type: 'scatter', - symbolSize: 20, + symbolSize: 10, data: data1 }, { coordinateSystem: 'polar', name: 'scatter2', type: 'scatter', - symbolSize: 20, + symbolSize: 10, data: data2 }, { coordinateSystem: 'polar', name: 'scatter3', type: 'scatter', - symbolSize: 20, + symbolSize: 10, data: data3 }] }); diff --git a/test/scatter.html b/test/scatter.html index 3073bbfaf08df000ee8243712b54699babc3b88c..42545635921c9d215d2bf8e52a1f86fe4a7ffd27 100644 --- a/test/scatter.html +++ b/test/scatter.html @@ -29,10 +29,10 @@ var data2 = []; var data3 = []; - for (var i = 0; i < 20; i++) { - data1.push([Math.random() * 5, Math.random() * 4]); - data2.push([Math.random() * 10, Math.random() * 5]); - data3.push([Math.random() * 15, Math.random() * 10]); + for (var i = 0; i < 100; i++) { + data1.push([Math.random() * 5, Math.random() * 4, Math.random()]); + data2.push([Math.random() * 10, Math.random() * 5, Math.random()]); + data3.push([Math.random() * 15, Math.random() * 10, Math.random()]); } chart.setOption({ @@ -40,25 +40,64 @@ data: ['scatter', 'scatter2', 'scatter3'] }, xAxis: { - type: 'value' + type: 'value', + splitLine: { + show: false + } }, yAxis: { - type: 'value' + type: 'value', + splitLine: { + show: false + } }, series: [{ name: 'scatter', type: 'scatter', - symbolSize: 20, + itemStyle: { + normal: { + opacity: 0.8, + shadowBlur: 10, + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + }, + symbolSize: function (val) { + return val[2] * 40; + }, data: data1 }, { name: 'scatter2', type: 'scatter', - symbolSize: 20, + itemStyle: { + normal: { + opacity: 0.8, + shadowBlur: 10, + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + }, + symbolSize: function (val) { + return val[2] * 40; + }, data: data2 }, { name: 'scatter3', type: 'scatter', - symbolSize: 20, + itemStyle: { + normal: { + opacity: 0.8, + shadowBlur: 10, + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowColor: 'rgba(0, 0, 0, 0.5)' + } + }, + symbolSize: function (val) { + return val[2] * 40; + }, data: data3 }] });