diff --git a/src/chart/map.js b/src/chart/map.js index 27912f7c35ee9378f13c4c4ec0389bb6a5de4632..f988216560568949544ce013d6144af2dd30deb9 100644 --- a/src/chart/map.js +++ b/src/chart/map.js @@ -354,8 +354,7 @@ define(function (require) { if (mapType == 'china') { var leftTop = this.geo2pos( mapType, - _geoCoord['南海诸岛'] - || _mapParams['南海诸岛'].textCoord + _geoCoord['南海诸岛'] || _mapParams['南海诸岛'].textCoord ); // scale.x : width = 10.51 : 64 var scale = transform.scale.x / 10.5; @@ -368,10 +367,8 @@ define(function (require) { textPosition[1] += _textFixed['南海诸岛'][1]; } province.push({ - text : this._nameChange(mapType, '南海诸岛'), - path : _mapParams['南海诸岛'].getPath( - leftTop, scale - ), + name : this._nameChange(mapType, '南海诸岛'), + path : _mapParams['南海诸岛'].getPath(leftTop, scale), position : position, textX : textPosition[0], textY : textPosition[1] @@ -618,7 +615,7 @@ define(function (require) { highlightStyle = { name : style.name, path : style.path, - position : style.position + position : zrUtil.clone(style.position) }; name = style.name; data = valueData[name]; // 多系列合并后的数据 @@ -635,8 +632,11 @@ define(function (require) { ) { this.shapeList.push(new CircleShape({ zlevel : this._zlevelBase + 1, - position : style.position, + position : zrUtil.clone(style.position), _mapType : mapType, + _geo : this.pos2geo( + mapType, [style.textX + 3 + j * 7, style.textY - 10] + ), style : { x : style.textX + 3 + j * 7, y : style.textY - 10, @@ -706,11 +706,13 @@ define(function (require) { font = this.deepQuery(queryTarget, 'itemStyle.normal.label.textStyle'); // 文字标签避免覆盖单独一个shape textShape = { - shape : 'text', zlevel : this._zlevelBase + 1, hoverable: this._hoverable[mapType], - position : style.position, + position : zrUtil.clone(style.position), _mapType : mapType, + _geo : this.pos2geo( + mapType, [style.textX, style.textY] + ), style : { brushType : 'fill', x : style.textX, @@ -749,10 +751,9 @@ define(function (require) { } shape = { - shape : 'path', zlevel : this._zlevelBase, hoverable: this._hoverable[mapType], - position : style.position, + position : zrUtil.clone(style.position), style : style, highlightStyle : highlightStyle, _style: zrUtil.clone(style), @@ -761,6 +762,7 @@ define(function (require) { textShape = new TextShape(textShape); shape = new PathShape(shape); + shape.pathArray = shape._parsePathData(shape.style.path); if (this._selectedMode[mapType] && this._selected[name] @@ -853,7 +855,10 @@ define(function (require) { ) : [0, 0]; }, - + getMarkGeo : function(name) { + return _geoCoord[name]; + }, + _nameChange : function (mapType, name) { return this._nameMap[mapType][name] || name; }, @@ -932,21 +937,16 @@ define(function (require) { // 位置转经纬度 geoAndPos = this.pos2geo(mapType, [mx - left, my - top]); if (delta > 0) { - delta = 1.2; - // 放大 - transform.scale.x *= delta; - transform.scale.y *= delta; - transform.width = width * delta; - transform.height = height * delta; + delta = 1.2; // 放大 } else { - // 缩小 - delta = 1.2; - transform.scale.x /= delta; - transform.scale.y /= delta; - transform.width = width / delta; - transform.height = height / delta; + delta = 1 / 1.2; // 缩小 } + transform.scale.x *= delta; + transform.scale.y *= delta; + transform.width = width * delta; + transform.height = height * delta; + this._mapDataMap[mapType].hasRoam = true; this._mapDataMap[mapType].transform = transform; // 经纬度转位置 @@ -955,12 +955,61 @@ define(function (require) { transform.left -= geoAndPos[0] - (mx - left); transform.top -= geoAndPos[1] - (my - top); this._mapDataMap[mapType].transform = transform; - // 让refresh飞一会 - clearTimeout(this._refreshDelayTicket); + + this.clearAnimationShape(); + for (var i = 0, l = this.shapeList.length; i < l; i++) { + if(this.shapeList[i]._mapType == mapType) { + this.shapeList[i].position[0] = transform.left; + this.shapeList[i].position[1] = transform.top; + if (this.shapeList[i].type == 'path') { + this.shapeList[i].scale[0] *= delta; + this.shapeList[i].scale[1] *= delta; + } + else if (this.shapeList[i].type == 'mark-line') { + this.shapeList[i].style.pointListLength = undefined; + this.shapeList[i].style.pointList = false; + geoAndPos = this.geo2pos(mapType, this.shapeList[i]._geo[0]); + this.shapeList[i].style.xStart = geoAndPos[0]; + this.shapeList[i].style.yStart = geoAndPos[1]; + geoAndPos = this.geo2pos(mapType, this.shapeList[i]._geo[1]); + this.shapeList[i].style.xEnd = geoAndPos[0]; + this.shapeList[i].style.yEnd = geoAndPos[1]; + } + else if (this.shapeList[i].type == 'icon') { + geoAndPos = this.geo2pos(mapType, this.shapeList[i]._geo); + this.shapeList[i].style.x = + geoAndPos[0] - this.shapeList[i].style.width / 2; + this.shapeList[i].style.y = + geoAndPos[1] - this.shapeList[i].style.height / 2; + } + else { + geoAndPos = this.geo2pos(mapType, this.shapeList[i]._geo); + this.shapeList[i].style.x = geoAndPos[0]; + this.shapeList[i].style.y = geoAndPos[1]; + if (this.shapeList[i].type == 'text') { + this.shapeList[i]._style.x = this.shapeList[i].highlightStyle.x + = geoAndPos[0]; + this.shapeList[i]._style.y = this.shapeList[i].highlightStyle.y + = geoAndPos[1]; + } + } + + this.zr.modShape(this.shapeList[i].id); + } + } + + this.clearAnimationShape(); + this.zr.refresh(); + var self = this; - this._refreshDelayTicket = setTimeout(function(){ - self.refresh(); - }, 100); + clearTimeout(this._refreshDelayTicket); + this._refreshDelayTicket = setTimeout( + function(){ + self.animationEffect(); + }, + 100 + ); + this.messageCenter.dispatch( ecConfig.EVENT.MAP_ROAM, param.event, @@ -1009,11 +1058,10 @@ define(function (require) { this._my = my; this._mapDataMap[this._curMapType].transform = transform; - var position = [transform.left, transform.top]; - var mod = {position : [transform.left, transform.top]}; for (var i = 0, l = this.shapeList.length; i < l; i++) { if(this.shapeList[i]._mapType == this._curMapType) { - this.shapeList[i].position = position; + this.shapeList[i].position[0] = transform.left; + this.shapeList[i].position[1] = transform.top; this.zr.modShape(this.shapeList[i].id); } } @@ -1257,7 +1305,6 @@ define(function (require) { * 释放后实例不可用 */ dispose : function () { - this.clear(); this.shapeList = null; this._isAlive = false; if (this._needRoam) { diff --git a/src/component/base.js b/src/component/base.js index 939e2f10157bcfd541636381d814e89d567506e7..9103a44eafaff9bec524e8185291852ec677cf7d 100644 --- a/src/component/base.js +++ b/src/component/base.js @@ -315,7 +315,7 @@ define(function (require) { + shapeList[i].style.height / 2; */ for (var key in attachStyle) { - shapeList[i][key] = attachStyle[key]; + shapeList[i][key] = zrUtil.clone(attachStyle[key]); } this.shapeList.push(shapeList[i]); } @@ -377,7 +377,7 @@ define(function (require) { for (var i = 0, l = shapeList.length; i < l; i++) { shapeList[i].zlevel = _zlevelBase + 1; for (var key in attachStyle) { - shapeList[i][key] = attachStyle[key]; + shapeList[i][key] = zrUtil.clone(attachStyle[key]); } this.shapeList.push(shapeList[i]); } @@ -466,6 +466,10 @@ define(function (require) { itemShape.effect = effect; } + if (serie.type == ecConfig.CHART_TYPE_MAP) { + itemShape._geo = this.getMarkGeo(data[i].name); + } + // 重新pack一下数据 ecData.pack( itemShape, @@ -577,6 +581,13 @@ define(function (require) { itemShape.effect = effect; } + if (serie.type == ecConfig.CHART_TYPE_MAP) { + itemShape._geo = [ + this.getMarkGeo(data[i][0].name), + this.getMarkGeo(data[i][1].name) + ]; + } + // 重新pack一下数据 ecData.pack( itemShape, @@ -1106,10 +1117,11 @@ define(function (require) { else if (shape._mark === 'line') { effectShape.style.x = shape.style.xStart - Offset; effectShape.style.y = shape.style.yStart - Offset; - var distance = - (shape.style.xStart - shape._x) * (shape.style.xStart - shape._x) - + - (shape.style.yStart - shape._y) * (shape.style.yStart - shape._y); + var distance = (shape.style.xStart - shape.style.xEnd) + * (shape.style.xStart - shape.style.xEnd) + + + (shape.style.yStart - shape.style.yEnd) + * (shape.style.yStart - shape.style.yEnd); duration = Math.round(Math.sqrt(Math.round( distance * effect.period * effect.period ))); @@ -1162,7 +1174,8 @@ define(function (require) { var len = pointList.length; duration = Math.round(duration / len); var deferred = this.zr.animate(effectShape.id, 'style', true); - for (var j = 0; j < len; j++) { + var step = Math.ceil(len / 8); + for (var j = 0; j < len - step; j+= step) { deferred.when( duration * (j + 1), { @@ -1171,7 +1184,14 @@ define(function (require) { } ); } - deferred.start(); + deferred.when( + duration * len, + { + x : pointList[len - 1][0] - Offset, + y : pointList[len - 1][1] - Offset + } + ); + deferred.start('spline'); } } } diff --git a/src/util/shape/MarkLine.js b/src/util/shape/MarkLine.js index 30619b8e442b852c3c6ca3baa1fb09cd729b3aa6..f471752bd18d2337bed84f127a625d8bb1617438 100644 --- a/src/util/shape/MarkLine.js +++ b/src/util/shape/MarkLine.js @@ -79,7 +79,7 @@ define(function (require) { if (typeof style.pointListLength == 'undefined') { style.pointListLength = pointList.length; } - var len = Math.round(style.pointListLength); + var len = Math.min(pointList.length, Math.round(style.pointListLength)); if (!style.lineType || style.lineType == 'solid') { //默认为实线 ctx.moveTo(pointList[0][0],pointList[0][1]); @@ -106,9 +106,9 @@ define(function (require) { } else { // 曲线 - for (var i = 0; i < len - 1; i += 2) { - ctx.moveTo(pointList[i][0],pointList[i][1]); - ctx.lineTo(pointList[i + 1][0],pointList[i + 1][1]); + for (var i = 1; i < len; i += 2) { + ctx.moveTo(pointList[i - 1][0],pointList[i - 1][1]); + ctx.lineTo(pointList[i][0],pointList[i][1]); } } } @@ -134,7 +134,10 @@ define(function (require) { } // symbolRotate - var len = Math.round(style.pointListLength || style.pointList.length); + var len = Math.min( + style.pointList.length, + Math.round(style.pointListLength || style.pointList.length) + ); var x = idx === 0 ? style.pointList[0][0] : style.pointList[len - 1][0]; var y = idx === 0 ? style.pointList[0][1] : style.pointList[len - 1][1]; var rotate = typeof style.symbolRotate[idx] != 'undefined' @@ -177,7 +180,10 @@ define(function (require) { }, buildArrawPath : function (ctx, style, idx) { - var len = Math.round(style.pointListLength || style.pointList.length); + var len = Math.min( + style.pointList.length, + Math.round(style.pointListLength || style.pointList.length) + ); var symbolSize = style.symbolSize[idx] * 2; var xStart = style.pointList[0][0]; var xEnd = style.pointList[len - 1][0]; @@ -337,9 +343,40 @@ define(function (require) { }, isCover : function (x, y) { - return this.style.smooth !== 'spline' - ? area.isInside(lineInstance, this.style, x, y) - : area.isInside(brokenLineInstance, this.style, x, y); + //对鼠标的坐标也做相同的变换 + if(this.needTransform && this._transform){ + var inverseMatrix = []; + matrix.invert(inverseMatrix, this._transform); + + var originPos = [x, y]; + matrix.mulVector(originPos, inverseMatrix, [x, y, 1]); + + if (x == originPos[0] && y == originPos[1]) { + // 避免外部修改导致的__needTransform不准确 + this.updateNeedTransform(); + } + + x = originPos[0]; + y = originPos[1]; + } + + // 快速预判并保留判断矩形 + var rect = this.style.__rect; + if (!rect) { + rect = this.style.__rect = this.getRect(this.style); + } + if (x >= rect.x + && x <= (rect.x + rect.width) + && y >= rect.y + && y <= (rect.y + rect.height) + ) { + // 矩形内 + return this.style.smooth !== 'spline' + ? area.isInside(lineInstance, this.style, x, y) + : area.isInside(brokenLineInstance, this.style, x, y); + } + + return false; } };