From b3f9d47bd89373cae14556d491f6b19ea429422c Mon Sep 17 00:00:00 2001 From: lang Date: Tue, 20 Oct 2015 16:23:14 +0800 Subject: [PATCH] Component#name, Roam on map --- src/action/geoRoam.js | 56 +++++++++++++++ src/chart/bar/BarSeries.js | 5 +- src/chart/helper/DataSymbol.js | 11 +-- src/chart/map.js | 2 + src/chart/map/MapSeries.js | 2 +- src/chart/map/MapView.js | 27 ++++++- src/component/geo.js | 2 + src/component/geo/GeoView.js | 21 ++++++ src/component/helper/RoamController.js | 83 ++++++++++++++++++++++ src/coord/geo/Geo.js | 97 ++++++++++++++++++++++++-- src/coord/geo/GeoModel.js | 20 ++++++ src/coord/geo/geoCreator.js | 23 ++++-- src/model/Component.js | 15 +++- src/model/Series.js | 11 --- 14 files changed, 340 insertions(+), 35 deletions(-) create mode 100644 src/action/geoRoam.js create mode 100644 src/component/helper/RoamController.js diff --git a/src/action/geoRoam.js b/src/action/geoRoam.js new file mode 100644 index 000000000..03baad9c3 --- /dev/null +++ b/src/action/geoRoam.js @@ -0,0 +1,56 @@ +define(function (require) { + + var echarts = require('../../echarts'); + var actionInfo = { + type: 'geoRoam', + event: 'geoRoam', + update: 'updateView' + }; + + /** + * @payload + * @property {string} [component=series] + * @property {string} name Component name + * @property {number} [dx] + * @property {number} [dy] + * @property {number} [zoom] + * @property {number} [originX] + * @property {number} [originY] + */ + echarts.registerAction(actionInfo, function (payload, ecModel) { + var componentType = payload.component || 'series'; + ecModel.eachComponent(componentType, function (componentModel) { + if (componentModel.name === payload.name) { + var dx = payload.dx; + var dy = payload.dy; + var zoom = payload.zoom; + var geo = componentModel.coordinateSystem; + if (geo.type !== 'geo') { + return; + } + + var roamDetailModel = componentModel.getModel('roamDetail'); + if (dx != null && dy != null) { + var mapScale = geo.mapScale; + + var panX = (roamDetailModel.get('x') || 0) + dx / mapScale[0]; + var panY = (roamDetailModel.get('y') || 0) + dy / mapScale[1]; + + componentModel.setRoamPan + && componentModel.setRoamPan(panX, panY); + + geo && geo.setPan(panX, panY); + + } + if (zoom != null && componentModel.setRoamZoom) { + var previousZoom = roamDetailModel.get('zoom') || 1; + + zoom *= previousZoom; + componentModel.setRoamZoom(zoom); + + geo && geo.setZoom(zoom); + } + } + }); + }); +}); \ No newline at end of file diff --git a/src/chart/bar/BarSeries.js b/src/chart/bar/BarSeries.js index b2d612dd1..cbbd2c1b0 100644 --- a/src/chart/bar/BarSeries.js +++ b/src/chart/bar/BarSeries.js @@ -66,10 +66,7 @@ define(function(require) { // 柱条边线圆角,单位px,默认为0 barBorderRadius: 0, // 柱条边线线宽,单位px,默认为1 - barBorderWidth: 0, - label: { - show: false - } + barBorderWidth: 0 }, emphasis: { // color: '各异', diff --git a/src/chart/helper/DataSymbol.js b/src/chart/helper/DataSymbol.js index 86394d186..23991cf77 100644 --- a/src/chart/helper/DataSymbol.js +++ b/src/chart/helper/DataSymbol.js @@ -151,8 +151,6 @@ define(function (require) { symbolSize[0], symbolSize[1] ) || {}; } - var newColor = data.getItemVisual(newIdx, 'color'); - el.setColor(newColor); // TODO Merge animateTo and attr methods into one newTarget.position = point; @@ -192,13 +190,16 @@ define(function (require) { .execute(); // Update common properties - var itemStyleAccessPath = ['itemStyle', 'normal']; + var normalStyleAccessPath = ['itemStyle', 'normal']; + var emphasisStyleAccessPath = [normalStyleAccessPath[0], 'emphasis']; data.eachItemGraphicEl(function (el, idx) { var itemModel = data.getItemModel(idx); - var normalItemStyleModel = itemModel.getModel(itemStyleAccessPath); + var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath); var labelModel = itemModel.getModel('label.normal'); var color = data.getItemVisual(idx, 'color'); + el.setColor(color); + zrUtil.extend( el.style, normalItemStyleModel.getItemStyle(['color']) @@ -221,7 +222,7 @@ define(function (require) { graphic.setHoverStyle( el, - itemModel.getModel('itemStyle.emphasis').getItemStyle() + itemModel.getModel(emphasisStyleAccessPath).getItemStyle() ); }, this); diff --git a/src/chart/map.js b/src/chart/map.js index f505d4513..f9c45f7d1 100644 --- a/src/chart/map.js +++ b/src/chart/map.js @@ -6,6 +6,8 @@ define(function (require) { require('./map/MapView'); + require('../action/geoRoam'); + echarts.registerLayout(require('./map/mapSymbolLayout')); echarts.registerVisualCoding('chart', require('./map/mapVisual')); diff --git a/src/chart/map/MapSeries.js b/src/chart/map/MapSeries.js index abd13c7fd..1116829f3 100644 --- a/src/chart/map/MapSeries.js +++ b/src/chart/map/MapSeries.js @@ -134,6 +134,6 @@ define(function (require) { roamDetail.x = x; roamDetail.y = y; } - } + } }) }); \ No newline at end of file diff --git a/src/chart/map/MapView.js b/src/chart/map/MapView.js index 2771def83..18c2c61b7 100644 --- a/src/chart/map/MapView.js +++ b/src/chart/map/MapView.js @@ -3,18 +3,41 @@ define(function (require) { var zrUtil = require('zrender/core/util'); var graphic = require('../../util/graphic'); + var RoamController = require('../../component/helper/RoamController'); + require('../../echarts').extendChartView({ type: 'map', + init: function (ecModel, api) { + var controller = new RoamController(api.getZr(), null, null); + this._controller = controller; + }, + render: function (mapModel, ecModel, api) { - this.group.removeAll(); + var group = this.group; + var geo = mapModel.coordinateSystem; + group.removeAll(); mapModel.needsDrawMap && this._renderArea(mapModel, ecModel, api); mapModel.get('showLegendSymbol') && ecModel.getComponent('legend') && this._renderSymbols(mapModel, ecModel, api); + + var controller = this._controller; + controller.off('pan') + .on('pan', function (dx, dy) { + api.dispatch({ + type: 'geoRoam', + // component: 'series', + name: mapModel.name, + dx: dx, + dy: dy + }); + }); + + controller.rect = geo.getViewBox(); }, _renderArea: function (mapModel, ecModel, api) { @@ -47,7 +70,7 @@ define(function (require) { // Competitable with 2.0 var areaStylePath = 'areaStyle.color'; itemStyle.fill = itemStyleModel.get(areaStylePath); - hoverItemStyle.fill = hoverItemStyleModel.get(areaStylePath); + hoverItemStyle.fill = hoverItemStyleModel.get('areaColor'); var styleObj = zrUtil.defaults( { diff --git a/src/component/geo.js b/src/component/geo.js index 18b0589ea..569761ab1 100644 --- a/src/component/geo.js +++ b/src/component/geo.js @@ -3,4 +3,6 @@ define(function (require) { require('../coord/geo/geoCreator'); require('./geo/GeoView'); + + require('../action/geoRoam'); }); \ No newline at end of file diff --git a/src/component/geo/GeoView.js b/src/component/geo/GeoView.js index 45f26c8ca..500db8b1c 100644 --- a/src/component/geo/GeoView.js +++ b/src/component/geo/GeoView.js @@ -5,10 +5,17 @@ define(function (require) { var zrUtil = require('zrender/core/util'); var graphic = require('../../util/graphic'); + var RoamController = require('../helper/RoamController'); + return require('../../echarts').extendComponentView({ type: 'geo', + init: function (ecModel, api) { + var controller = new RoamController(api.getZr(), null, null); + this._controller = controller; + }, + render: function (geoModel, ecModel, api) { this.group.removeAll(); @@ -55,6 +62,20 @@ define(function (require) { mapGroup.add(regionGroup); }); + + var controller = this._controller; + controller.off('pan') + .on('pan', function (dx, dy) { + api.dispatch({ + type: 'geoRoam', + component: 'geo', + name: geoModel.name, + dx: dx, + dy: dy + }); + }); + + controller.rect = geo.getViewBox(); } }); }); \ No newline at end of file diff --git a/src/component/helper/RoamController.js b/src/component/helper/RoamController.js new file mode 100644 index 000000000..f0857592d --- /dev/null +++ b/src/component/helper/RoamController.js @@ -0,0 +1,83 @@ +define(function (require) { + + var Eventful = require('zrender/mixin/Eventful'); + var zrUtil = require('zrender/core/util'); + + function mousedown(e) { + var x = e.offsetX; + var y = e.offsetY; + var rect = this.rect; + if (rect && rect.contain(x, y)) { + this._x = x; + this._y = y; + this._dragging = true; + } + } + + function mousemove(e) { + if (this._dragging) { + var x = e.offsetX; + var y = e.offsetY; + + var dx = x - this._x; + var dy = y - this._y; + + this._x = x; + this._y = y; + + var target = this.target; + + if (target) { + var pos = target.position; + var scale = target.scale; + pos[0] += dx * scale[0]; + pos[1] += dy * scale[1]; + target.dirty(); + } + + this.trigger('pan', dx, dy); + } + } + + function mouseup(e) { + this._dragging =false; + } + + function mousewheel(e) { + var x = e.offsetX; + var y = e.offsetY; + var rect = this.rect; + if (rect && rect.contain(x, y)) { + + } + } + + /** + * @param {module:zrender/zrender~ZRender} zr + * @param {module:zrender/Element} target + * @param {module:zrender/core/BoundingRect} rect + */ + function RoamController(zr, target, rect) { + + /** + * @type {module:zrender/Element} + */ + this.target = target; + + /** + * @type {module:zrender/core/BoundingRect} + */ + this.rect = rect; + + zr.on('mousedown', mousedown, this); + zr.on('mousemove', mousemove, this); + zr.on('mouseup', mouseup, this); + zr.on('mousewheel', mousewheel, this); + + Eventful.call(this); + } + + zrUtil.mixin(RoamController, Eventful); + + return RoamController; +}); \ No newline at end of file diff --git a/src/coord/geo/Geo.js b/src/coord/geo/Geo.js index 8ea73af2d..131938931 100644 --- a/src/coord/geo/Geo.js +++ b/src/coord/geo/Geo.js @@ -8,6 +8,8 @@ define(function (require) { var BoundingRect = require('zrender/core/BoundingRect'); + var v2Copy = vector.copy; + function Geo(name, geoJson) { this.name = name; @@ -22,6 +24,27 @@ define(function (require) { Transformable.call(this); this._nameCoordMap = {}; + + /** + * @param Array. + */ + this.mapPosition = [0, 0]; + + /** + * @param Array. + */ + this.mapScale = [1, 1]; + + /** + * @param Array. + * @private + */ + this._pan = [0, 0]; + /** + * @param number + * @private + */ + this._zoom = 1; }; Geo.prototype = { @@ -80,12 +103,12 @@ define(function (require) { /** * Transformed to particular position and size - * @param {number} cx - * @param {number} cy + * @param {number} x + * @param {number} y * @param {number} width * @param {number} height */ - transformTo: function (cx, cy, width, height) { + transformTo: function (x, y, width, height) { var rect = this.getBoundingRect(); rect = rect.clone(); @@ -93,17 +116,75 @@ define(function (require) { rect.y = -rect.y - rect.height; this.transform = rect.calculateTransform( - new BoundingRect(cx - width / 2, cy - height / 2, width, height) + new BoundingRect(x, y, width, height) ); this.decomposeTransform(); var scale = this.scale; + scale[1] = -scale[1]; + v2Copy(this.mapPosition, this.position); + v2Copy(this.mapScale, scale); + + this._updateTransform(); + }, + + /** + * @param {number} x + * @param {number} y + * @param {number} width + * @param {number} height + */ + setViewBox: function (x, y, width, height) { + this._viewBox = new BoundingRect(x, y, width, height); + }, + + /** + * @param {number} x + * @param {number} y + */ + setPan: function (x, y) { + var pan = this._pan; + pan[0] = x; + pan[1] = y; + + this._updateTransform(); + }, + + /** + * @param {number} zoom + */ + setZoom: function (zoom) { + this._zoom = zoom; + + this._updateTransform(); + }, + + /** + * Update transform from roam and mapLocation + * @private + */ + _updateTransform: function () { + var mapScale = this.mapScale; + + var pan = this._pan; + + // Update transform position + pan = [ + pan[0] * mapScale[0], + pan[1] * mapScale[1] + ]; + vector.add(this.position, this.mapPosition, pan); + vector.scale(this.scale, mapScale, this._zoom); + this.updateTransform(); }, + /** + * @return {module:zrender/core/BoundingRect} + */ getBoundingRect: function () { if (this._rect) { return this._rect; @@ -120,6 +201,13 @@ define(function (require) { return this._rect = rect || new BoundingRect(0, 0, 0, 0); }, + /** + * @return {module:zrender/core/BoundingRect} + */ + getViewBox: function () { + return this._viewBox; + }, + /** * If contain point * @param {Array.} point @@ -134,7 +222,6 @@ define(function (require) { * @return {boolean} */ containData: function (data) { - }, /** diff --git a/src/coord/geo/GeoModel.js b/src/coord/geo/GeoModel.js index e82adf78e..678820fa4 100644 --- a/src/coord/geo/GeoModel.js +++ b/src/coord/geo/GeoModel.js @@ -29,6 +29,13 @@ define(function (require) { // Map type map: '', + // 在 roam 开启的时候使用 + roamDetail: { + x: 0, + y: 0, + zoom: 1 + }, + itemStyle: { normal: { // color: 各异, @@ -52,6 +59,19 @@ define(function (require) { } } } + }, + + setRoamZoom: function (zoom) { + var roamDetail = this.option.roamDetail; + roamDetail && (roamDetail.zoom = zoom); + }, + + setRoamPan: function (x, y) { + var roamDetail = this.option.roamDetail; + if (roamDetail) { + roamDetail.x = x; + roamDetail.y = y; + } } }); }); \ No newline at end of file diff --git a/src/coord/geo/geoCreator.js b/src/coord/geo/geoCreator.js index d5b78f81c..df673e8c1 100644 --- a/src/coord/geo/geoCreator.js +++ b/src/coord/geo/geoCreator.js @@ -10,12 +10,13 @@ define(function (require) { /** * Resize method bound to the geo - * @param {module:echarts/coord/geo/GeoModel|module:echarts/chart/map/MapModel} locModel + * @param {module:echarts/coord/geo/GeoModel|module:echarts/chart/map/MapModel} geoModel * @param {module:echarts/ExtensionAPI} api */ - var resizeGeo = function (locModel, api) { - if (locModel.type === 'series.map') { - locModel = locModel.getModel('mapLocation'); + var resizeGeo = function (geoModel, api) { + var locModel = geoModel; + if (geoModel.type === 'series.map') { + locModel = geoModel.getModel('mapLocation'); } var x = locModel.get('x'); @@ -66,7 +67,19 @@ define(function (require) { break; } - this.transformTo(cx, cy, width, height); + x = cx - width / 2; + y = cy - height / 2; + this.transformTo(x, y, width, height); + this.setViewBox(x, y, width, height); + + var roamDetailModel = geoModel.getModel('roamDetail'); + + var panX = roamDetailModel.get('x') || 0; + var panY = roamDetailModel.get('y') || 0; + var zoom = roamDetailModel.get('zoom') || 1; + + this.setPan(panX, panY); + this.setZoom(zoom); } var geoCreator = { diff --git a/src/model/Component.js b/src/model/Component.js index 8b9c8519d..4830aa38c 100644 --- a/src/model/Component.js +++ b/src/model/Component.js @@ -21,6 +21,11 @@ define(function(require) { type: 'component', + /** + * @readOnly + */ + name: '', + /** * @type {Object} * @protected @@ -47,7 +52,7 @@ define(function(require) { */ uid: null, - init: function () { + init: function (option, parentModel, ecModel, dependentModels, index) { this.mergeDefaultAndTheme(this.option, this.ecModel); }, @@ -80,10 +85,16 @@ define(function(require) { // Reset ComponentModel.extend, add preConstruct. componentUtil.enableClassExtend( ComponentModel, - function (option, parentModel, ecModel, dependentModels) { + function (option, parentModel, ecModel, dependentModels, index) { this.ecModel = ecModel; this.dependentModels = dependentModels; this.uid = componentUtil.getUID('componentModel'); + + var componentName = option.name; + if (componentName == null) { + componentName = this.type + '' + index; + } + this.name = componentName + ''; } ); diff --git a/src/model/Series.js b/src/model/Series.js index 11ef90b25..487e93563 100644 --- a/src/model/Series.js +++ b/src/model/Series.js @@ -18,11 +18,6 @@ define(function(require) { */ seriesIndex: 0, - /** - * @readOnly - */ - name: '', - // coodinateSystem will be injected in the echarts/CoordinateSystem coordinateSystem: null, @@ -47,12 +42,6 @@ define(function(require) { this.mergeDefaultAndTheme(option, ecModel); - var seriesName = this.get('name'); - if (seriesName == null) { - seriesName = this.get('type') + '' + seriesIndex; - } - this.name = seriesName + ''; - /** * @type {module:echarts/data/List|module:echarts/data/Tree|module:echarts/data/Graph} * @private -- GitLab