diff --git a/src/ExtensionAPI.js b/src/ExtensionAPI.js index ddb7cb85b45513543f5e0a1bd1f3bfa02e0f0be6..8e7d3db17c718fca29a5e99514333e66a3a8a7f0 100644 --- a/src/ExtensionAPI.js +++ b/src/ExtensionAPI.js @@ -16,7 +16,10 @@ define(function(require) { // Mix graphic api zrUtil.merge(ExtensionAPI.prototype, require('./util/graphic')); + zrUtil.merge(ExtensionAPI.prototype, require('./util/symbol')); + ExtensionAPI.prototype.log = require('zrender/core/log'); + return ExtensionAPI; }); \ No newline at end of file diff --git a/src/chart/bar/BarSeries.js b/src/chart/bar/BarSeries.js index 0c96633ba679a02cf3147d870b928d43a2097224..0cc9febaed55bd72b5a1c5e224c0bb05d741a17f 100644 --- a/src/chart/bar/BarSeries.js +++ b/src/chart/bar/BarSeries.js @@ -9,7 +9,7 @@ define(function(require) { type: 'series.bar', - dependencies: ['xAxis', 'yAxis'], + dependencies: ['grid', 'polar'], getInitialData: function (option, ecModel) { return List.fromArray(option.data, this, ecModel); @@ -22,8 +22,14 @@ define(function(require) { clickable: true, legendHoverLink: true, // stack: null + + // Cartesian coordinate system xAxisIndex: 0, yAxisIndex: 0, + + // Polar coordinate system + polarIndex: 0, + barMinHeight: 0, // 最小高度改为0 // barWidth: null, // 默认自适应 barGap: '30%', // 柱间距离,默认为柱形宽度的30%,可设固定值 diff --git a/src/chart/bar/BarView.js b/src/chart/bar/BarView.js index 31f0fadf9f61b0fe57f13849ef75cfaf023a9cba..2dad258ccc3c616cd95d5bba3312577321005529 100644 --- a/src/chart/bar/BarView.js +++ b/src/chart/bar/BarView.js @@ -46,22 +46,20 @@ define(function (require) { group.add(rect); // Animation - rect.animateShape() - .when(500, layout) - .delay(300 * dataItem.dataIndex / data.elements.length) - .start('cubicOut'); + rect.animateTo({ + shape: layout + }, 1000, 300 * dataItem.dataIndex / data.elements.length, 'cubicOut'); }) .update(function (newData, oldData) { var el = oldData.__el; - el.stopAnimation(); // 空数据 if (newData.getValue() == null) { group.remove(el); return; } - el.animateShape() - .when(500, newData.layout) - .start('cubicOut'); + el.animateTo({ + shape: newData.layout + }, 500, 'cubicOut'); newData.__el = el; @@ -83,15 +81,14 @@ define(function (require) { var group = this.group; this._data.each(function (dataItem) { var el = dataItem.__el; - el.stopAnimation(); - el.animateShape() - .when(200, { + el.animateTo({ + shape: { width: 0 - }) - .done(function () { - group.remove(dataItem.__el); - }) - .start('cubicOut'); + } + }, 300, 'cubicOut', + function () { + group.remove(el); + }); }); } } diff --git a/src/chart/bar/barLayoutGrid.js b/src/chart/bar/barLayoutGrid.js index bb31501447c18d23ad626c77302c06cd0744e830..5b23416dcef62cb81a14ff642b9f5c08e477990e 100644 --- a/src/chart/bar/barLayoutGrid.js +++ b/src/chart/bar/barLayoutGrid.js @@ -139,7 +139,8 @@ define(function(require) { var columnLayoutInfo = barWidthAndOffset[cartesian.name][stackId]; var columnOffset = columnLayoutInfo.offset; var columnWidth = columnLayoutInfo.width; - var projectAxis = columnLayoutInfo.axis; + var valueAxis = cartesian.getOtherAxis(columnLayoutInfo.axis); + if (data.type === 'list') { var coords = cartesian.dataToCoords(data); lastStackCoords[stackId] = lastStackCoords[stackId] || []; @@ -152,23 +153,22 @@ define(function(require) { } var coord = coords[dataIndex]; - var lastCoord = lastStackCoords[stackId][dataIndex] || projectAxis.otherCoord; + var lastCoord = lastStackCoords[stackId][dataIndex] || valueAxis.dataToCoord(0); var x, y, width, height; - if (projectAxis.isHorizontal()) { - x = coord[0] + columnOffset; - y = Math.min(lastCoord, coord[1]); - width = columnWidth; - height = Math.abs(coord[1] - lastCoord); - - lastStackCoords[stackId][dataIndex] = y; - } - else { + if (valueAxis.isHorizontal()) { x = Math.min(lastCoord, coord[0]); y = coord[1] + columnOffset; width = Math.abs(coord[0] - lastCoord); height = columnWidth; lastStackCoords[stackId][dataIndex] = x; } + else { + x = coord[0] + columnOffset; + y = Math.min(lastCoord, coord[1]); + width = columnWidth; + height = Math.abs(coord[1] - lastCoord); + lastStackCoords[stackId][dataIndex] = y; + } dataItem.layout = { x: x, y: y, diff --git a/src/chart/line/LineSeries.js b/src/chart/line/LineSeries.js index 3bfe523645681fce0747c3f0c9180c6f415fb5f3..e27c171ad7a7404f7290727a2e1e8132af90de75 100644 --- a/src/chart/line/LineSeries.js +++ b/src/chart/line/LineSeries.js @@ -9,7 +9,7 @@ define(function(require) { type: 'series.line', - dependencies: ['xAxis', 'yAxis'], + dependencies: ['grid', 'polar'], getInitialData: function (option, ecModel) { return List.fromArray(option.data, this, ecModel); diff --git a/src/chart/line/LineView.js b/src/chart/line/LineView.js index 38918baa16d59e333d163b09cee48d9ba5d4a16d..7cb916aa300e2d7eac018a98bb4f4a3b874dc9d9 100644 --- a/src/chart/line/LineView.js +++ b/src/chart/line/LineView.js @@ -25,7 +25,7 @@ define(function(require) { } }); // Initialization animation - if (! this._data) { + if (!this._data) { var cartesian = seriesModel.coordinateSystem; var xAxis = cartesian.getAxis('x'); var yAxis = cartesian.getAxis('y'); diff --git a/src/chart/pie/pieLayout.js b/src/chart/pie/pieLayout.js index d9b8d60ba6a493da2064b42681540300b6e46d94..cf078f7d02554edd9743ae0299b6cf873d1bebaf 100644 --- a/src/chart/pie/pieLayout.js +++ b/src/chart/pie/pieLayout.js @@ -1,3 +1,4 @@ define(function (require) { + }); \ No newline at end of file diff --git a/src/chart/scatter/ScatterSeries.js b/src/chart/scatter/ScatterSeries.js index 39dce3aadd3658babdd75b9e324c162c87ba4bf7..ce0f1a210578ac48cfb8b1d69b46e703dcf81563 100644 --- a/src/chart/scatter/ScatterSeries.js +++ b/src/chart/scatter/ScatterSeries.js @@ -9,7 +9,7 @@ define(function (require) { type: 'series.scatter', - dependencies: ['xAxis', 'yAxis'], + dependencies: ['grid', 'polar'], getInitialData: function (option, ecModel) { return List.fromArray(option.data, this, ecModel); @@ -21,8 +21,14 @@ define(function (require) { z: 2, // 二级层叠 clickable: true, legendHoverLink: true, + + // Cartesian coordinate system xAxisIndex: 0, yAxisIndex: 0, + + // Polar coordinate system + polarIndex: 0, + // symbol: null, // 图形类型 symbolSize: 4, // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 // symbolRotate: null, // 图形旋转控制 diff --git a/src/chart/scatter/ScatterView.js b/src/chart/scatter/ScatterView.js index a672945d1778fb37a548e5699f9dda66f27ae2d0..01315be4144628aa665643c20815318440420931 100644 --- a/src/chart/scatter/ScatterView.js +++ b/src/chart/scatter/ScatterView.js @@ -35,11 +35,9 @@ define(function (require) { fill: dataItem.getVisual('color') }); - symbolShape.animate() - .when(500, { - scale: [symbolSize, symbolSize] - }) - .start(); + symbolShape.animateTo({ + scale: [symbolSize, symbolSize] + }, 500); dataItem.__el = symbolShape; @@ -56,12 +54,11 @@ define(function (require) { // group.remove(oldData.__el); // return; // } - el.animate() - .when(500, { - scale: [symbolSize, symbolSize], - position: [layout.x, layout.y] - }) - .start('cubicOut'); + el.animateTo({ + scale: [symbolSize, symbolSize], + position: [layout.x, layout.y] + }, 500, 'cubicOut'); + newData.__el = el; // Add back @@ -83,14 +80,11 @@ define(function (require) { this._data.each(function (dataItem) { var el = dataItem.__el; el.stopAnimation(); - el.animate() - .when(200, { - scale: [0, 0] - }) - .done(function () { - group.remove(dataItem.__el); - }) - .start('cubicOut'); + el.animateTo({ + scale: [0, 0] + }, 200, 'cubicOut', function () { + group.remove(dataItem.__el); + }); }); } } diff --git a/src/chart/scatter/scatterLayout.js b/src/chart/scatter/scatterLayout.js index 8b340716e331382a06060a3fcb38092acee57e02..c07541d2734129a61c930c98fb8092998c181673 100644 --- a/src/chart/scatter/scatterLayout.js +++ b/src/chart/scatter/scatterLayout.js @@ -3,13 +3,9 @@ define(function (require) { require('../../echarts').registerLayout(function (ecModel, api) { ecModel.eachSeriesByType('scatter', function (scatterSeries) { - var cartesian = scatterSeries.coordinateSystem; - if (cartesian.type !== 'cartesian2d') { - return; - } - + var coordinateSystem = scatterSeries.coordinateSystem; var data = scatterSeries.getData(); - var coords = cartesian.dataToCoords(data); + var coords = coordinateSystem.dataToCoords(data); data.each(function (dataItem, idx) { var coord = coords[idx]; diff --git a/src/component/angleAxis.js b/src/component/angleAxis.js new file mode 100644 index 0000000000000000000000000000000000000000..0ee91e1b4b212301d9ed1e17869dc6fb40379a22 --- /dev/null +++ b/src/component/angleAxis.js @@ -0,0 +1,143 @@ +define(function(require) { + 'use strict'; + + var zrUtil = require('zrender/core/util'); + var vector = require('zrender/core/vector'); + + 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; + + lineDirection[0] = Math.cos(radian); + lineDirection[1] = Math.sin(radian); + + vector.scaleAndAdd(lineStart, center, lineDirection, r0); + vector.scaleAndAdd(lineEnd, center, lineDirection, r); + + return { + x1: lineStart[0], + y1: lineStart[1], + x2: lineEnd[0], + y2: lineEnd[1] + }; + } + + + require('../coord/polar/polarCreator'); + + require('../echarts').extendComponentView({ + + type: 'angleAxis', + + render: function (angleAxisModel, ecModel, api) { + this.group.clear(); + + var polarModel = ecModel.getComponent('polar', angleAxisModel.get('polarIndex')); + var angleAxis = angleAxisModel.axis; + var polar = polarModel.coordinateSystem; + var cx = polar.cx; + var cy = polar.cy; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var ticksAngles = angleAxis.getTicksPositions(); + zrUtil.each(elementList, function (name) { + if (angleAxisModel.get(name +'.show')) { + this['_' + name](angleAxisModel, ticksAngles, radiusExtent, cx, cy, api); + } + }, this); + }, + + /** + * @private + */ + _axisLine: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + var lineStyleModel = angleAxisModel.getModel('axisLine.lineStyle'); + + var arc = new api.Arc({ + shape: { + x: cx, + y: cy, + r0: radiusExtent[0], + r: radiusExtent[1] + }, + style: lineStyleModel.getLineStyle() + }); + + this.group.add(arc); + }, + + /** + * @private + */ + _axisTick: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + var tickModel = angleAxisModel.getModel('axisTick'); + + var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length'); + + var lines = zrUtil.map(ticksAngles, function (tickAngle) { + return new api.Line({ + shape: getLineShape(cx, cy, radiusExtent[1], radiusExtent[1] + tickLen, tickAngle) + }); + }); + this.group.add(api.mergePath( + lines, tickModel.getModel('lineStyle').getLineStyle()) + ); + }, + + /** + * @private + */ + _axisLabel: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + + }, + + /** + * @private + */ + _splitLine: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + var splitLineModel = angleAxisModel.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 < ticksAngles.length; i++) { + var colorIndex = (lineCount++) % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new api.Line({ + shape: getLineShape(cx, cy, radiusExtent[0], radiusExtent[1], tickAngle) + })) + } + + // 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 + }, + silent: true, + z: angleAxisModel.get('z') + })); + } + }, + + /** + * @private + */ + _splitArea: function (angleAxisModel, ticksAngles, radiusExtent, cx, cy, api) { + + } + }); +}); \ No newline at end of file diff --git a/src/component/axis.js b/src/component/axis.js index 957b69491ce7095a0e5c456edb68ea72bf90fa66..6c35a3eaa7a82aa62301701418507cbf3c66b475 100644 --- a/src/component/axis.js +++ b/src/component/axis.js @@ -1,9 +1,12 @@ // TODO Split line interval // TODO Axis tick interval +// TODO Axis name +// TODO Axis splitNumber, min, max define(function(require) { 'use strict'; - var numberUtil = require('../util/number'); + var zrUtil = require('zrender/core/util'); + var elementList = ['axisLine', 'axisLabel', 'axisTick', 'splitLine', 'splitArea']; require('../coord/cartesian/AxisModel'); @@ -25,23 +28,12 @@ define(function(require) { this._axisLinePosition = this._getAxisLinePosition(axisModel, gridModel); - var labelShowList; - if (axisModel.get('axisLabel.show')) { - labelShowList = this._renderAxisLabel(axisModel, gridModel, api); - } - if (axisModel.get('splitLine.show')) { - this._renderSplitLine(axisModel, gridModel, api, labelShowList); - } - if (axisModel.get('splitArea.show')) { - this._renderSplitArea(axisModel, gridModel, api, labelShowList); - } - - if (axisModel.get('axisLine.show')) { - this._renderAxisLine(axisModel, gridModel, api); - } - if (axisModel.get('axisTick.show')) { - this._renderAxisTick(axisModel, gridModel, api); - } + var showList = []; + zrUtil.each(elementList, function (name) { + if (axisModel.get(name +'.show')) { + this['_' + name](axisModel, gridModel, api, showList); + } + }, this); }, _getAxisLinePosition: function (axisModel, gridModel) { @@ -80,27 +72,23 @@ define(function(require) { * @param {module:echarts/ExtensionAPI} api * @private */ - _renderAxisLine: function (axisModel, gridModel, api) { + _axisLine: function (axisModel, gridModel, api) { var axis = axisModel.axis; - var grid = gridModel.coordinateSystem; var p1 = []; var p2 = []; var lineStyleModel = axisModel.getModel('axisLine.lineStyle'); var lineWidth = lineStyleModel.get('width'); - var lineColor = lineStyleModel.get('color'); - var lineType = lineStyleModel.get('type'); - - var rect = grid.getRect(); + var coordExtent = axis.getExtent(); if (axis.isHorizontal()) { - p1[0] = rect.x; - p2[0] = rect.x + rect.width; + p1[0] = coordExtent[0]; + p2[0] = coordExtent[1]; p1[1] = p2[1] = this._axisLinePosition; } else { - p1[1] = rect.y; - p2[1] = rect.y + rect.height; + p1[1] = coordExtent[0]; + p2[1] = coordExtent[1]; p1[0] = p2[0] = this._axisLinePosition; } @@ -113,12 +101,9 @@ define(function(require) { x2: p2[0], y2: p2[1] }, - style: { - stroke: lineColor, - lineWidth: lineWidth, - lineCap: 'round', - lineType: lineType - }, + style: zrUtil.merge({ + lineCap: 'round' + }, lineStyleModel.getLineStyle()), z: axisModel.get('z'), silent: true })); @@ -130,40 +115,36 @@ define(function(require) { * @param {module:echarts/ExtensionAPI} api * @private */ - _renderAxisTick: function (axisModel, gridModel, api) { + _axisTick: function (axisModel, gridModel, api) { var axis = axisModel.axis; var tickModel = axisModel.getModel('axisTick'); var lineStyleModel = tickModel.getModel('lineStyle'); var tickLen = tickModel.get('length'); - var tickColor = lineStyleModel.get('color'); var tickLineWidth = lineStyleModel.get('width'); var tickInterval = tickModel.get('interval') || 0; + var isTickInside = tickModel.get('inside'); + var isTickIntervalFunction = typeof tickInterval === 'function'; // PENDING Axis tick don't have the situation that don't have enough space to place if (tickInterval === 'auto') { tickInterval = 0; } - var isOrdinalAxis = axis.scale.type === 'ordinal'; - var axisPosition = axis.position; var ticksCoords = axis.getTicksPositions(); var tickLines = []; for (var i = 0; i < ticksCoords.length; i++) { // Only ordinal scale support tick interval - if (isOrdinalAxis) { - if (isTickIntervalFunction) { - if (!tickInterval(i, axis.scale.getItem(i))) { - continue; - } - } - else { - if (i % (tickInterval + 1)) { - continue; - } - } + if ( + axis.scale.type === 'ordinal' + && (isTickIntervalFunction + && !tickInterval(i, axis.scale.getItem(i)) + || i % (tickInterval + 1) + ) + ) { + continue } var tickCoord = ticksCoords[i]; @@ -183,12 +164,15 @@ define(function(require) { y = tickCoord; offX = axisPosition === 'left' ? -tickLen : tickLen; } - if (tickModel.get('inside')) { + + if (isTickInside) { offX = -offX; offY = -offY; } + var p1 = [x, y]; var p2 = [x + offX, y + offY]; + api.subPixelOptimizeLine(p1, p2, tickLineWidth); // Tick line tickLines.push(new api.Line({ @@ -201,10 +185,7 @@ define(function(require) { })); } var tickEl = api.mergePath(tickLines, { - style: { - stroke: tickColor, - lineWidth: tickLineWidth - }, + style: lineStyleModel.getLineStyle(), silent: true, z: axisModel.get('z') }); @@ -215,39 +196,15 @@ define(function(require) { * @param {module:echarts/coord/cartesian/AxisModel} axisModel * @param {module:echarts/coord/cartesian/GridModel} gridModel * @param {module:echarts/ExtensionAPI} api + * @param {Array.} showList * @private */ - _renderAxisLabel: function (axisModel, gridModel, api) { + _axisLabel: function (axisModel, gridModel, api, showList) { var axis = axisModel.axis; var labelModel = axisModel.getModel('axisLabel'); var textStyleModel = labelModel.getModel('textStyle'); - var labelFormatter = labelModel.get('formatter'); - if (!labelFormatter) { - // Default formatter - switch (axisModel.get('type')) { - // TODO - case 'log': - break; - case 'category': - labelFormatter = function (val) {return val;}; - break; - default: - labelFormatter = function (val) { - return numberUtil.addCommas(numberUtil.round(val)); - } - break; - } - } - else if (typeof labelFormatter === 'string') { - labelFormatter = (function (tpl) { - return function (val) { - return tpl.replace('{value}', val); - }; - })(labelFormatter); - } - var gridRect = gridModel.coordinateSystem.getRect(); var ticks = axis.scale.getTicks(); @@ -256,14 +213,22 @@ define(function(require) { var labelInterval = labelModel.get('interval') || 0; var isLabelIntervalFunction = typeof labelInterval === 'function'; - var labelShowList = []; - var textSpaceTakenRect; var needsCheckTextSpace; + var labels; + if (axis.scale.type === 'ordinal') { + labels = zrUtil.map(ticks, zrUtil.bind(axis.scale.getItem, axis.scale)); + } + else { + labels = ticks.slice(); + } + + labels = axisModel.formatLabels(labels); + for (var i = 0; i < ticks.length; i++) { // Default is false - labelShowList[i] = false; + showList[i] = false; needsCheckTextSpace = false; @@ -272,15 +237,10 @@ define(function(require) { if (labelInterval === 'auto') { needsCheckTextSpace = true; } - else if (isLabelIntervalFunction) { - if (!labelInterval(tick, axis.scale.getItem(tick))) { - continue; - } - } - else { - if (tick % (labelInterval + 1)) { - continue; - } + if (isLabelIntervalFunction + && !labelInterval(tick, axis.scale.getItem(tick)) + || tick % (labelInterval + 1)) { + continue; } } @@ -291,15 +251,6 @@ define(function(require) { var labelTextAlign = 'center'; var labelTextBaseline = 'middle'; - var label = tick; - switch (axis.type) { - case 'category': - label = axis.scale.getItem(tick); - break; - case 'time': - // TODO - } - switch (axis.position) { case 'top': y = gridRect.y - labelMargin; @@ -321,19 +272,18 @@ define(function(require) { y = tickCoord; labelTextAlign = 'left'; } - if (axis.isHorizontal()) { - if (labelRotate) { - labelTextAlign = labelRotate > 0 ? 'left' : 'right'; - } + if (axis.isHorizontal() && labelRotate) { + labelTextAlign = labelRotate > 0 ? 'left' : 'right'; } var textEl = new api.Text({ style: { x: x, y: y, - text: labelFormatter(label), + text: labels[i], textAlign: labelTextAlign, - textBaseline: labelTextBaseline + textBaseline: labelTextBaseline, + font: textStyleModel.getFont() }, rotation: labelRotate * Math.PI / 180, origin: [x, y], @@ -346,18 +296,16 @@ define(function(require) { if (!textSpaceTakenRect) { textSpaceTakenRect = rect; } + // There is no space for current label; + else if (textSpaceTakenRect.intersect(rect)) { + continue; + } else { - // There is no space for current label; - if (textSpaceTakenRect.intersect(rect)) { - continue; - } - else { - textSpaceTakenRect.union(rect); - } + textSpaceTakenRect.union(rect); } } - labelShowList[i] = true; + showList[i] = true; this.group.add(textEl); } @@ -370,14 +318,13 @@ define(function(require) { * @param {Array.} showList * @private */ - _renderSplitLine: function (axisModel, gridModel, api, showList) { + _splitLine: function (axisModel, gridModel, api, showList) { var axis = axisModel.axis; var splitLineModel = axisModel.getModel('splitLine'); var lineStyleModel = splitLineModel.getModel('lineStyle'); var lineWidth = lineStyleModel.get('width'); var lineColors = lineStyleModel.get('color'); - var lineType = lineStyleModel.get('type'); lineColors = lineColors instanceof Array ? lineColors : [lineColors]; @@ -426,7 +373,7 @@ define(function(require) { this.group.add(api.mergePath(splitLines[i], { style: { stroke: lineColors[i % lineColors.length], - lineType: lineType, + lineDash: lineStyleModel.getLineDash(), lineWidth: lineWidth }, silent: true, @@ -442,7 +389,7 @@ define(function(require) { * @param {Array.} showList * @private */ - _renderSplitArea: function (axisModel, gridModel, api, showList) { + _splitArea: function (axisModel, gridModel, api, showList) { var axis = axisModel.axis; var splitAreaModel = axisModel.getModel('splitArea'); @@ -451,8 +398,8 @@ define(function(require) { var gridRect = gridModel.coordinateSystem.getRect(); var ticksCoords = axis.getTicksPositions(); - var prevX; - var prevY; + var prevX = ticksCoords[0]; + var prevY = ticksCoords[0]; var splitAreaRects = []; var count = 0; @@ -490,8 +437,8 @@ define(function(require) { } })); - prevX = x; - prevY = y; + prevX = x + width; + prevY = y + height; } // Simple optimization diff --git a/src/component/grid.js b/src/component/grid.js index 47ceebd12c7d04dea40ae82b7be5fab8b15d21b0..fb95a33c69cf9384f775ced323cce42549034620 100644 --- a/src/component/grid.js +++ b/src/component/grid.js @@ -3,6 +3,8 @@ define(function(require) { require('../coord/cartesian/Grid'); + require('./axis'); + // Grid view require('../echarts').extendComponentView({ diff --git a/src/component/polar.js b/src/component/polar.js new file mode 100644 index 0000000000000000000000000000000000000000..4902a3bf21df6414b048acc9e14cf213303b0e72 --- /dev/null +++ b/src/component/polar.js @@ -0,0 +1,17 @@ +define(function(require) { + 'use strict'; + + require('../coord/polar/Polar'); + + require('./angleAxis'); + require('./radiusAxis'); + + // Polar view + require('../echarts').extendComponentView({ + + type: 'polar', + + render: function (gridModel, ecModel, api) { + } + }); +}); \ No newline at end of file diff --git a/src/component/radiusAxis.js b/src/component/radiusAxis.js new file mode 100644 index 0000000000000000000000000000000000000000..fee55045c32dc99305b04686ecbccf68e5f1eb20 --- /dev/null +++ b/src/component/radiusAxis.js @@ -0,0 +1,11 @@ +define(function (require) { + + require('../echarts').extendComponentView({ + + type: 'radiusAxis', + + render: function (radiusAxisModel, ecModel, api) { + + } + }); +}); \ No newline at end of file diff --git a/src/coord/Axis.js b/src/coord/Axis.js index 7b41ace58cfe9cad071fa28811430d8cf0c3100c..8d5cd4464cc1f84d2dc2f322041be7c12fe83f6e 100644 --- a/src/coord/Axis.js +++ b/src/coord/Axis.js @@ -32,7 +32,7 @@ define(function (require) { * @type {Array.} * @private */ - this._extent = extent; + this._extent = extent || [0, 0]; /** * @type {boolean} @@ -64,13 +64,13 @@ define(function (require) { /** * Set coord extent - * @param {number} min - * @param {number} max + * @param {number} start + * @param {number} end */ - setExtent: function (min, max) { + setExtent: function (start, end) { var extent = this._extent; - extent[0] = min; - extent[1] = max; + extent[0] = start; + extent[1] = end; }, /** @@ -138,8 +138,6 @@ define(function (require) { * If axis has ticks [1, 2, 3, 4]. Bands on the axis are * |---1---|---2---|---3---|---4---|. * - * If margin is true. Coord extent is start at the position of first tick and end - * at the position of last tick. * @return {Array} */ getBands: function () { diff --git a/src/coord/axisDefault.js b/src/coord/axisDefault.js new file mode 100644 index 0000000000000000000000000000000000000000..8dad734de0c57ab03c1026f8bccb751f47f08266 --- /dev/null +++ b/src/coord/axisDefault.js @@ -0,0 +1,116 @@ +define({ + valueAxis: { + show: true, + zlevel: 0, // 一级层叠 + z: 0, // 二级层叠 + inverse: false, // 反向坐标轴 + name: '', // 坐标轴名字,默认为空 + nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' + nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 + boundaryGap: [0, 0], // 数值起始和结束两端空白策略 + // min: null, // 最小值 + // max: null, // 最大值 + // scale: false, // 脱离0值比例,放大聚焦到最终_min,_max区间 + // splitNumber: 5, // 分割段数,默认为5 + axisLine: { // 坐标轴线 + show: true, // 默认显示,属性show控制显示与否 + onZero: true, + lineStyle: { // 属性lineStyle控制线条样式 + color: '#48b', + width: 2, + type: 'solid' + } + }, + axisTick: { // 坐标轴小标记 + show: true, // 属性show控制显示与否,默认显示 + inside: false, // 控制小标记是否在grid里 + length: 5, // 属性length控制线长 + lineStyle: { // 属性lineStyle控制线条样式 + color: '#333', + width: 1 + } + }, + axisLabel: { // 坐标轴文本标签,详见axis.axisLabel + show: true, + rotate: 0, + margin: 8, + // clickable: false, + // formatter: null, + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#333' + } + }, + splitLine: { // 分隔线 + show: true, // 默认显示,属性show控制显示与否 + lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 + color: ['#ccc'], + width: 1, + type: 'solid' + } + }, + splitArea: { // 分隔区域 + show: false, // 默认不显示,属性show控制显示与否 + areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 + color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] + } + } + }, + + categoryAxis: { + show: true, + zlevel: 0, // 一级层叠 + z: 0, // 二级层叠 + inverse: false, // 反向坐标轴 + name: '', // 坐标轴名字,默认为空 + nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' + nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 + boundaryGap: true, // 类目起始和结束两端空白策略 + axisLine: { // 坐标轴线 + show: true, // 默认显示,属性show控制显示与否 + onZero: true, + lineStyle: { // 属性lineStyle控制线条样式 + color: '#48b', + width: 2, + type: 'solid' + } + }, + axisTick: { // 坐标轴小标记 + show: true, // 属性show控制显示与否,默认不显示 + interval: 'auto', + inside: false, // 控制小标记是否在grid里 + // onGap: null, + length :5, // 属性length控制线长 + lineStyle: { // 属性lineStyle控制线条样式 + color: '#333', + width: 1 + } + }, + axisLabel: { // 坐标轴文本标签,详见axis.axisLabel + show: true, + interval: 'auto', + rotate: 0, + margin: 8, + // clickable: false, + // formatter: null, + textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#333' + } + }, + splitLine: { // 分隔线 + show: true, // 默认显示,属性show控制显示与否 + // onGap: null, + lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 + color: ['#ccc'], + width: 1, + type: 'solid' + } + }, + splitArea: { // 分隔区域 + show: false, // 默认不显示,属性show控制显示与否 + // onGap: null, + areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 + color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] + } + } + } +}); \ No newline at end of file diff --git a/src/coord/axisModelCommonMixin.js b/src/coord/axisModelCommonMixin.js new file mode 100644 index 0000000000000000000000000000000000000000..8d6247743896bd57763bf2e1ffc57ab3ca084ef0 --- /dev/null +++ b/src/coord/axisModelCommonMixin.js @@ -0,0 +1,48 @@ +define(function (require) { + + var numberUtil = require('../util/number'); + var zrUtil = require('zrender/core/util'); + + function categoryDefaultFormatter(val) { + return val; + } + + /** + * Format labels + * @param {Array.} labels + * @return {Array.} + */ + function formatLabels (labels) { + var labelFormatter = this.get('axisLabel.formatter'); + + if (! labelFormatter) { + switch (this.get('type')) { + case 'category': + labelFormatter = categoryDefaultFormatter; + break; + case 'time': + break; + case 'log': + // TODO + break; + default: + labelFormatter = function (val) { + return numberUtil.addCommas(numberUtil.round(val)); + }; + } + } + else if (typeof labelFormatter === 'string') { + labelFormatter = (function (tpl) { + return function (val) { + return tpl.replace('{value}', val); + }; + })(labelFormatter); + } + + return zrUtil.map(labels, labelFormatter); + } + + return { + formatLabels: formatLabels + }; +}); \ No newline at end of file diff --git a/src/coord/cartesian/AxisModel.js b/src/coord/cartesian/AxisModel.js index bf422c97818c901516644a5d9321eb7396235ec7..d6f9444aba9c7d14658ac7527bd0cb41f6514603 100644 --- a/src/coord/cartesian/AxisModel.js +++ b/src/coord/cartesian/AxisModel.js @@ -2,128 +2,7 @@ define(function(require) { 'use strict'; - var defaultOption = { - - valueAxis: { - show: true, - zlevel: 0, // 一级层叠 - z: 0, // 二级层叠 - gridIndex: 0, - inverse: false, // 反向坐标轴 - name: '', // 坐标轴名字,默认为空 - nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' - nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 - boundaryGap: [0, 0], // 数值起始和结束两端空白策略 - // min: null, // 最小值 - // max: null, // 最大值 - // scale: false, // 脱离0值比例,放大聚焦到最终_min,_max区间 - // splitNumber: 5, // 分割段数,默认为5 - dataZoomStart: 0, // 并不开放设置,而是由dataZoom设置 - dataZoomEnd: 100, // 并不开放设置,而是由dataZoom设置 - axisLine: { // 坐标轴线 - show: true, // 默认显示,属性show控制显示与否 - onZero: true, - lineStyle: { // 属性lineStyle控制线条样式 - color: '#48b', - width: 2, - type: 'solid' - } - }, - axisTick: { // 坐标轴小标记 - show: true, // 属性show控制显示与否,默认显示 - inside: false, // 控制小标记是否在grid里 - length: 5, // 属性length控制线长 - lineStyle: { // 属性lineStyle控制线条样式 - color: '#333', - width: 1 - } - }, - axisLabel: { // 坐标轴文本标签,详见axis.axisLabel - show: true, - rotate: 0, - margin: 8, - // clickable: false, - // formatter: null, - textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE - color: '#333' - } - }, - splitLine: { // 分隔线 - show: true, // 默认显示,属性show控制显示与否 - lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 - color: ['#ccc'], - width: 1, - type: 'solid' - } - }, - splitArea: { // 分隔区域 - show: false, // 默认不显示,属性show控制显示与否 - areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 - color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] - } - } - }, - - categoryAxis: { - show: true, - zlevel: 0, // 一级层叠 - z: 0, // 二级层叠 - gridIndex: 0, - inverse: false, // 反向坐标轴 - name: '', // 坐标轴名字,默认为空 - nameLocation: 'end', // 坐标轴名字位置,支持'start' | 'end' - nameTextStyle: {}, // 坐标轴文字样式,默认取全局样式 - boundaryGap: true, // 类目起始和结束两端空白策略 - axisLine: { // 坐标轴线 - show: true, // 默认显示,属性show控制显示与否 - onZero: true, - lineStyle: { // 属性lineStyle控制线条样式 - color: '#48b', - width: 2, - type: 'solid' - } - }, - axisTick: { // 坐标轴小标记 - show: true, // 属性show控制显示与否,默认不显示 - interval: 'auto', - inside: false, // 控制小标记是否在grid里 - // onGap: null, - length :5, // 属性length控制线长 - lineStyle: { // 属性lineStyle控制线条样式 - color: '#333', - width: 1 - } - }, - axisLabel: { // 坐标轴文本标签,详见axis.axisLabel - show: true, - interval: 'auto', - rotate: 0, - margin: 8, - // clickable: false, - // formatter: null, - textStyle: { // 其余属性默认使用全局文本样式,详见TEXTSTYLE - color: '#333' - } - }, - splitLine: { // 分隔线 - show: true, // 默认显示,属性show控制显示与否 - // onGap: null, - lineStyle: { // 属性lineStyle(详见lineStyle)控制线条样式 - color: ['#ccc'], - width: 1, - type: 'solid' - } - }, - splitArea: { // 分隔区域 - show: false, // 默认不显示,属性show控制显示与否 - // onGap: null, - areaStyle: { // 属性areaStyle(详见areaStyle)控制区域样式 - color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)'] - } - } - } - }; - + var defaultOption = require('../axisDefault'); var zrUtil = require('zrender/core/util'); function mergeDefault(axisOption, ecModel) { @@ -135,7 +14,7 @@ define(function(require) { } var AxisModel = require('../../model/Component').extend({ - type: 'axis', + type: 'cartesian2dAxis', /** * @type {module:echarts/coord/cartesian/Axis2D} @@ -154,7 +33,11 @@ define(function(require) { } }); - AxisModel.AxisX = AxisModel.extend({ + zrUtil.merge(AxisModel.prototype, require('../axisModelCommonMixin')); + + + // x axis + AxisModel.extend({ type: 'xAxis', @@ -163,11 +46,14 @@ define(function(require) { axisOption.position = axisOption.position || 'bottom'; + axisOption.gridIndex = axisOption.gridIndex || 0; + mergeDefault(axisOption, ecModel); } }); - AxisModel.AxisY = AxisModel.extend({ + // y axis + AxisModel.extend({ type: 'yAxis', @@ -176,6 +62,8 @@ define(function(require) { axisOption.position = axisOption.position || 'left'; + axisOption.gridIndex = axisOption.gridIndex || 0; + mergeDefault(axisOption, ecModel); } }); diff --git a/src/coord/cartesian/Cartesian2D.js b/src/coord/cartesian/Cartesian2D.js index ad440f2087d819f5f5475b80f18ed2ec497f9b94..21e4939d3a17b823702725e065b8a42974d41c2c 100644 --- a/src/coord/cartesian/Cartesian2D.js +++ b/src/coord/cartesian/Cartesian2D.js @@ -33,6 +33,14 @@ define(function(require) { coord[1 - xIndex] = yAxis.dataToCoord(dataItem.getY()); return coord; }, this); + }, + + /** + * Get other axis + * @param {module:echarts/coord/cartesian/Axis2D} axis + */ + getOtherAxis: function (axis) { + return this.getAxis(axis.dim === 'x' ? 'y' : 'x'); } }; diff --git a/src/coord/cartesian/Grid.js b/src/coord/cartesian/Grid.js index f4e97ed6edaf17cfe29b75de0301ef19964da3eb..f54ad2911cc47bb53622b09c2a5e8ffd041e4d6e 100644 --- a/src/coord/cartesian/Grid.js +++ b/src/coord/cartesian/Grid.js @@ -16,9 +16,30 @@ define(function(require, factory) { // 依赖 GridModel, AxisModel 做预处理 require('./GridModel'); - require('./AxisModel'); - function Grid(gridModel, ecModel) { + /** + * @param {module:echarts/coord/cartesian/AxisModel} axisModel + * @return {module:echarts/scale/*} + * @inner + */ + function createScaleByModel(axisModel) { + var axisType = axisModel.get('type'); + if (axisType) { + return axisType === 'category' + ? new OrdinalScale(axisModel.get('data')) + : new IntervalScale(); + } + }; + + /** + * Check if the axis is used in the specified grid + * @inner + */ + function isAxisUsedInTheGrid(axisModel, gridModel, ecModel) { + return ecModel.getComponent('grid', axisModel.get('gridIndex')) === gridModel; + } + + function Grid(gridModel, ecModel, api) { /** * @type {number} @@ -68,7 +89,7 @@ define(function(require, factory) { */ this._axesList = []; - this._initCartesian(gridModel, ecModel); + this._initCartesian(gridModel, ecModel, api); } Grid.prototype = { @@ -86,6 +107,8 @@ define(function(require, factory) { /** * Resize the grid + * @param {module:echarts/coord/cartesian/GridModel} gridModel + * @param {module:echarts/ExtensionAPI} api */ resize: function (gridModel, api) { var viewportWidth = api.getWidth(); @@ -113,28 +136,21 @@ define(function(require, factory) { zrUtil.each(this._axesList, function (axis) { var extent; - var otherCoord; switch (axis.position) { case 'top': extent = [gridX, gridX + gridWidth]; - otherCoord = gridY; break; case 'left': extent = [gridY, gridY + gridHeight]; - otherCoord = gridX; break; case 'right': extent = [gridY, gridY + gridHeight]; - otherCoord = gridX + gridWidth; break; default: // Bottom extent = [gridX, gridX + gridWidth]; - otherCoord = gridY + gridHeight; break; } - axis.otherCoord = otherCoord; - var start = axis.isHorizontal() ? 0 : 1; axis.setExtent(extent[start], extent[1 - start]); }); @@ -158,34 +174,25 @@ define(function(require, factory) { * Initialize cartesian coordinate systems * @private */ - _initCartesian: function (gridModel, ecModel) { - /** - * @inner - */ - var getScaleByOption = function (axisType, axisModel) { - if (axisType) { - return axisType === 'value' - ? new IntervalScale() - : new OrdinalScale(axisModel.get('data')); - } - }; - + _initCartesian: function (gridModel, ecModel, api) { var leftUsed = false; var bottomUsed = false; + var xAxesMap = {}; + var yAxesMap = {}; + var xAxesCount = 0; + var yAxesCount = 0; + ecModel.eachComponent('xAxis', function (xAxisModel, idx) { - if (ecModel.getComponent( - 'grid', xAxisModel.get('gridIndex') - ) !== gridModel) { + if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel)) { return; } // Create x axis - var xAxisType = xAxisModel.get('type'); var xAxisPosition = xAxisModel.get('position') || (bottomUsed ? 'top' : 'bottom'); bottomUsed = xAxisPosition === 'bottom'; var axisX = new Axis2D( - 'x', getScaleByOption(xAxisType, xAxisModel), + 'x', createScaleByModel(xAxisModel), [0, 0], xAxisModel.get('type'), xAxisPosition @@ -198,21 +205,21 @@ define(function(require, factory) { this._axesList.push(axisX); this._axesMap['x' + idx] = axisX; + + xAxesMap[idx] = axisX; + xAxesCount++; }, this); ecModel.eachComponent('yAxis', function (yAxisModel, idx) { - if (ecModel.getComponent( - 'grid', yAxisModel.get('gridIndex') - ) !== gridModel) { + if (!isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel)) { return; } // Create y axis - var yAxisType = yAxisModel.get('type'); var yAxisPosition = yAxisModel.get('position') || (leftUsed ? 'right' : 'left'); leftUsed = yAxisPosition === 'left'; var axisY = new Axis2D( - 'y', getScaleByOption(yAxisType, yAxisModel), + 'y', createScaleByModel(yAxisModel), [0, 0], yAxisModel.get('type'), yAxisModel.get('position') @@ -224,8 +231,31 @@ define(function(require, factory) { this._axesList.push(axisY); this._axesMap['y' + idx] = axisY; + + xAxesMap[idx] = axisY; + yAxesCount++; }, this); + if (! xAxesCount || ! yAxesCount) { + api.log('Grid must has at least one x axis and one y axis'); + // Roll back + this._axesMap = {}; + this._axesList = []; + return; + } + + zrUtil.each(xAxesMap, function (xAxis, xAxisIndex) { + zrUtil.each(yAxesMap, function (yAxis, yAxisIndex) { + var key = 'x' + xAxisIndex + 'y' + yAxisIndex; + var cartesian = new Cartesian2D(key); + this._coordsMap[key] = cartesian; + this._coordsList.push(cartesian); + + cartesian.addAxis(xAxis); + cartesian.addAxis(yAxis); + }); + }); + ecModel.eachComponent('xAxis', function (xAxisModel, i) { ecModel.eachComponent('yAxis', function (yAxisModel, j) { var key = 'x' + i + 'y' + j; @@ -238,7 +268,7 @@ define(function(require, factory) { }, this); }, this); - this._updateCartesianFromSeries(ecModel); + this._updateCartesianFromSeries(ecModel, gridModel); }, /** @@ -246,16 +276,23 @@ define(function(require, factory) { * @param {module:echarts/model/Option} option * @private */ - _updateCartesianFromSeries: function (ecModel) { + _updateCartesianFromSeries: function (ecModel, gridModel) { var axisDataMap = {}; ecModel.eachSeries(function (seriesModel) { - var coordinateSystem = seriesModel.get('coordinateSystem'); - - if (coordinateSystem === 'cartesian2d') { + if (seriesModel.get('coordinateSystem') === 'cartesian2d') { var xAxisIndex = seriesModel.get('xAxisIndex'); var yAxisIndex = seriesModel.get('yAxisIndex'); + var xAxisModel = ecModel.getComponent('xAxis', xAxisIndex); + var yAxisModel = ecModel.getComponent('yAxis', yAxisIndex); + + if (!isAxisUsedInTheGrid(xAxisModel, gridModel, ecModel) + || !isAxisUsedInTheGrid(yAxisModel, gridModel, ecModel) + ) { + return; + } + var cartesian = this.getCartesian(xAxisIndex, yAxisIndex); var axisData = axisDataMap[cartesian.name]; if (! axisData) { @@ -263,8 +300,8 @@ define(function(require, factory) { x: [], y: [], cartesian: cartesian, - xModel: ecModel.getComponent('xAxis', xAxisIndex), - yModel: ecModel.getComponent('yAxis', yAxisIndex) + xModel: xAxisModel, + yModel: yAxisModel }; } @@ -317,8 +354,8 @@ define(function(require, factory) { Grid.create = function (ecModel, api) { var grids = []; - ecModel.eachComponent('grid', function (gridModel) { - var grid = new Grid(gridModel, ecModel); + ecModel.eachComponent('grid', function (gridModel, idx) { + var grid = new Grid(gridModel, ecModel, api); grid.resize(gridModel, api); // Inject the coordinateSystems into seriesModel diff --git a/src/coord/cartesian/GridModel.js b/src/coord/cartesian/GridModel.js index 81750932269aa75959dd3a78b135a793eda998e3..6485cedcad689083f3a61ca98a459e4dbdcc2e66 100644 --- a/src/coord/cartesian/GridModel.js +++ b/src/coord/cartesian/GridModel.js @@ -4,10 +4,15 @@ define(function(require) { 'use strict'; - return require('../../model/Component').extend({ + require('./AxisModel'); + + require('../../echarts').extendComponentModel({ type: 'grid', + dependencies: ['xAxis', 'yAxis'], + + /** /** * @type {module:echarts/coord/cartesian/Grid} */ diff --git a/src/coord/polar/AngleAxis.js b/src/coord/polar/AngleAxis.js new file mode 100644 index 0000000000000000000000000000000000000000..6ef659cc4329f0429703516845fd25c7ec10b2ca --- /dev/null +++ b/src/coord/polar/AngleAxis.js @@ -0,0 +1,36 @@ +define(function(require) { + 'use strict'; + + var zrUtil = require('zrender/core/util'); + var Axis = require('../Axis'); + + function AngleAxis(scale, angleExtent) { + + angleExtent = angleExtent || [0, Math.PI * 2]; + + Axis.call(this, 'angle', scale, angleExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = 'category'; + }; + + AngleAxis.prototype = { + + constructor: AngleAxis, + + dataToAngle: Axis.prototype.mapData, + + angleToData: Axis.prototype.unmapData + }; + + zrUtil.inherits(AngleAxis, Axis); + + return AngleAxis; +}); \ No newline at end of file diff --git a/src/coord/polar/AxisModel.js b/src/coord/polar/AxisModel.js new file mode 100644 index 0000000000000000000000000000000000000000..b4acf4643b89d97397665055ab67901e14334604 --- /dev/null +++ b/src/coord/polar/AxisModel.js @@ -0,0 +1,66 @@ +define(function(require) { + + 'use strict'; + + var axisDefault = require('../axisDefault'); + + var zrUtil = require('zrender/core/util'); + + function mergeDefault(axisOption, ecModel) { + var axisType = axisOption.type + 'Axis'; + + zrUtil.merge(axisOption, ecModel.get(axisType)); + zrUtil.merge(axisOption, ecModel.getTheme().get(axisType)); + zrUtil.merge(axisOption, axisDefault[axisType]); + } + + var PolarAxisModel = require('../../model/Component').extend({ + type: 'polarAxis', + /** + * @type {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + */ + axis: null + }); + + zrUtil.merge(PolarAxisModel.prototype, require('../axisModelCommonMixin')); + + + + // Radius axis + PolarAxisModel.extend({ + + type: 'radiusAxis', + + /** + * @type {module:echarts/coord/polar/RadiusAxis} + */ + axis: null, + + init: function (axisOption, parentModel, ecModel) { + axisOption.type = axisOption.type || 'value'; + + axisOption.polarIndex = axisOption.polarIndex || 0; + + mergeDefault(axisOption, ecModel); + } + }); + + // Angle axis + PolarAxisModel.extend({ + + type: 'angleAxis', + + /** + * @type {module:echarts/coord/polar/AngleAxis} + */ + axis: null, + + init: function (axisOption, parentModel, ecModel) { + axisOption.type = axisOption.type || 'category'; + + axisOption.polarIndex = axisOption.polarIndex || 0; + + mergeDefault(axisOption, ecModel); + } + }); +}); \ No newline at end of file diff --git a/src/coord/polar/Polar.js b/src/coord/polar/Polar.js index 14d293bbbeef220581b5d87d893626268aba026d..b5af6c012f765011b47b8f90c70205fee2743e35 100644 --- a/src/coord/polar/Polar.js +++ b/src/coord/polar/Polar.js @@ -1,10 +1,120 @@ +/** + * @module echarts/coord/polar/Polar + */ define(function(require) { 'use strict'; - var Polar = function () { + var RadiusAxis = require('./RadiusAxis'); + var AngleAxis = require('./AngleAxis'); + /** + * @alias {module:echarts/coord/polar/Polar} + * @constructor + * @param {string} name + */ + var Polar = function (name) { + + /** + * @type {string} + */ + this.name = name || ''; + + /** + * x of polar center + * @type {number} + */ + this.cx = 0; + + /** + * y of polar center + * @type {number} + */ + this.cy = 0; + + /** + * @type {module:echarts/coord/polar/RadiusAxis} + * @private + */ + this._radiusAxis = new RadiusAxis(); + + /** + * @type {module:echarts/coord/polar/AngleAxis} + * @private + */ + this._angleAxis = new AngleAxis(); }; + Polar.prototype = { + + constructor: Polar, + + type: 'polar', + + /** + * @return {module:echarts/coord/polar/AngleAxis} + */ + getAngleAxis: function () { + return this._angleAxis; + }, + + /** + * @return {module:echarts/coord/polar/RadiusAxis} + */ + getRadiusAxis: function () { + return this._radiusAxis; + }, + + /** + * Convert series data to a list of coorindates + * @param {module:echarts/data/List} data + * @return {Array} + * Return list of coordinates. For example: + * `[[10, 10], [20, 20], [30, 30]]` + */ + dataToCoords: function (data) { + return data.map(function (dataItem) { + return this.dataToCoord([dataItem.getRadius(), dataItem.getAngle()]); + }, this); + }, + + /** + * Convert a single data item to coordinate. + * Parameter data is an array which the first element is radius and the second is angle + * @param {Array.} data + * @return {Array.} + */ + dataToCoord: function (data) { + var radius = this._radiusAxis.dataToRadius(data[0]); + var angle = this._angleAxis.dataToAngle(data[1]); + + var x = Math.cos(angle) * radius + this.cx; + var y = Math.sin(angle) * radius + this.cy; + + return [x, y]; + }, + + /** + * Convert a coord to data + * @param {Array.} coord + * @return {Array.} + */ + coordToData: function (coord) { + var dx = coord[0] - this.cx; + var dy = coord[1] - this.cy; + + var radius = Math.sqrt(dx * dx + dy * dy); + dx /= radius; + dy /= radius; + + var angle = Math.atan2(dy, dx); + + return [ + this._radiusAxis.radiusToData(radius), + this._angleAxis.angleToData(angle) + ]; + } + } + return Polar; }); \ No newline at end of file diff --git a/src/coord/polar/PolarModel.js b/src/coord/polar/PolarModel.js new file mode 100644 index 0000000000000000000000000000000000000000..05562b863f8df909f79c906e1f9347d43218c77d --- /dev/null +++ b/src/coord/polar/PolarModel.js @@ -0,0 +1,29 @@ +define(function (require) { + + 'use strict'; + + require('./AxisModel'); + + require('../../echarts').extendComponentModel({ + + type: 'polar', + + dependencies: ['polarAxis', 'angleAxis'], + + /** + * @type {module:echarts/coord/polar/Polar} + */ + coordinateSystem: null, + + defaultOption: { + + zlevel: 0, + + z: 0, + + center: ['50%', '50%'], + + radius: ['0%', '75%'] + } + }); +}); \ No newline at end of file diff --git a/src/coord/polar/RadiusAxis.js b/src/coord/polar/RadiusAxis.js new file mode 100644 index 0000000000000000000000000000000000000000..686167475f57ab200cb5de42530e9c362a052391 --- /dev/null +++ b/src/coord/polar/RadiusAxis.js @@ -0,0 +1,34 @@ +define(function (require) { + 'use strict'; + + var zrUtil = require('zrender/core/util'); + var Axis = require('../Axis'); + + function RadiusAxis(scale, radiusExtent) { + + Axis.call(this, 'radius', scale, radiusExtent); + + /** + * Axis type + * - 'category' + * - 'value' + * - 'time' + * - 'log' + * @type {string} + */ + this.type = 'category'; + } + + RadiusAxis.prototype = { + + constructor: RadiusAxis, + + dataToRadius: Axis.prototype.mapData, + + radiusToData: Axis.prototype.unmapData + }; + + zrUtil.inherits(RadiusAxis, Axis); + + return RadiusAxis; +}); \ No newline at end of file diff --git a/src/coord/polar/polarCreator.js b/src/coord/polar/polarCreator.js index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ebc47fdee089de0323401c38ba65bf1c4472d657 100644 --- a/src/coord/polar/polarCreator.js +++ b/src/coord/polar/polarCreator.js @@ -0,0 +1,152 @@ +// TODO Axis scale +define(function (require) { + + var Polar = require('./Polar'); + var IntervalScale = require('../../scale/Interval'); + var OrdinalScale = require('../../scale/Ordinal'); + var numberUtil = require('../../util/number'); + + // 依赖 PolarModel, AxisModel 做预处理 + require('./PolarModel'); + require('./AxisModel'); + + /** + * Retrieve angle axis or radius axis belongs to the given polar + * @param {string} axisType + * @param {number} polarIndex + * @param {module:echarts/model/Global} ecModel + * @param {module:echarts/ExtensionAPI} api + * @return {module:echarts/coord/polar/AxisModel} + * @inner + */ + function retrieveAxisModelForPolar(axisType, polarIndex, ecModel, api) { + var axisModel; + ecModel.eachComponent(axisType, function (model) { + if (model.get('polarIndex') === polarIndex) { + if (axisModel) { + api.log('Polar ' + polarIndex + ' has more than one ' + axisType); + return; + } + axisModel = model; + } + }); + return axisModel; + } + + /** + * Resize methods bound to the polar + * @param {module:echarts/coord/polar/PolarModel} polarModel + * @param {module:echarts/ExtensionAPI} api + */ + function resizePolar(polarModel, api) { + var center = polarModel.get('center'); + var radius = polarModel.get('radius'); + var width = api.getWidth(); + var height = api.getHeight(); + var parsePercent = numberUtil.parsePercent; + + this.cx = parsePercent(center[0], width); + this.cy = parsePercent(center[1], height); + + var radiusAxis = this.getRadiusAxis(); + var size = Math.min(width, height); + radiusAxis.setExtent( + parsePercent(radius[0], size), + parsePercent(radius[1], size) + ); + } + + /** + * @param {module:echarts/coord/cartesian/AxisModel} axisModel + * @return {module:echarts/scale/*} + * @inner + */ + function createScaleByModel(axisModel) { + var axisType = axisModel.get('type'); + if (axisType) { + return axisType === 'value' + ? new IntervalScale() + : new OrdinalScale(axisModel.get('data')); + } + }; + + /** + * Set common axis properties + * @param {module:echarts/coord/polar/AngleAxis|module:echarts/coord/polar/RadiusAxis} + * @param {module:echarts/coord/polar/AxisModel} + * @inner + */ + function setAxis(axis, axisModel) { + axis.type = axisModel.get('type'); + axis.scale = createScaleByModel(axisModel); + axis.onBand = axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + + // Inject axis instance + axisModel.axis = axis; + } + + /** + * Set polar axis scale from series data + */ + function setPolarAxisFromSeries(polarList, ecModel, api) { + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.get('coordinateSystem') === 'polar') { + var polarIndex = seriesModel.get('polarIndex') || 0; + + var polar = polarList[polarIndex]; + if (! polar) { + api.log('Polar configuration not exist for series ' + seriesModel.name + '.'); + return; + } + // Inject polar instance + seriesModel.coordinateSystem = polar; + + var radiusAxis = polar.getRadiusAxis(); + var angleAxis = polar.getAngleAxis(); + var isRadiusCategory = radiusAxis.type === 'category'; + var isAngleCategory = angleAxis.type === 'category'; + + var data = seriesModel.getData(); + if (! isRadiusCategory) { + radiusAxis.scale.setExtentFromData(data.map(function (dataItem) { return dataItem.getRadius(); }), true); + } + if (! isAngleCategory) { + angleAxis.scale.setExtentFromData(data.map(function (dataItem) { return dataItem.getAngle(); }), true); + } + } + }); + } + + var polarCreator = { + + create: function (ecModel, api) { + var polarList = []; + ecModel.eachComponent('polar', function (polarModel, idx) { + var polar = new Polar(idx); + // Inject resize method + polar.resize = resizePolar; + + var radiusAxis = polar.getRadiusAxis(); + var angleAxis = polar.getAngleAxis(); + + var radiusAxisModel = retrieveAxisModelForPolar('radiusAxis', idx, ecModel, api); + var angleAxisModel = retrieveAxisModelForPolar('angleAxis', idx, ecModel, api); + + setAxis(radiusAxis, radiusAxisModel); + setAxis(angleAxis, angleAxisModel); + + polar.resize(polarModel, api); + polarList.push(polar); + + polarModel.coordinateSystem = polar; + }); + + setPolarAxisFromSeries(polarList, ecModel, api); + + return polarList; + } + }; + + require('../../CoordinateSystem').register('polar', polarCreator); +}); \ No newline at end of file diff --git a/src/data/List.js b/src/data/List.js index 449220df236923187cdc7980d06249252d530610..3c758c08b05a642cf8bf07feb648777912b021d6 100644 --- a/src/data/List.js +++ b/src/data/List.js @@ -1,3 +1,5 @@ +// TODO entry.getLon(), entry.getLat() +// List supported for cartesian, polar coordinateSystem define(function(require) { 'use strict'; @@ -25,7 +27,7 @@ define(function(require) { } } } - + var dimensions = ['x', 'y', 'z', 'value', 'radius', 'angle'] /** * @name echarts/data/List~Entry * @extends {module:echarts/model/Model} @@ -58,6 +60,18 @@ define(function(require) { */ zIndex: -1, + /** + * @type {number} + * @protected + */ + radiusIndex: 0, + + /** + * @type {number} + * @protected + */ + angleIndex: 1, + /** * @type {number} * @protected @@ -119,15 +133,16 @@ define(function(require) { this.option, this.parentModel, this.dataIndex ); entry.name = this.name; - entry.xIndex = this.xIndex; - entry.yIndex = this.yIndex; - entry.zIndex = this.zIndex; - entry.valueIndex = this.valueIndex; + + for (var i = 0; i < dimensions.length; i++) { + var key = dimensions[i] + 'Index'; + entry[key] = this[key]; + } return entry; } }); - zrUtil.each(['x', 'y', 'z', 'value'], function (dim) { + zrUtil.each(dimensions, function (dim) { var capitalized = dim[0].toUpperCase() + dim.substr(1); var indexKey = dim + 'Index'; Entry.prototype['get' + capitalized] = function () { @@ -247,28 +262,62 @@ define(function(require) { }); List.fromArray = function (data, seriesModel, ecModel) { - var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex')); - var yAxisModel = ecModel.getComponent('yAxis', seriesModel.get('yAxisIndex')); + var coordinateSystem = seriesModel.get('coordinateSystem'); var independentVar; var dependentVar; - if (xAxisModel.get('type') === 'category') { - independentVar = ['x']; - dependentVar = 'y'; - } - else if (yAxisModel.get('type') === 'category') { - independentVar = ['y']; - dependentVar = 'x'; - } - else { - var dim = data[0] && data[0].length; - if (dim === 2) { + // FIXME + // 这里 List 跟几个坐标系和坐标系 Model 耦合了 + if (coordinateSystem === 'cartesian2d') { + var xAxisModel = ecModel.getComponent('xAxis', seriesModel.get('xAxisIndex')); + var yAxisModel = ecModel.getComponent('yAxis', seriesModel.get('yAxisIndex')); + if (xAxisModel.get('type') === 'category') { independentVar = ['x']; dependentVar = 'y'; } - else if (dim === 3) { - independentVar = ['x', 'y']; - dependentVar = 'z'; + else if (yAxisModel.get('type') === 'category') { + independentVar = ['y']; + dependentVar = 'x'; + } + else { + // PENDING + var dim = data[0] && data[0].length; + if (dim === 2) { + independentVar = ['x']; + dependentVar = 'y'; + } + else if (dim === 3) { + independentVar = ['x', 'y']; + dependentVar = 'z'; + } + } + } + else if (coordinateSystem === 'polar') { + function axisFinder(axisModel) { + return axisModel.get('polarIndex') === polarIndex; + }; + var polarIndex = seriesModel.get('polarIndex') || 0; + var angleAxisModel = ecModel.findComponent('angleAxis', axisFinder); + var radiusAxisModel = ecModel.findComponent('radiusAxis', axisFinder); + + if (angleAxisModel.get('type') === 'category') { + independentVar = ['angle']; + dependentVar = 'radius'; + } + else if (radiusAxisModel.get('type') === 'category') { + independentVar = ['radius']; + dependentVar = 'angle'; + } + else { + var dim = data[0] && data[0].length; + if (dim === 2) { + independentVar = ['radius']; + dependentVar = 'angle'; + } + else if (dim === 3) { + independentVar = ['radius', 'angle']; + dependentVar = 'value'; + } } } @@ -277,7 +326,7 @@ define(function(require) { // Normalize data list.elements = zrUtil.map(data, function (dataItem, index) { var entry = new Entry(dataItem, seriesModel, index, independentVar, dependentVar); - // TODO + // FIXME if (! dataItem.name) { entry.name = index; } diff --git a/src/model/Global.js b/src/model/Global.js index f7a6de16f32e8b03a99799edf43abcdcf8b95e16..ad7473d59d93e84af9e229972b0044351ce6d940 100644 --- a/src/model/Global.js +++ b/src/model/Global.js @@ -108,6 +108,8 @@ define(function (require) { } }); + // FIXME 这里 componentTypes 是新的 Option,在依赖处理上是否会有问题 + // FIXME OPTION 同步是否要改回原来的 ComponentModel.topologicalTravel(componentTypes, function (componentType, dependencies) { var componentOption = newOption[componentType]; @@ -125,6 +127,10 @@ define(function (require) { componentType, componentOption[i] ); + if (! ComponentModelClass) { + throw new Error('Component ' + componentType + ' not exists'); + } + if (componentModel && componentModel instanceof ComponentModelClass) { componentModel.mergeOption(componentOption[i], this); } @@ -171,6 +177,24 @@ define(function (require) { zrUtil.each(this._componentsMap[type], cb, context); }, + /** + * @param {string} type + * @param {Function} cb + * @param {*} context + * @return {module:echarts/model/Component} + */ + findComponent: function (type, cb, context) { + var components = this._componentsMap[type]; + if (components) { + for (var i = 0, len = components.length; i < len; i++) { + if (cb.call(context, components[i], i)) { + // Return first found + return components[i]; + } + } + } + }, + /** * @param {string} name * @param {boolean} beforeProcessing @@ -221,6 +245,11 @@ define(function (require) { zrUtil.each(this._componentsMap.series, cb, context); }, + /** + * @parma {string} type + * @param {Function} cb + * @param {*} context + */ eachSeriesByType: function (type, cb, context) { return zrUtil.each(this.getSeriesByType(type), cb, context); }, diff --git a/src/model/Model.js b/src/model/Model.js index 31c1ec467781bba3b8b029d565b3ac840ac6809f..bbcff080ae3d9244811f3b298dbf5184e36d6cf8 100644 --- a/src/model/Model.js +++ b/src/model/Model.js @@ -64,7 +64,6 @@ define(function (require) { */ get: function (path, parentModel) { if (typeof path === 'string') { - // path = this._prefix + path; path = path.split('.'); } if (this.option == null) { @@ -156,5 +155,10 @@ define(function (require) { return ExtendedModel; }; + zrUtil.merge(Model.prototype, require('./mixin/lineStyle')); + zrUtil.merge(Model.prototype, require('./mixin/areaStyle')); + zrUtil.merge(Model.prototype, require('./mixin/textStyle')); + zrUtil.merge(Model.prototype, require('./mixin/itemStyle')); + return Model; }); \ No newline at end of file diff --git a/src/model/mixin/areaStyle.js b/src/model/mixin/areaStyle.js new file mode 100644 index 0000000000000000000000000000000000000000..420274089f0cf927046561fe63611df002d03d3e --- /dev/null +++ b/src/model/mixin/areaStyle.js @@ -0,0 +1,11 @@ +define({ + getAreaStyle: function () { + return { + fill: this.get('color'), + shadowBlur: this.get('shadowBlur'), + shadowOffsetX: this.get('shadowOffsetX'), + shadowOffsetY: this.get('shadowOffsetY'), + shadowColor: this.get('shadowColor') + }; + } +}); \ No newline at end of file diff --git a/src/model/mixin/itemStyle.js b/src/model/mixin/itemStyle.js new file mode 100644 index 0000000000000000000000000000000000000000..4b5fe6226ef42e29562a45e380787872bb485e78 --- /dev/null +++ b/src/model/mixin/itemStyle.js @@ -0,0 +1,14 @@ +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') + }; + } +}); \ No newline at end of file diff --git a/src/model/mixin/lineStyle.js b/src/model/mixin/lineStyle.js new file mode 100644 index 0000000000000000000000000000000000000000..f28431551f4014c1ac32fd4f6ef63a3cb863692b --- /dev/null +++ b/src/model/mixin/lineStyle.js @@ -0,0 +1,19 @@ +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') + }; + }, + + getLineDash: function () { + var type = this.get('type'); + return type === 'solid' ? null + : (type === 'dashed' ? [5, 5] : [1, 1]); + } +}); \ No newline at end of file diff --git a/src/model/mixin/textStyle.js b/src/model/mixin/textStyle.js new file mode 100644 index 0000000000000000000000000000000000000000..3b966a1a4b20ae99ac3fd16d7e26734155603a19 --- /dev/null +++ b/src/model/mixin/textStyle.js @@ -0,0 +1,10 @@ +define({ + getFont: function () { + return [ + this.get('fontStyle'), + this.get('fontWeight'), + this.get('fontSize') + 'px', + this.get('fontFamily') + ].join(' '); + } +}); \ No newline at end of file diff --git a/src/scale/Interval.js b/src/scale/Interval.js index d3341644bcb79895ab43d7f605bfecbf3f0fe492..88660d84e72fabbfdb2db5cee1f9a62b26ec5b84 100644 --- a/src/scale/Interval.js +++ b/src/scale/Interval.js @@ -21,7 +21,7 @@ define(function (require) { * @type {Array.} * @private */ - this._extent = [-Infinity, Infinity]; + this._extent = [Infinity, -Infinity]; if (data) { this.setExtentFromData(data); @@ -63,10 +63,13 @@ define(function (require) { /** * Set extent from data + * @param {Array.} data + * @param {boolean} union If union with current extent */ - setExtentFromData: function (data) { - var max = -Infinity; - var min = Infinity; + setExtentFromData: function (data, union) { + var extent = this._extent; + var max = union ? extent[1] : -Infinity; + var min = union ? extent[0] : Infinity; for (var i = 0; i < data.length; i++) { if (data[i] == null || data[i] === '-') { continue; @@ -149,7 +152,7 @@ define(function (require) { approxTickNum = approxTickNum || 10; var extent = this._extent; var span = extent[1] - extent[0]; - if (span === Infinity) { + if (span === Infinity || span <= 0) { return; } diff --git a/src/scale/Ordinal.js b/src/scale/Ordinal.js index 08972bf6819b1b6ac3540989adb3d54f1e5c38ed..67284f4459505dc279a12f15100d9b3d321b60a4 100644 --- a/src/scale/Ordinal.js +++ b/src/scale/Ordinal.js @@ -18,7 +18,7 @@ define(function (require) { * Default is 0...len(list)-1 * @type {Array.} */ - this._extent = [0, Infinity]; + this._extent = [0, 0]; if (list) { this.setExtentFromData(list); diff --git a/src/util/graphic.js b/src/util/graphic.js index 6b3a698d91a2e2be1f20704c570c46af42aebc30..cc118aa44f958261c8231990ed390b08f1127cb5 100644 --- a/src/util/graphic.js +++ b/src/util/graphic.js @@ -27,6 +27,8 @@ define(function(require) { Line: require('zrender/graphic/shape/Line'), + Arc: require('zrender/graphic/shape/Arc'), + /** * Extend shape with parameters */ diff --git a/src/view/Chart.js b/src/view/Chart.js index b6b46498cb720730eca307955abd1bae3dc6f550..43aaf9c856f39918614f5c98e937039f07a5d2ad 100644 --- a/src/view/Chart.js +++ b/src/view/Chart.js @@ -27,7 +27,9 @@ define(function (require) { render: function () {}, - remove: function () {}, + remove: function () { + this.group.clear(); + }, dispose: function () {} }; diff --git a/test/bar.html b/test/bar.html index bef2a75f60f3cfd205c272b0bbdf8dab50cd429d..5c62e1b3b43ad6ecc18099b230175c2175aeb480 100644 --- a/test/bar.html +++ b/test/bar.html @@ -18,8 +18,7 @@ 'echarts', 'echarts/chart/bar', 'echarts/component/legend', - 'echarts/component/grid', - 'echarts/component/axis' + 'echarts/component/grid' ], function (echarts) { var chart = echarts.init(document.getElementById('main'), null, { @@ -54,9 +53,15 @@ } }, xAxis: { - data: xAxisData + data: xAxisData, + splitArea: { + show: true + } }, yAxis: { + splitArea: { + show: false + } }, series: [{ name: 'bar', diff --git a/test/line.html b/test/line.html index 7b946de12a0ca86fd0a4dac5004b91f533450ea3..a9c54e4553ae3d405f683e2b20f6da6562e98f1e 100644 --- a/test/line.html +++ b/test/line.html @@ -18,8 +18,7 @@ 'echarts', 'echarts/chart/line', 'echarts/component/legend', - 'echarts/component/grid', - 'echarts/component/axis' + 'echarts/component/grid' ], function (echarts) { var chart = echarts.init(document.getElementById('main'), null, { @@ -47,6 +46,9 @@ data: xAxisData }, yAxis: { + splitLine: { + show: false + } }, series: [{ name: 'line', diff --git a/test/polar.html b/test/polar.html new file mode 100644 index 0000000000000000000000000000000000000000..fdb9d840c3b052bda93d1cf39e3aad837d3efad0 --- /dev/null +++ b/test/polar.html @@ -0,0 +1,75 @@ + + + + + + + + +
+ + + \ No newline at end of file diff --git a/test/scatter.html b/test/scatter.html index 1a6df16d140f382c0e34380dee4be840d4e11c7b..3073bbfaf08df000ee8243712b54699babc3b88c 100644 --- a/test/scatter.html +++ b/test/scatter.html @@ -18,8 +18,7 @@ 'echarts', 'echarts/chart/scatter', 'echarts/component/legend', - 'echarts/component/grid', - 'echarts/component/axis' + 'echarts/component/grid' ], function (echarts) { var chart = echarts.init(document.getElementById('main'), null, { @@ -31,9 +30,9 @@ var data3 = []; for (var i = 0; i < 20; i++) { - data1.push([Math.random() * 2, Math.random() * 1]); + data1.push([Math.random() * 5, Math.random() * 4]); data2.push([Math.random() * 10, Math.random() * 5]); - data3.push([Math.random() * 20, Math.random() * 20]); + data3.push([Math.random() * 15, Math.random() * 10]); } chart.setOption({