/** * 折线型动画 * * @param {ZRender} zr * @param {shape} oldShape * @param {shape} newShape * @param {number} duration * @param {tring} easing */ function pointList(zr, oldShape, newShape, duration, easing) { var newPointList = newShape.style.pointList; var newPointListLen = newPointList.length; var oldPointList; if (!oldShape) { // add oldPointList = []; if (newShape._orient != 'vertical') { var y = newPointList[0][1]; for (var i = 0; i < newPointListLen; i++) { oldPointList[i] = [newPointList[i][0], y]; } } else { var x = newPointList[0][0]; for (var i = 0; i < newPointListLen; i++) { oldPointList[i] = [x, newPointList[i][1]]; } } if (newShape.type == 'half-smooth-polygon') { oldPointList[newPointListLen - 1] = zrUtil.clone(newPointList[newPointListLen - 1]); oldPointList[newPointListLen - 2] = zrUtil.clone(newPointList[newPointListLen - 2]); } oldShape = {style : {pointList : oldPointList}}; } oldPointList = oldShape.style.pointList; var oldPointListLen = oldPointList.length; if (oldPointListLen == newPointListLen) { newShape.style.pointList = oldPointList; } else if (oldPointListLen < newPointListLen) { // 原来短,新的长,补全 newShape.style.pointList = oldPointList.concat(newPointList.slice(oldPointListLen)); } else { // 原来长,新的短,截断 newShape.style.pointList = oldPointList.slice(0, newPointListLen); } zr.addShape(newShape); newShape.__animating = true; zr.animate(newShape.id, 'style') .when( duration, { pointList: newPointList } ) .during(function () { // Updating bezier points if (newShape.updateControlPoints) { newShape.updateControlPoints(newShape.style); } }) .done(function() { newShape.__animating = false; }) .start(easing); }
reformOption: function (opt) { // 默认配置项动态多级合并,依赖加载的组件选项未被merge到ecTheme里,需要从config里取 opt = zrUtil.merge( zrUtil.merge( opt || {}, zrUtil.clone(this.ecTheme[this.type] || {}) ), zrUtil.clone(ecConfig[this.type] || {}) ); this.z = opt.z; this.zlevel = opt.zlevel; return opt; },
getFont: function (textStyle) { var finalTextStyle = this.getTextStyle( zrUtil.clone(textStyle) ); return finalTextStyle.fontStyle + ' ' + finalTextStyle.fontWeight + ' ' + finalTextStyle.fontSize + 'px ' + finalTextStyle.fontFamily; },
reformOption: function (opt) { // 常用方法快捷方式 var _merge = zrUtil.merge; opt = _merge( _merge( opt || {}, zrUtil.clone(this.ecTheme.pie || {}) ), zrUtil.clone(ecConfig.pie) ); // 通用字体设置 opt.itemStyle.normal.label.textStyle = this.getTextStyle( opt.itemStyle.normal.label.textStyle ); opt.itemStyle.emphasis.label.textStyle = this.getTextStyle( opt.itemStyle.emphasis.label.textStyle ); this.z = opt.z; this.zlevel = opt.zlevel; return opt; },
buildPath : function (ctx, style) { var yList = zrUtil.clone(style.y).sort(this._numberOrder); ctx.moveTo(style.x, yList[3]); ctx.lineTo(style.x, yList[2]); ctx.moveTo(style.x - style.width / 2, yList[2]); ctx.rect( style.x - style.width / 2, yList[2], style.width, yList[1] - yList[2] ); ctx.moveTo(style.x, yList[1]); ctx.lineTo(style.x, yList[0]); },
getRect : function (style) { if (!style.__rect) { var lineWidth = 0; if (style.brushType == 'stroke' || style.brushType == 'fill') { lineWidth = style.lineWidth || 1; } var yList = zrUtil.clone(style.y).sort(this._numberOrder); style.__rect = { x : Math.round(style.x - style.width / 2 - lineWidth / 2), y : Math.round(yList[3] - lineWidth / 2), width : style.width + lineWidth, height : yList[0] - yList[3] + lineWidth }; } return style.__rect; },
_mapData: function(seriesIndex) { var serie = this.series[seriesIndex]; var funnelData = zrUtil.clone(serie.data); for (var i = 0, l = funnelData.length; i < l; i++) { funnelData[i]._index = i; } function numDescending (a, b) { if (a.value === '-') { return 1; } else if (b.value === '-') { return -1; } return b.value - a.value; } function numAscending (a, b) { return -numDescending(a, b); } if (serie.sort != 'none') { funnelData.sort(serie.sort === 'descending' ? numDescending : numAscending); } return funnelData; },
getLabelLine: function ( seriesIndex, dataIndex, center, r0, r1, midAngle, defaultColor, isEmphasis ) { var series = this.series; var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (this._needLabelLine(serie, data, isEmphasis)) { var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle ); // labelLine配置 var labelLineControl = itemStyle[status].labelLine; var lineStyle = labelLineControl.lineStyle || {}; var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 // 视觉引导线起点半径 var minRadius = r1; // 视觉引导线终点半径 var maxRadius = this.parseRadius(this.zr, serie.radius)[1] - (-labelLineControl.length); var cosValue = zrMath.cos(midAngle, true); var sinValue = zrMath.sin(midAngle, true); return new PolylineShape({ zlevel: serie.zlevel, z: serie.z + 1, hoverable: false, style: { pointList: [ [ centerX + minRadius * cosValue, centerY - minRadius * sinValue ], [ centerX + maxRadius * cosValue, centerY - maxRadius * sinValue ], [ data.__labelX, data.__labelY ] ], //xStart: centerX + minRadius * cosValue, //yStart: centerY - minRadius * sinValue, //xEnd: centerX + maxRadius * cosValue, //yEnd: centerY - maxRadius * sinValue, strokeColor: lineStyle.color || defaultColor, lineType: lineStyle.type, lineWidth: lineStyle.width }, _seriesIndex: seriesIndex, _dataIndex: dataIndex }); } else { return; } },
getLabel: function ( seriesIndex, dataIndex, percent, center, midAngle, defaultColor, isEmphasis ) { var series = this.series; var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (!this._needLabel(serie, data, isEmphasis)) { return; } var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle ); // label配置 var labelControl = itemStyle[status].label; var textStyle = labelControl.textStyle || {}; var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 var x; var y; var radius = this.parseRadius(this.zr, serie.radius); // 标签位置半径 var textAlign; var textBaseline = 'middle'; labelControl.position = labelControl.position || itemStyle.normal.label.position; if (labelControl.position === 'center') { // center显示 x = centerX; y = centerY; textAlign = 'center'; } else if (labelControl.position === 'inner' || labelControl.position === 'inside') { // 内部标签显示, 按外半径比例计算标签位置 radius = (radius[0] + radius[1]) * (labelControl.distance || 0.5); x = Math.round(centerX + radius * zrMath.cos(midAngle, true)); y = Math.round(centerY - radius * zrMath.sin(midAngle, true)); defaultColor = '#fff'; textAlign = 'center'; } else { // 外部显示,默认 labelControl.position === 'outer') radius = radius[1] - (-itemStyle[status].labelLine.length); x = Math.round(centerX + radius * zrMath.cos(midAngle, true)); y = Math.round(centerY - radius * zrMath.sin(midAngle, true)); textAlign = (midAngle >= 90 && midAngle <= 270) ? 'right' : 'left'; } if (labelControl.position != 'center' && labelControl.position != 'inner' && labelControl.position != 'inside' ) { x += textAlign === 'left' ? 20 : -20; } data.__labelX = x - (textAlign === 'left' ? 5 : -5); data.__labelY = y; var ts = new TextShape({ zlevel: serie.zlevel, z: serie.z + 1, hoverable: false, style: { x: x, y: y, color: textStyle.color || defaultColor, text: this.getLabelText(seriesIndex, dataIndex, percent, status), textAlign: textStyle.align || textAlign, textBaseline: textStyle.baseline || textBaseline, textFont: this.getFont(textStyle) }, highlightStyle: { brushType: 'fill' } }); ts._radius = radius; ts._labelPosition = labelControl.position || 'outer'; ts._rect = ts.getRect(ts.style); ts._seriesIndex = seriesIndex; ts._dataIndex = dataIndex; return ts; },
getLabelLine: function ( seriesIndex, dataIndex, defaultColor, x, y, topWidth, bottomWidth, height, align ) { var serie = this.series[seriesIndex]; var data = serie.data[dataIndex]; var location = this._paramsMap[seriesIndex].location; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle ); var status = 'normal'; // labelLine配置 var labelLineControl = itemStyle[status].labelLine; var lineLength = itemStyle[status].labelLine.length; var lineStyle = labelLineControl.lineStyle || {}; var labelControl = itemStyle[status].label; labelControl.position = labelControl.position || itemStyle.normal.label.position; var lineShape = { zlevel: serie.zlevel, z: serie.z + 1, hoverable: false, style: { xStart: this._getLabelLineStartPoint(x, location, topWidth, bottomWidth, align), yStart: y + height / 2, xEnd: this._getLabelPoint( labelControl.position, x, location, topWidth, bottomWidth,lineLength, align ), yEnd: y + height / 2, strokeColor: lineStyle.color || defaultColor, lineType: lineStyle.type, lineWidth: lineStyle.width } }; status = 'emphasis'; // labelLine配置 labelLineControl = itemStyle[status].labelLine || labelLineControl; lineLength = itemStyle[status].labelLine.length || lineLength; lineStyle = labelLineControl.lineStyle || lineStyle; labelControl = itemStyle[status].label || labelControl; labelControl.position = labelControl.position; lineShape.highlightStyle = { xEnd: this._getLabelPoint( labelControl.position, x, location, topWidth, bottomWidth,lineLength, align ), strokeColor: lineStyle.color || defaultColor, lineType: lineStyle.type, lineWidth: lineStyle.width }; return new LineShape(lineShape); },
getLabel: function ( seriesIndex, dataIndex, defaultColor, x, y, topWidth, bottomWidth, height, align ) { var serie = this.series[seriesIndex]; var data = serie.data[dataIndex]; var location = this._paramsMap[seriesIndex].location; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle ); var status = 'normal'; // label配置 var labelControl = itemStyle[status].label; var textStyle = labelControl.textStyle || {}; var lineLength = itemStyle[status].labelLine.length; var text = this.getLabelText(seriesIndex, dataIndex, status); var textFont = this.getFont(textStyle); var textAlign; var textColor = defaultColor; labelControl.position = labelControl.position || itemStyle.normal.label.position; if (labelControl.position === 'inner' || labelControl.position === 'inside' || labelControl.position === 'center' ) { // 内部 textAlign = align; textColor = Math.max(topWidth, bottomWidth) / 2 > zrArea.getTextWidth(text, textFont) ? '#fff' : zrColor.reverse(defaultColor); } else if (labelControl.position === 'left'){ // 左侧显示 textAlign = 'right'; } else { // 右侧显示,默认 labelControl.position === 'outer' || 'right) textAlign = 'left'; } var textShape = { zlevel: serie.zlevel, z: serie.z + 1, style: { x: this._getLabelPoint( labelControl.position, x, location, topWidth, bottomWidth,lineLength, align ), y: y + height / 2, color: textStyle.color || textColor, text: text, textAlign: textStyle.align || textAlign, textBaseline: textStyle.baseline || 'middle', textFont: textFont } }; //----------高亮 status = 'emphasis'; // label配置 labelControl = itemStyle[status].label || labelControl; textStyle = labelControl.textStyle || textStyle; lineLength = itemStyle[status].labelLine.length || lineLength; labelControl.position = labelControl.position || itemStyle.normal.label.position; text = this.getLabelText(seriesIndex, dataIndex, status); textFont = this.getFont(textStyle); textColor = defaultColor; if (labelControl.position === 'inner' || labelControl.position === 'inside' || labelControl.position === 'center' ) { // 内部 textAlign = align; textColor = Math.max(topWidth, bottomWidth) / 2 > zrArea.getTextWidth(text, textFont) ? '#fff' : zrColor.reverse(defaultColor); } else if (labelControl.position === 'left'){ // 左侧显示 textAlign = 'right'; } else { // 右侧显示,默认 labelControl.position === 'outer' || 'right) textAlign = 'left'; } textShape.highlightStyle = { x: this._getLabelPoint( labelControl.position, x, location, topWidth, bottomWidth,lineLength, align ), color: textStyle.color || textColor, text: text, textAlign: textStyle.align || textAlign, textFont: textFont, brushType: 'fill' }; return new TextShape(textShape); },
_buildBorkenLine: function (seriesArray, pointList, categoryAxis, curOrient) { var orient = curOrient == 'other' ? 'horizontal' : curOrient; var series = this.series; var data; // 堆积层叠需求,反顺序构建 for (var sIdx = seriesArray.length - 1; sIdx >= 0; sIdx--) { var seriesIndex = seriesArray[sIdx]; var serie = series[seriesIndex]; var seriesPL = pointList[seriesIndex]; if (serie.type === this.type && seriesPL != null) { var bbox = this._getBbox(seriesIndex, orient); var defaultColor = this._sIndex2ColorMap[seriesIndex]; // 折线相关,多级控制 var lineWidth = this.query( serie, 'itemStyle.normal.lineStyle.width' ); var lineType = this.query( serie, 'itemStyle.normal.lineStyle.type' ); var lineColor = this.query( serie, 'itemStyle.normal.lineStyle.color' ); var normalColor = this.getItemStyleColor( this.query(serie, 'itemStyle.normal.color'), seriesIndex, -1 ); // 填充相关 var isFill = this.query(serie, 'itemStyle.normal.areaStyle') != null; var fillNormalColor = this.query( serie, 'itemStyle.normal.areaStyle.color' ); for (var i = 0, l = seriesPL.length; i < l; i++) { var singlePL = seriesPL[i]; var isLarge = curOrient != 'other' && this._isLarge(orient, singlePL); if (!isLarge) { // 非大数据模式才显示拐点symbol for (var j = 0, k = singlePL.length; j < k; j++) { data = serie.data[singlePL[j][2]]; if (this.deepQuery([data, serie, this.option], 'calculable') // 可计算 || this.deepQuery([data, serie], 'showAllSymbol') // 全显示 || (categoryAxis.type === 'categoryAxis' // 主轴非空 && categoryAxis.isMainAxis(singlePL[j][2]) && this.deepQuery([data, serie], 'symbol') != 'none' ) ) { this.shapeList.push(this._getSymbol( seriesIndex, singlePL[j][2], // dataIndex singlePL[j][3], // name singlePL[j][0], // x singlePL[j][1], // y orient )); } } } else { // 大数据模式截取pointList singlePL = this._getLargePointList( orient, singlePL, serie.dataFilter ); } // 折线图 var polylineShape = new PolylineShape({ zlevel: serie.zlevel, z: serie.z, style: { miterLimit: lineWidth, pointList: singlePL, strokeColor: lineColor || normalColor || defaultColor, lineWidth: lineWidth, lineType: lineType, smooth: this._getSmooth(serie.smooth), smoothConstraint: bbox, shadowColor: this.query( serie, 'itemStyle.normal.lineStyle.shadowColor' ), shadowBlur: this.query( serie, 'itemStyle.normal.lineStyle.shadowBlur' ), shadowOffsetX: this.query( serie, 'itemStyle.normal.lineStyle.shadowOffsetX' ), shadowOffsetY: this.query( serie, 'itemStyle.normal.lineStyle.shadowOffsetY' ) }, hoverable: false, _main: true, _seriesIndex: seriesIndex, _orient: orient }); ecData.pack( polylineShape, series[seriesIndex], seriesIndex, 0, i, series[seriesIndex].name ); this.shapeList.push(polylineShape); if (isFill) { var halfSmoothPolygonShape = new HalfSmoothPolygonShape({ zlevel: serie.zlevel, z: serie.z, style: { miterLimit: lineWidth, pointList: zrUtil.clone(singlePL).concat([ [ singlePL[singlePL.length - 1][4], singlePL[singlePL.length - 1][5] ], [ singlePL[0][4], singlePL[0][5] ] ]), brushType: 'fill', smooth: this._getSmooth(serie.smooth), smoothConstraint: bbox, color: fillNormalColor ? fillNormalColor : zrColor.alpha(defaultColor,0.5) }, highlightStyle: { brushType: 'fill' }, hoverable: false, _main: true, _seriesIndex: seriesIndex, _orient: orient }); ecData.pack( halfSmoothPolygonShape, series[seriesIndex], seriesIndex, 0, i, series[seriesIndex].name ); this.shapeList.push(halfSmoothPolygonShape); } } } } },