function onclick(param) { if (!self.isClick || !param.target) { // 没有在当前实例上发生点击直接返回 return; } var deviation = 10; // 偏移 var target = param.target; var style = target.style; if (!style._hasClick) { var midAngle = ((style.startAngle + style.endAngle) / 2) .toFixed(2) - 0; target.style._hasClick = true; target.style._x = target.style.x; target.style._y = target.style.y; target.style.x += zrMath.cos(midAngle, true) * deviation; target.style.y -= zrMath.sin(midAngle, true) * deviation; } else { // 复位 target.style.x = target.style._x; target.style.y = target.style._y; target.style._hasClick = false; } zr.modShape(target.id, target); zr.refresh(); }
/** * 需要显示则会有返回构建好的shape,否则返回undefined */ function _getLabelLine( seriesIndex, dataIndex, r0, r1, startAngle, endAngle, defaultColor, isEmphasis ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (_needLabelLine(serie, data, isEmphasis)) { var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle, { 'overwrite' : false, 'recursive' : true } ); // labelLine配置 var labelLineControl = itemStyle[status].labelLine; var lineStyle = labelLineControl.lineStyle || {}; var center = self.parseCenter(serie.center); var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 // 视觉引导线起点半径 var midRadius = r1; // 视觉引导线终点半径 var maxRadius = self.parseRadius(serie.radius)[1] - (-labelLineControl.length); var midAngle = ((endAngle + startAngle) / 2) % 360; // 角度中值 var cosValue = zrMath.cos(midAngle, true); var sinValue = zrMath.sin(midAngle, true); // 三角函数缓存已在zrender/tool/math中做了 return { shape : 'line', zlevel : _zlevelBase + 1, hoverable : false, style : { xStart : centerX + midRadius * cosValue, yStart : centerY - midRadius * 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; } }
onclick: function (param) { var series = this.series; if (!this.isClick || !param.target) { return; } this.isClick = false; var offset; var target = param.target; var style = target.style; var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); for (var i = 0, len = this.shapeList.length; i < len; i++) { if (this.shapeList[i].id === target.id) { seriesIndex = ecData.get(target, 'seriesIndex'); dataIndex = ecData.get(target, 'dataIndex'); if (!style._hasSelected) { var midAngle = ((style.startAngle + style.endAngle) / 2).toFixed(2) - 0; target.style._hasSelected = true; this._selected[seriesIndex][dataIndex] = true; target.style._x = target.style.x; target.style._y = target.style.y; offset = this.query(series[seriesIndex], 'selectedOffset'); target.style.x += zrMath.cos(midAngle, true) * offset; target.style.y -= zrMath.sin(midAngle, true) * offset; } else { target.style.x = target.style._x; target.style.y = target.style._y; target.style._hasSelected = false; this._selected[seriesIndex][dataIndex] = false; } this.zr.modShape(target.id, target); } else if (this.shapeList[i].style._hasSelected && this._selectedMode === 'single') { seriesIndex = ecData.get(this.shapeList[i], 'seriesIndex'); dataIndex = ecData.get(this.shapeList[i], 'dataIndex'); this.shapeList[i].style.x = this.shapeList[i].style._x; this.shapeList[i].style.y = this.shapeList[i].style._y; this.shapeList[i].style._hasSelected = false; this._selected[seriesIndex][dataIndex] = false; this.zr.modShape(this.shapeList[i].id, this.shapeList[i]); } } this.messageCenter.dispatch(ecConfig.EVENT.PIE_SELECTED, param.event, { selected: this._selected, target: ecData.get(target, 'name') }, this.myChart); this.zr.refreshNextFrame(); }
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'; var itemStyle = zrUtil.merge(zrUtil.clone(data.itemStyle) || {}, serie.itemStyle); 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: this.getZlevelBase(), z: this.getZBase() + 1, hoverable: false, style: { pointList: [ [ centerX + minRadius * cosValue, centerY - minRadius * sinValue ], [ centerX + maxRadius * cosValue, centerY - maxRadius * sinValue ], [ data.__labelX, data.__labelY ] ], strokeColor: lineStyle.color || defaultColor, lineType: lineStyle.type, lineWidth: lineStyle.width }, _seriesIndex: seriesIndex, _dataIndex: dataIndex }); } else { return; } },
getLabelLine : function ( seriesIndex, dataIndex, lastAddRadius, r0, r1, startAngle, endAngle, 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 center = this.parseCenter(this.zr, serie.center); var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 // 视觉引导线起点半径 var midRadius = r1; // 视觉引导线终点半径 var maxRadius = this.parseRadius(this.zr, serie.radius)[1] - (-labelLineControl.length) + lastAddRadius; var midAngle = ((endAngle + startAngle) / 2) % 360; // 角度中值 var cosValue = zrMath.cos(midAngle, true); var sinValue = zrMath.sin(midAngle, true); // 三角函数缓存已在zrender/tool/math中做了 return new BrokenLineShape({ // shape : 'brokenLine', zlevel : this._zlevelBase + 1, hoverable : false, style : { pointList : [ [ centerX + midRadius * cosValue, centerY - midRadius * sinValue ], [ centerX + maxRadius * cosValue, centerY - maxRadius * sinValue ], [ data.__labelX, data.__labelY ] ], //xStart : centerX + midRadius * cosValue, //yStart : centerY - midRadius * 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, lastAddRadius, startAngle, endAngle, 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 center = this.parseCenter(this.zr, serie.center); var centerX = center[0]; // 圆心横坐标 var centerY = center[1]; // 圆心纵坐标 var x; var y; var midAngle = ((endAngle + startAngle) / 2 + 360) % 360; // 中值 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显示 radius = radius[1]; x = centerX; y = centerY; textAlign = 'center'; } else if (labelControl.position == 'inner'){ // 内部显示 radius = (radius[0] + radius[1]) / 2 + lastAddRadius; 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) //- (-textStyle.fontSize) + lastAddRadius; x = centerX + radius * zrMath.cos(midAngle, true); y = centerY - radius * zrMath.sin(midAngle, true); textAlign = (midAngle >= 90 && midAngle <= 270) ? 'right' : 'left'; } if (labelControl.position != 'center' && labelControl.position != 'inner' ) { x += textAlign == 'left' ? 20 : -20; } data.__labelX = x - (textAlign == 'left' ? 5 : -5); data.__labelY = y; return new TextShape({ zlevel : this._zlevelBase + 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' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }); },
getSector : function ( seriesIndex, dataIndex, percent, isSelected, r0, r1, startAngle, endAngle, defaultColor ) { var series = this.series; var serie = series[seriesIndex]; var data = serie.data[dataIndex]; var queryTarget = [data, serie]; var center = this.parseCenter(this.zr, serie.center); // 多级控制 var normal = this.deepMerge( queryTarget, 'itemStyle.normal' ) || {}; var emphasis = this.deepMerge( queryTarget, 'itemStyle.emphasis' ) || {}; var normalColor = this.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || defaultColor; var emphasisColor = this.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data) || (typeof normalColor == 'string' ? zrColor.lift(normalColor, -0.2) : normalColor ); var sector = { zlevel : this._zlevelBase, clickable : true, style : { x : center[0], // 圆心横坐标 y : center[1], // 圆心纵坐标 r0 : r0, // 圆环内半径 r : r1, // 圆环外半径 startAngle : startAngle, endAngle : endAngle, brushType : 'both', color : normalColor, lineWidth : normal.borderWidth, strokeColor : normal.borderColor, lineJoin: 'round' }, highlightStyle : { color : emphasisColor, lineWidth : emphasis.borderWidth, strokeColor : emphasis.borderColor, lineJoin: 'round' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; if (isSelected) { var midAngle = ((sector.style.startAngle + sector.style.endAngle) / 2) .toFixed(2) - 0; sector.style._hasSelected = true; sector.style._x = sector.style.x; sector.style._y = sector.style.y; var offset = this.query(serie, 'selectedOffset'); sector.style.x += zrMath.cos(midAngle, true) * offset; sector.style.y -= zrMath.sin(midAngle, true) * offset; this._selected[seriesIndex][dataIndex] = true; } else { this._selected[seriesIndex][dataIndex] = false; } if (this._selectedMode) { sector.onclick = this.shapeHandler.onclick; } if (this.deepQuery([data, serie, this.option], 'calculable')) { this.setCalculable(sector); sector.draggable = true; } // “normal下不显示,emphasis显示”添加事件响应 if (this._needLabel(serie, data, true) // emphasis下显示文本 || this._needLabelLine(serie, data, true) // emphasis下显示引导线 ) { sector.onmouseover = this.shapeHandler.onmouseover; } sector = new SectorShape(sector); return sector; },
function onclick(param) { if (!self.isClick || !param.target) { // 没有在当前实例上发生点击直接返回 return; } var offset; // 偏移 var target = param.target; var style = target.style; var seriesIndex = ecData.get(target, 'seriesIndex'); var dataIndex = ecData.get(target, 'dataIndex'); for (var i = 0, len = self.shapeList.length; i < len; i++) { if (self.shapeList[i].id == target.id) { seriesIndex = ecData.get(target, 'seriesIndex'); dataIndex = ecData.get(target, 'dataIndex'); // 当前点击的 if (!style._hasSelected) { var midAngle = ((style.startAngle + style.endAngle) / 2) .toFixed(2) - 0; target.style._hasSelected = true; _selected[seriesIndex][dataIndex] = true; target.style._x = target.style.x; target.style._y = target.style.y; offset = self.deepQuery( [series[seriesIndex]], 'selectedOffset' ); target.style.x += zrMath.cos(midAngle, true) * offset; target.style.y -= zrMath.sin(midAngle, true) * offset; } else { // 复位 target.style.x = target.style._x; target.style.y = target.style._y; target.style._hasSelected = false; _selected[seriesIndex][dataIndex] = false; } zr.modShape(target.id, target); } else if (self.shapeList[i].style._hasSelected && _selectedMode == 'single' ) { seriesIndex = ecData.get(self.shapeList[i], 'seriesIndex'); dataIndex = ecData.get(self.shapeList[i], 'dataIndex'); // 单选模式下需要取消其他已经选中的 self.shapeList[i].style.x = self.shapeList[i].style._x; self.shapeList[i].style.y = self.shapeList[i].style._y; self.shapeList[i].style._hasSelected = false; _selected[seriesIndex][dataIndex] = false; zr.modShape( self.shapeList[i].id, self.shapeList[i] ); } } messageCenter.dispatch( ecConfig.EVENT.PIE_SELECTED, param.event, {selected : _selected} ); zr.refresh(); }
/** * 需要显示则会有返回构建好的shape,否则返回undefined */ function _getLabel( seriesIndex, dataIndex, percent, startAngle, endAngle, defaultColor, isEmphasis ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 特定状态下是否需要显示文本标签 if (_needLabel(serie, data, isEmphasis)) { var status = isEmphasis ? 'emphasis' : 'normal'; // serie里有默认配置,放心大胆的用! var itemStyle = zrUtil.merge( zrUtil.clone(data.itemStyle) || {}, serie.itemStyle, { 'overwrite' : false, 'recursive' : true } ); // label配置 var labelControl = itemStyle[status].label; var textStyle = labelControl.textStyle || {}; var centerX = serie.center[0]; // 圆心横坐标 var centerY = serie.center[1]; // 圆心纵坐标 var midAngle = ((endAngle + startAngle) / 2) % 360; // 角度中值 var radius; // 标签位置半径 var textAlign; if (labelControl.position == 'outer') { // 外部显示,默认 radius = serie.radius[1] + itemStyle[status].labelLine.length + textStyle.fontSize; textAlign = (midAngle >= 150 && midAngle <= 210) ? 'right' : ((midAngle <= 30 || midAngle >= 330) ? 'left' : 'center' ); return { shape : 'text', zlevel : _zlevelBase + 1, hoverable : false, style : { x : centerX + radius * zrMath.cos(midAngle, true), y : centerY - radius * zrMath.sin(midAngle, true), color : textStyle.color || defaultColor, text : _getLabelText( seriesIndex, dataIndex, percent, status ), textAlign : textStyle.align || textAlign, textBaseline : textStyle.baseline || 'middle', textFont : self.getFont(textStyle) }, highlightStyle : { brushType : 'fill' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; } else if (labelControl.position == 'center') { return { shape : 'text', zlevel : _zlevelBase + 1, hoverable : false, style : { x : centerX, y : centerY, color : textStyle.color || defaultColor, text : _getLabelText( seriesIndex, dataIndex, percent, status ), textAlign : textStyle.align || 'center', textBaseline : textStyle.baseline || 'middle', textFont : self.getFont(textStyle) }, highlightStyle : { brushType : 'fill' }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; } else { // 内部显示由sector自带,不返回即可 return; /* radius = (serie.radius[0] + serie.radius[1]) / 2; textAlign = 'center'; defaultColor = '#fff'; */ } } else { return; } }
/** * 构建扇形 */ function _getSector( seriesIndex, dataIndex, percent, isSelected, startAngle, endAngle, defaultColor ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 多级控制 var normalColor = self.deepQuery( [data, serie], 'itemStyle.normal.color' ); var emphasisColor = self.deepQuery( [data, serie], 'itemStyle.emphasis.color' ); var sector = { shape : 'sector', // 扇形 zlevel : _zlevelBase, clickable : true, style : { x : serie.center[0], // 圆心横坐标 y : serie.center[1], // 圆心纵坐标 r0 : serie.radius[0], // 圆环内半径 r : serie.radius[1], // 圆环外半径 startAngle : startAngle, endAngle : endAngle, brushType : 'both', color : normalColor || defaultColor, strokeColor : '#fff', lineWidth: 1 }, highlightStyle : { color : emphasisColor || normalColor || defaultColor }, _seriesIndex : seriesIndex, _dataIndex : dataIndex }; if (isSelected) { var midAngle = ((sector.style.startAngle + sector.style.endAngle) / 2) .toFixed(2) - 0; sector.style._hasSelected = true; sector.style._x = sector.style.x; sector.style._y = sector.style.y; var offset = self.deepQuery([serie], 'selectedOffset'); sector.style.x += zrMath.cos(midAngle, true) * offset; sector.style.y -= zrMath.sin(midAngle, true) * offset; _selected[seriesIndex][dataIndex] = true; } else { _selected[seriesIndex][dataIndex] = false; } if (_selectedMode) { sector.onclick = self.shapeHandler.onclick; } if (self.deepQuery([data, serie, option], 'calculable')) { self.setCalculable(sector); sector.draggable = true; } if (_needLabel(serie, data, false) && self.deepQuery( [data, serie], 'itemStyle.normal.label.position' ) == 'inner' ) { sector.style.text = _getLabelText( seriesIndex, dataIndex, percent, 'normal' ); sector.style.textPosition = 'specific'; sector.style.textColor = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.color' ) || '#fff'; sector.style.textAlign = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.align' ) || 'center'; sector.style.textBaseLine = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.baseline' ) || 'middle'; sector.style.textX = Math.round( serie.center[0] + (serie.radius[1] + serie.radius[0]) / 2 * zrMath.cos((startAngle + endAngle) / 2, true) ); sector.style.textY = Math.round( serie.center[1] - (serie.radius[1] + serie.radius[0]) / 2 * zrMath.sin((startAngle + endAngle) / 2, true) ); sector.style.textFont = self.getFont(self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle' )); } if (_needLabel(serie, data, true) && self.deepQuery( [data, serie], 'itemStyle.emphasis.label.position' ) == 'inner' ) { sector.highlightStyle.text = _getLabelText( seriesIndex, dataIndex, percent, 'emphasis' ); sector.highlightStyle.textPosition = 'specific'; sector.highlightStyle.textColor = self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle.color' ) || '#fff'; sector.highlightStyle.textAlign = self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle.align' ) || 'center'; sector.highlightStyle.textBaseLine = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.baseline' ) || 'middle'; sector.highlightStyle.textX = Math.round( serie.center[0] + (serie.radius[1] + serie.radius[0]) / 2 * zrMath.cos((startAngle + endAngle) / 2, true) ); sector.highlightStyle.textY = Math.round( serie.center[1] - (serie.radius[1] + serie.radius[0]) / 2 * zrMath.sin((startAngle + endAngle) / 2, true) ); sector.highlightStyle.textFont = self.getFont(self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle' )); } // “normal下不显示,emphasis显示”添加事件响应 if (_needLabel(serie, data, true) // emphasis下显示文本 || _needLabelLine(serie, data, true) // emphasis下显示引导线 ) { sector.onmouseover = self.shapeHandler.onmouserover; } return sector; }
function polar2cartesian(r, theta) { return [ r * zrMath.sin(theta), r * zrMath.cos(theta) ]; }
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: this.getZlevelBase(), z: this.getZBase() + 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; },
define("echarts/chart/pie",["require","../component/base","./base","zrender/shape/Text","zrender/shape/Ring","zrender/shape/Circle","zrender/shape/Sector","zrender/shape/BrokenLine","../config","../util/ecData","zrender/tool/util","zrender/tool/math","zrender/tool/color","../chart"],function(require){function e(e,s,a,r,o){t.call(this,e,s,a,r,o),i.call(this);var n=this;n.shapeHandler.onmouseover=function(e){var t=e.target,i=l.get(t,"seriesIndex"),s=l.get(t,"dataIndex"),a=l.get(t,"special"),r=t._lastAddRadius,o=t.style.startAngle,h=t.style.endAngle,p=t.highlightStyle.color,d=n.getLabel(i,s,a,r,o,h,p,!0);if(d)n.zr.addHoverShape(d);var c=n.getLabelLine(i,s,r,t.style.r0,t.style.r,o,h,p,!0);if(c)n.zr.addHoverShape(c)},this.refresh(r)}var t=require("../component/base"),i=require("./base"),s=require("zrender/shape/Text"),a=require("zrender/shape/Ring"),r=require("zrender/shape/Circle"),o=require("zrender/shape/Sector"),n=require("zrender/shape/BrokenLine"),h=require("../config"),l=require("../util/ecData"),p=require("zrender/tool/util"),d=require("zrender/tool/math"),c=require("zrender/tool/color");return e.prototype={type:h.CHART_TYPE_PIE,_buildShape:function(){var e=this.series,t=this.component.legend;this.selectedMap={},this._selected={};var i,s,o;this._selectedMode=!1;for(var n,p=0,d=e.length;d>p;p++)if(e[p].type==h.CHART_TYPE_PIE){if(e[p]=this.reformOption(e[p]),n=e[p].name||"",this.selectedMap[n]=t?t.isSelected(n):!0,!this.selectedMap[n])continue;if(i=this.parseCenter(this.zr,e[p].center),s=this.parseRadius(this.zr,e[p].radius),this._selectedMode=this._selectedMode||e[p].selectedMode,this._selected[p]=[],this.deepQuery([e[p],this.option],"calculable"))o={zlevel:this._zlevelBase,hoverable:!1,style:{x:i[0],y:i[1],r0:s[0]<=10?0:s[0]-10,r:s[1]+10,brushType:"stroke",lineWidth:1,strokeColor:e[p].calculableHolderColor||this.ecTheme.calculableHolderColor}},l.pack(o,e[p],p,void 0,-1),this.setCalculable(o),o=s[0]<=10?new r(o):new a(o),this.shapeList.push(o);this._buildSinglePie(p),this.buildMark(p)}this.addShapeList()},_buildSinglePie:function(e){for(var t,i=this.series,s=i[e],a=s.data,r=this.component.legend,o=0,n=0,h=0,l=Number.NEGATIVE_INFINITY,p=0,d=a.length;d>p;p++){if(t=a[p].name,r)this.selectedMap[t]=r.isSelected(t);else this.selectedMap[t]=!0;if(this.selectedMap[t]&&!isNaN(a[p].value)){if(0!==+a[p].value)o++;else n++;h+=+a[p].value,l=Math.max(l,+a[p].value)}}for(var c,f,u,y,m,g,_=100,v=0,b=s.clockWise,x=s.startAngle.toFixed(2)-0,S=s.minAngle||.01,M=360-S*o-.01*n,L=s.roseType,p=0,d=a.length;d>p;p++)if(t=a[p].name,this.selectedMap[t]&&!isNaN(a[p].value)){if(r)u=r.getColor(t);else u=this.zr.getColor(p);if(c=_,_=a[p].value/h,"area"!=L)f=b?x-_*M-(0!==_?S:.01):_*M+x+(0!==_?S:.01);else f=b?x-360/d:360/d+x;if(f=f.toFixed(2)-0,_=(100*_).toFixed(2),y=this.parseRadius(this.zr,s.radius),m=+y[0],g=+y[1],"radius"==L)g=a[p].value/l*(g-m)*.8+.2*(g-m)+m;else if("area"==L)g=Math.sqrt(a[p].value/l)*(g-m)+m;if(b){var C;C=x,x=f,f=C}if(p>0&&Math.abs(x-f)<15&&4>c&&this._needLabel(s,a[p],!1)&&"center"!=this.deepQuery([a[p],s],"itemStyle.normal.label.position"))v+=4>_?20:-20;else v=0;if(this._buildItem(e,p,_,v,a[p].selected,m,g,x,f,u),!b)x=f}else;},_buildItem:function(e,t,i,s,a,r,o,n,h,p){var d=this.series,c=this.getSector(e,t,i,a,r,o,n,h,p);l.pack(c,d[e],e,d[e].data[t],t,d[e].data[t].name,i),c._lastAddRadius=s,this.shapeList.push(c);var f=this.getLabel(e,t,i,s,n,h,p,!1);if(f)l.pack(f,d[e],e,d[e].data[t],t,d[e].data[t].name,i),f._dataIndex=t,this.shapeList.push(f);var u=this.getLabelLine(e,t,s,r,o,n,h,p,!1);if(u)l.pack(u,d[e],e,d[e].data[t],t,d[e].data[t].name,i),u._dataIndex=t,this.shapeList.push(u)},getSector:function(e,t,i,s,a,r,n,h,l){var p=this.series,f=p[e],u=f.data[t],y=[u,f],m=this.parseCenter(this.zr,f.center),g=this.deepMerge(y,"itemStyle.normal")||{},_=this.deepMerge(y,"itemStyle.emphasis")||{},v=this.getItemStyleColor(g.color,e,t,u)||l,b=this.getItemStyleColor(_.color,e,t,u)||("string"==typeof v?c.lift(v,-.2):v),x={zlevel:this._zlevelBase,clickable:this.deepQuery(y,"clickable"),style:{x:m[0],y:m[1],r0:a,r:r,startAngle:n,endAngle:h,brushType:"both",color:v,lineWidth:g.borderWidth,strokeColor:g.borderColor,lineJoin:"round"},highlightStyle:{color:b,lineWidth:_.borderWidth,strokeColor:_.borderColor,lineJoin:"round"},_seriesIndex:e,_dataIndex:t};if(s){var S=((x.style.startAngle+x.style.endAngle)/2).toFixed(2)-0;x.style._hasSelected=!0,x.style._x=x.style.x,x.style._y=x.style.y;var M=this.query(f,"selectedOffset");x.style.x+=d.cos(S,!0)*M,x.style.y-=d.sin(S,!0)*M,this._selected[e][t]=!0}else this._selected[e][t]=!1;if(this._selectedMode)x.onclick=this.shapeHandler.onclick;if(this.deepQuery([u,f,this.option],"calculable"))this.setCalculable(x),x.draggable=!0;if(this._needLabel(f,u,!0)||this._needLabelLine(f,u,!0))x.onmouseover=this.shapeHandler.onmouseover;return x=new o(x)},getLabel:function(e,t,i,a,r,o,n,h){var l=this.series,c=l[e],f=c.data[t];if(this._needLabel(c,f,h)){var u,y,m,g=h?"emphasis":"normal",_=p.merge(p.clone(f.itemStyle)||{},c.itemStyle),v=_[g].label,b=v.textStyle||{},x=this.parseCenter(this.zr,c.center),S=x[0],M=x[1],L=((o+r)/2+360)%360,C=this.parseRadius(this.zr,c.radius),z="middle";if(v.position=v.position||_.normal.label.position,"center"==v.position)C=C[1],u=S,y=M,m="center";else if("inner"==v.position)C=(C[0]+C[1])/2+a,u=Math.round(S+C*d.cos(L,!0)),y=Math.round(M-C*d.sin(L,!0)),n="#fff",m="center";else C=C[1]- -_[g].labelLine.length+a,u=S+C*d.cos(L,!0),y=M-C*d.sin(L,!0),m=L>=90&&270>=L?"right":"left";if("center"!=v.position&&"inner"!=v.position)u+="left"==m?20:-20;return f.__labelX=u-("left"==m?5:-5),f.__labelY=y,new s({zlevel:this._zlevelBase+1,hoverable:!1,style:{x:u,y:y,color:b.color||n,text:this.getLabelText(e,t,i,g),textAlign:b.align||m,textBaseline:b.baseline||z,textFont:this.getFont(b)},highlightStyle:{brushType:"fill"},_seriesIndex:e,_dataIndex:t})}},getLabelText:function(e,t,i,s){var a=this.series,r=a[e],o=r.data[t],n=this.deepQuery([o,r],"itemStyle."+s+".label.formatter");if(n){if("function"==typeof n)return n.call(this.myChart,r.name,o.name,o.value,i);else if("string"==typeof n)return n=n.replace("{a}","{a0}").replace("{b}","{b0}").replace("{c}","{c0}").replace("{d}","{d0}"),n=n.replace("{a0}",r.name).replace("{b0}",o.name).replace("{c0}",o.value).replace("{d0}",i)}else return o.name},getLabelLine:function(e,t,i,s,a,r,o,h,l){var c=this.series,f=c[e],u=f.data[t];if(this._needLabelLine(f,u,l)){var y=l?"emphasis":"normal",m=p.merge(p.clone(u.itemStyle)||{},f.itemStyle),g=m[y].labelLine,_=g.lineStyle||{},v=this.parseCenter(this.zr,f.center),b=v[0],x=v[1],S=a,M=this.parseRadius(this.zr,f.radius)[1]- -g.length+i,L=(o+r)/2%360,C=d.cos(L,!0),z=d.sin(L,!0);return new n({zlevel:this._zlevelBase+1,hoverable:!1,style:{pointList:[[b+S*C,x-S*z],[b+M*C,x-M*z],[u.__labelX,u.__labelY]],strokeColor:_.color||h,lineType:_.type,lineWidth:_.width},_seriesIndex:e,_dataIndex:t})}else;},_needLabel:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".label.show")},_needLabelLine:function(e,t,i){return this.deepQuery([t,e],"itemStyle."+(i?"emphasis":"normal")+".labelLine.show")},reformOption:function(e){var t=p.merge;return e=t(e||{},this.ecTheme.pie),e.itemStyle.normal.label.textStyle=t(e.itemStyle.normal.label.textStyle||{},this.ecTheme.textStyle),e.itemStyle.emphasis.label.textStyle=t(e.itemStyle.emphasis.label.textStyle||{},this.ecTheme.textStyle),e},refresh:function(e){if(e)this.option=e,this.series=e.series;this.backupShapeList(),this._buildShape()},addDataAnimation:function(e){for(var t=this.series,i={},s=0,a=e.length;a>s;s++)i[e[s][0]]=e[s];var r={},o={},n={},l=this.shapeList;this.shapeList=[];for(var p,d,c,f={},s=0,a=e.length;a>s;s++)if(p=e[s][0],d=e[s][2],c=e[s][3],t[p]&&t[p].type==h.CHART_TYPE_PIE){if(d){if(!c)r[p+"_"+t[p].data.length]="delete";f[p]=1}else if(!c)r[p+"_-1"]="delete",f[p]=-1;else f[p]=0;this._buildSinglePie(p)}for(var u,y,s=0,a=this.shapeList.length;a>s;s++)switch(p=this.shapeList[s]._seriesIndex,u=this.shapeList[s]._dataIndex,y=p+"_"+u,this.shapeList[s].type){case"sector":r[y]=this.shapeList[s];break;case"text":o[y]=this.shapeList[s];break;case"broken-line":n[y]=this.shapeList[s]}this.shapeList=[];for(var m,s=0,a=l.length;a>s;s++)if(p=l[s]._seriesIndex,i[p]){if(u=l[s]._dataIndex+f[p],y=p+"_"+u,m=r[y],!m)continue;if("sector"==l[s].type)if("delete"!=m)this.zr.animate(l[s].id,"style").when(400,{startAngle:m.style.startAngle,endAngle:m.style.endAngle}).start();else this.zr.animate(l[s].id,"style").when(400,f[p]<0?{startAngle:l[s].style.startAngle}:{endAngle:l[s].style.endAngle}).start();else if("text"==l[s].type||"broken-line"==l[s].type)if("delete"==m)this.zr.delShape(l[s].id);else switch(l[s].type){case"text":m=o[y],this.zr.animate(l[s].id,"style").when(400,{x:m.style.x,y:m.style.y}).start();break;case"broken-line":m=n[y],this.zr.animate(l[s].id,"style").when(400,{pointList:m.style.pointList}).start()}}this.shapeList=l},onclick:function(e){var t=this.series;if(this.isClick&&e.target){this.isClick=!1;for(var i,s=e.target,a=s.style,r=l.get(s,"seriesIndex"),o=l.get(s,"dataIndex"),n=0,p=this.shapeList.length;p>n;n++)if(this.shapeList[n].id==s.id){if(r=l.get(s,"seriesIndex"),o=l.get(s,"dataIndex"),!a._hasSelected){var c=((a.startAngle+a.endAngle)/2).toFixed(2)-0;s.style._hasSelected=!0,this._selected[r][o]=!0,s.style._x=s.style.x,s.style._y=s.style.y,i=this.query(t[r],"selectedOffset"),s.style.x+=d.cos(c,!0)*i,s.style.y-=d.sin(c,!0)*i}else s.style.x=s.style._x,s.style.y=s.style._y,s.style._hasSelected=!1,this._selected[r][o]=!1;this.zr.modShape(s.id,s)}else if(this.shapeList[n].style._hasSelected&&"single"==this._selectedMode)r=l.get(this.shapeList[n],"seriesIndex"),o=l.get(this.shapeList[n],"dataIndex"),this.shapeList[n].style.x=this.shapeList[n].style._x,this.shapeList[n].style.y=this.shapeList[n].style._y,this.shapeList[n].style._hasSelected=!1,this._selected[r][o]=!1,this.zr.modShape(this.shapeList[n].id,this.shapeList[n]);this.messageCenter.dispatch(h.EVENT.PIE_SELECTED,e.event,{selected:this._selected,target:l.get(s,"name")},this.myChart),this.zr.refresh()}}},p.inherits(e,i),p.inherits(e,t),require("../chart").define("pie",e),e});
/** * 构建扇形 */ function _getSector( seriesIndex, dataIndex, percent, startAngle, endAngle, defaultColor ) { var serie = series[seriesIndex]; var data = serie.data[dataIndex]; // 多级控制 var normalColor = self.deepQuery( [data, serie], 'itemStyle.normal.color' ); var emphasisColor = self.deepQuery( [data, serie], 'itemStyle.emphasis.color' ); var sector = { shape : 'sector', // 扇形 zlevel : _zlevelBase, style : { x : serie.center[0], // 圆心横坐标 y : serie.center[1], // 圆心纵坐标 r0 : serie.radius[0], // 圆环内半径 r : serie.radius[1], // 圆环外半径 startAngle : startAngle, endAngle : endAngle, brushType : 'both', color : normalColor || defaultColor, strokeColor : '#fff', lineWidth: 2 }, highlightStyle : { color : emphasisColor || normalColor || defaultColor }, clickable : true, onclick : self.shapeHandler.onclick }; if (self.deepQuery([data, serie, option], 'calculable')) { self.setCalculable(sector); sector.draggable = true; } if (_needLabel(serie, data, false) && self.deepQuery( [data, serie], 'itemStyle.normal.label.position' ) == 'inner' ) { sector.style.text = data.name; sector.style.textPosition = 'specific'; sector.style.textColor = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.color' ) || '#fff'; sector.style.textAlign = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.align' ) || 'center'; sector.style.textBaseLine = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.baseline' ) || 'middle'; sector.style.textX = Math.round( serie.center[0] + (serie.radius[1] + serie.radius[0]) / 2 * zrMath.cos((startAngle + endAngle) / 2, true) ); sector.style.textY = Math.round( serie.center[1] - (serie.radius[1] + serie.radius[0]) / 2 * zrMath.sin((startAngle + endAngle) / 2, true) ); sector.style.textFont = self.getFont(self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle' )); } if (_needLabel(serie, data, true) && self.deepQuery( [data, serie], 'itemStyle.emphasis.label.position' ) == 'inner' ) { sector.highlightStyle.text = data.name; sector.highlightStyle.textPosition = 'specific'; sector.highlightStyle.textColor = self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle.color' ) || '#fff'; sector.highlightStyle.textAlign = self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle.align' ) || 'center'; sector.highlightStyle.textBaseLine = self.deepQuery( [data, serie], 'itemStyle.normal.label.textStyle.baseline' ) || 'middle'; sector.highlightStyle.textX = Math.round( serie.center[0] + (serie.radius[1] + serie.radius[0]) / 2 * zrMath.cos((startAngle + endAngle) / 2, true) ); sector.highlightStyle.textY = Math.round( serie.center[1] - (serie.radius[1] + serie.radius[0]) / 2 * zrMath.sin((startAngle + endAngle) / 2, true) ); sector.highlightStyle.textFont = self.getFont(self.deepQuery( [data, serie], 'itemStyle.emphasis.label.textStyle' )); } // “normal下不显示,emphasis显示”添加事件响应 if (_needLabel(serie, data, true) // emphasis下显示文本 || _needLabelLine(serie, data, true) // emphasis下显示引导线 ) { sector.onmouseover = self.shapeHandler.onmouserover; } return sector; }