diff --git a/src/chart/base.js b/src/chart/base.js index cdcef0f1c8e801c2ec6d95bdb63d86e15b6c8177..80edc6e73388b1a15befcf185fb49f71dd59fedf 100644 --- a/src/chart/base.js +++ b/src/chart/base.js @@ -12,6 +12,7 @@ define(function (require) { var MarkLineShape = require('../util/shape/MarkLine'); var SymbolShape = require('../util/shape/Symbol'); var PolylineShape = require('zrender/shape/Polyline'); + var ShapeBundle = require('zrender/shape/ShapeBundle'); var ecConfig = require('../config'); var ecData = require('../util/ecData'); @@ -56,7 +57,7 @@ define(function (require) { highlightStyle.strokeColor = self.ecTheme.calculableColor || ecConfig.calculableColor; highlightStyle.lineWidth = calculableShape.type === 'icon' ? 30 : 10; - + self.zr.addHoverShape(calculableShape); setTimeout(function (){ @@ -709,21 +710,52 @@ define(function (require) { var shapeList = this._markLine(seriesIndex, markLine); - for (var i = 0, l = shapeList.length; i < l; i++) { - var tarShape = shapeList[i]; - tarShape.zlevel = this.getZlevelBase(); - tarShape.z = this.getZBase() + 1; - for (var key in attachStyle) { - tarShape[key] = zrUtil.clone(attachStyle[key]); + var isLarge = markLine.large; + + if (isLarge) { + var shapeBundle = new ShapeBundle({ + style: { + shapeList: shapeList + } + }); + var firstShape = shapeList[0]; + if (firstShape) { + zrUtil.merge(shapeBundle.style, firstShape.style); + zrUtil.merge(shapeBundle.highlightStyle = {}, firstShape.highlightStyle); + shapeBundle.style.brushType = 'stroke'; + shapeBundle.zlevel = this.getZlevelBase(); + shapeBundle.z = this.getZBase() + 1; + shapeBundle.hoverable = false; + for (var key in attachStyle) { + shapeBundle[key] = zrUtil.clone(attachStyle[key]); + } + } + this.shapeList.push(shapeBundle); + this.zr.addShape(shapeBundle); + + shapeBundle._mark = 'largeLine'; + var effect = markLine.effect; + if (effect.show) { + shapeBundle.effect = effect; } - this.shapeList.push(tarShape); } - // 个别特殊图表需要自己addShape - if (this.type === ecConfig.CHART_TYPE_FORCE - || this.type === ecConfig.CHART_TYPE_CHORD - ) { + else { for (var i = 0, l = shapeList.length; i < l; i++) { - this.zr.addShape(shapeList[i]); + var tarShape = shapeList[i]; + tarShape.zlevel = this.getZlevelBase(); + tarShape.z = this.getZBase() + 1; + for (var key in attachStyle) { + tarShape[key] = zrUtil.clone(attachStyle[key]); + } + this.shapeList.push(tarShape); + } + // 个别特殊图表需要自己addShape + if (this.type === ecConfig.CHART_TYPE_FORCE + || this.type === ecConfig.CHART_TYPE_CHORD + ) { + for (var i = 0, l = shapeList.length; i < l; i++) { + this.zr.addShape(shapeList[i]); + } } } }, @@ -758,7 +790,7 @@ define(function (require) { var effect; var zrWidth = this.zr.getWidth(); var zrHeight = this.zr.getHeight(); - + if (!mpOption.large) { for (var i = 0, l = data.length; i < l; i++) { if (data[i].x == null || data[i].y == null) { @@ -955,6 +987,7 @@ define(function (require) { ); if (effect.show) { itemShape.effect = effect; + itemShape.effect.large = mlOption.large; } if (serie.type === ecConfig.CHART_TYPE_MAP) { @@ -976,6 +1009,7 @@ define(function (require) { ); shapeList.push(itemShape); } + return shapeList; }; })(), @@ -1189,7 +1223,6 @@ define(function (require) { var ShapeCtor = bundling ? PolylineShape : MarkLineShape; var itemShape = new ShapeCtor({ style: { - curveness: smoothness, symbol: symbol, symbolSize: symbolSize, symbolRotate: symbolRotate, @@ -1250,8 +1283,8 @@ define(function (require) { shapeStyle.yStart = points[0][1]; shapeStyle.xEnd = points[1][0]; shapeStyle.yEnd = points[1][1]; + shapeStyle.curveness = smoothness; itemShape.updatePoints(itemShape.style); - itemShape.updatePoints(itemShape.highlightStyle); } itemShape = this.addLabel( @@ -1529,26 +1562,26 @@ define(function (require) { * 标注动画 * @param {number} duration 时长 * @param {string=} easing 缓动效果 - * @param {Array=} addShapeList 指定特效对象,不指定默认使用this.shapeList + * @param {Array=} shapeList 指定特效对象,不指定默认使用this.shapeList */ - animationMark: function (duration , easing, addShapeList) { - var shapeList = addShapeList || this.shapeList; + animationMark: function (duration , easing, shapeList) { + var shapeList = shapeList || this.shapeList; for (var i = 0, l = shapeList.length; i < l; i++) { if (!shapeList[i]._mark) { continue; } this._animateMod(false, shapeList[i], duration, easing, 0, true); } - this.animationEffect(addShapeList); + this.animationEffect(shapeList); }, /** * 特效动画 - * @param {Array=} addShapeList 指定特效对象,不知道默认使用this.shapeList + * @param {Array=} shapeList 指定特效对象,不知道默认使用this.shapeList */ - animationEffect: function (addShapeList) { - !addShapeList && this.clearEffectShape(); - var shapeList = addShapeList || this.shapeList; + animationEffect: function (shapeList) { + !shapeList && this.clearEffectShape(); + shapeList = shapeList || this.shapeList; if (shapeList == null) { return; } diff --git a/src/util/ecEffect.js b/src/util/ecEffect.js index b841a55c26bfe33641fda660efa75a33adea6a7e..7471fabffc9190acd1de485aecf37165227b4f74 100644 --- a/src/util/ecEffect.js +++ b/src/util/ecEffect.js @@ -13,6 +13,7 @@ define(function (require) { var curveTool = require('zrender/tool/curve'); var IconShape = require('../util/shape/Icon'); var SymbolShape = require('../util/shape/Symbol'); + var ShapeBundle = require('zrender/shape/ShapeBundle'); var canvasSupported = require('zrender/tool/env').canvasSupported; @@ -203,7 +204,7 @@ define(function (require) { } } - function line(zr, effectList, shape, zlevel) { + function line(zr, effectList, shape, zlevel, isLarge) { var effect = shape.effect; var shapeStyle = shape.style; var color = effect.color || shapeStyle.strokeColor || shapeStyle.color; @@ -211,7 +212,7 @@ define(function (require) { var size = shapeStyle.lineWidth * effect.scaleSize; var shadowBlur = typeof effect.shadowBlur != 'undefined' ? effect.shadowBlur : size; - + var effectShape = new CircleShape({ zlevel : zlevel, style : { @@ -222,36 +223,31 @@ define(function (require) { shadowColor : shadowColor, shadowBlur : shadowBlur }, - draggable : false, hoverable : false }); - - var offset; - if (canvasSupported) { // 提高性能,换成image - effectShape.style.image = zr.shapeToImage( - effectShape, + + var offset = 0; + if (canvasSupported && ! isLarge) { // 提高性能,换成image + var zlevel = effectShape.zlevel; + effectShape = zr.shapeToImage( + effectShape, (size + shadowBlur) * 2, (size + shadowBlur) * 2 - ).style.image; - effectShape = new ImageShape({ - zlevel : effectShape.zlevel, - style : effectShape.style, - draggable : false, - hoverable : false - }); + ); + effectShape.zlevel = zlevel; + effectShape.hoverable = false; + offset = shadowBlur; } - else { - offset = 0; + + if (! isLarge) { + ecData.clone(shape, effectShape); + // 改变坐标, 不能移到前面 + effectShape.position = shape.position; + effectList.push(effectShape); + zr.addShape(effectShape); } - - ecData.clone(shape, effectShape); - - // 改变坐标, 不能移到前面 - effectShape.position = shape.position; - effectList.push(effectShape); - zr.addShape(effectShape); - + var x0 = shapeStyle.xStart - offset; var y0 = shapeStyle.yStart - offset; var x2 = shapeStyle.xEnd - offset; @@ -264,14 +260,16 @@ define(function (require) { distance * effect.period * effect.period ))); var effectDone = function () { - shape.effect.show = false; - zr.delShape(effectShape.id); + if (! isLarge) { + shape.effect.show = false; + zr.delShape(effectShape.id); + } } if (shape.style.curveness > 0) { var x1 = shapeStyle.cpX1 - offset; var y1 = shapeStyle.cpY1 - offset; var obj = { p: 0 }; - zr.animation.animate(effectShape, { loop: effect.loop }) + effectShape.effectAnimator = zr.animation.animate(effectShape, { loop: effect.loop }) .when(duration, { p: 1 }) .during(function (target, t) { effectShape.style.x = curveTool.quadraticAt( @@ -280,25 +278,79 @@ define(function (require) { effectShape.style.y = curveTool.quadraticAt( y0, y1, y2, t ); - zr.modShape(effectShape); + if (! isLarge) { + zr.modShape(effectShape); + } }) .done(effectDone) .start(); } else { - zr.animate(effectShape.id, 'style', effect.loop) + // 不用 zr.animate,因为在用 ShapeBundle 的时候单个 effectShape 不会 + // 被加到 zrender 中 + effectShape.effectAnimator = zr.animation.animate(effectShape.style, { loop: effect.loop }) .when(duration, { x: x2, y: y2 }) + .during(function () { + if (! isLarge) { + zr.modShape(effectShape); + } + }) .done(effectDone) .start(); } + effectShape.effectAnimator.duration = duration; + return effectShape; + } + + function largeLine(zr, effectList, shape, zlevel) { + var effectShape = new ShapeBundle({ + style: { + shapeList: [] + }, + zlevel: zlevel, + hoverable: false + }); + var shapeList = shape.style.shapeList; + var effect = shape.effect; + effectShape.position = shape.position; + + var longestAnimator = null; + var maxDuration = 0; + for (var i = 0; i < shapeList.length; i++) { + shapeList[i].effect = effect; + var singleEffectShape = line(zr, null, shapeList[i], zlevel, true); + var singleEffectAnimator = singleEffectShape.effectAnimator; + effectShape.style.shapeList.push(singleEffectShape); + if (singleEffectAnimator.duration > maxDuration) { + maxDuration = singleEffectAnimator.duration; + longestAnimator = singleEffectAnimator; + } + if (i === 0) { + effectShape.style.color = singleEffectShape.style.color; + effectShape.style.shadowBlur = singleEffectShape.style.shadowBlur; + effectShape.style.shadowColor = singleEffectShape.style.shadowColor; + } + } + effectList.push(effectShape); + zr.addShape(effectShape); + if (longestAnimator) { + longestAnimator.during(function () { + zr.modShape(effectShape); + }) + .done(function () { + shape.effect.show = false; + zr.delShape(effectShape.id); + }); + } } return { point : point, largePoint : largePoint, - line : line + line : line, + largeLine: largeLine }; });