/**
 * echarts图表类：饼图
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
 *
 */
module.exports = function (require) {
  var ChartBase = require('./base'); // 图形依赖


  var TextShape = require('zrender/shape/Text');

  var RingShape = require('zrender/shape/Ring');

  var CircleShape = require('zrender/shape/Circle');

  var SectorShape = require('zrender/shape/Sector');

  var PolylineShape = require('zrender/shape/Polyline');

  var ecConfig = require('../config'); // 饼图默认参数


  ecConfig.pie = {
    zlevel: 0,
    // 一级层叠
    z: 2,
    // 二级层叠
    clickable: true,
    legendHoverLink: true,
    center: ['50%', '50%'],
    // 默认全局居中
    radius: [0, '75%'],
    clockWise: true,
    // 默认顺时针
    startAngle: 90,
    minAngle: 0,
    // 最小角度改为0
    selectedOffset: 10,
    // 选中是扇区偏移量
    // selectedMode: false,     // 选择模式，默认关闭，可选single，multiple
    // roseType: null,          // 南丁格尔玫瑰图模式，'radius'（半径） | 'area'（面积）
    itemStyle: {
      normal: {
        // color: 各异,
        borderColor: 'rgba(0,0,0,0)',
        borderWidth: 1,
        label: {
          show: true,
          position: 'outer' // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
          // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
          // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数

        },
        labelLine: {
          show: true,
          length: 20,
          lineStyle: {
            // color: 各异,
            width: 1,
            type: 'solid'
          }
        }
      },
      emphasis: {
        // color: 各异,
        borderColor: 'rgba(0,0,0,0)',
        borderWidth: 1,
        label: {
          show: false // position: 'outer'
          // formatter: 标签文本格式器，同Tooltip.formatter，不支持异步回调
          // textStyle: null      // 默认使用全局文本样式，详见TEXTSTYLE
          // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数

        },
        labelLine: {
          show: false,
          length: 20,
          lineStyle: {
            // color: 各异,
            width: 1,
            type: 'solid'
          }
        }
      }
    }
  };

  var ecData = require('../util/ecData');

  var zrUtil = require('zrender/tool/util');

  var zrMath = require('zrender/tool/math');

  var zrColor = require('zrender/tool/color');
  /**
   * 构造函数
   * @param {Object} messageCenter echart消息中心
   * @param {ZRender} zr zrender实例
   * @param {Object} series 数据
   * @param {Object} component 组件
   */


  function Pie(ecTheme, messageCenter, zr, option, myChart) {
    // 图表基类
    ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
    var self = this;
    /**
     * 输出动态视觉引导线
     */

    self.shapeHandler.onmouseover = function (param) {
      var shape = param.target;
      var seriesIndex = ecData.get(shape, 'seriesIndex');
      var dataIndex = ecData.get(shape, 'dataIndex');
      var percent = ecData.get(shape, 'special');
      var center = [shape.style.x, shape.style.y];
      var startAngle = shape.style.startAngle;
      var endAngle = shape.style.endAngle;
      var midAngle = ((endAngle + startAngle) / 2 + 360) % 360; // 中值

      var defaultColor = shape.highlightStyle.color; // 文本标签，需要显示则会有返回

      var label = self.getLabel(seriesIndex, dataIndex, percent, center, midAngle, defaultColor, true);

      if (label) {
        self.zr.addHoverShape(label);
      } // 文本标签视觉引导线，需要显示则会有返回


      var labelLine = self.getLabelLine(seriesIndex, dataIndex, center, shape.style.r0, shape.style.r, midAngle, defaultColor, true);

      if (labelLine) {
        self.zr.addHoverShape(labelLine);
      }
    };

    this.refresh(option);
  }

  Pie.prototype = {
    type: ecConfig.CHART_TYPE_PIE,

    /**
     * 绘制图形
     */
    _buildShape: function () {
      var series = this.series;
      var legend = this.component.legend;
      this.selectedMap = {};
      this._selected = {};
      var center;
      var radius;
      var pieCase; // 饼图箱子

      this._selectedMode = false;
      var serieName;

      for (var i = 0, l = series.length; i < l; i++) {
        if (series[i].type === ecConfig.CHART_TYPE_PIE) {
          series[i] = this.reformOption(series[i]);
          this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
          serieName = series[i].name || ''; // 系列图例开关

          this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;

          if (!this.selectedMap[serieName]) {
            continue;
          }

          center = this.parseCenter(this.zr, series[i].center);
          radius = this.parseRadius(this.zr, series[i].radius);
          this._selectedMode = this._selectedMode || series[i].selectedMode;
          this._selected[i] = [];

          if (this.deepQuery([series[i], this.option], 'calculable')) {
            pieCase = {
              zlevel: series[i].zlevel,
              z: series[i].z,
              hoverable: false,
              style: {
                x: center[0],
                // 圆心横坐标
                y: center[1],
                // 圆心纵坐标
                // 圆环内外半径
                r0: radius[0] <= 10 ? 0 : radius[0] - 10,
                r: radius[1] + 10,
                brushType: 'stroke',
                lineWidth: 1,
                strokeColor: series[i].calculableHolderColor || this.ecTheme.calculableHolderColor || ecConfig.calculableHolderColor
              }
            };
            ecData.pack(pieCase, series[i], i, undefined, -1);
            this.setCalculable(pieCase);
            pieCase = radius[0] <= 10 ? new CircleShape(pieCase) : new RingShape(pieCase);
            this.shapeList.push(pieCase);
          }

          this._buildSinglePie(i);

          this.buildMark(i);
        }
      }

      this.addShapeList();
    },

    /**
     * 构建单个饼图
     *
     * @param {number} seriesIndex 系列索引
     */
    _buildSinglePie: function (seriesIndex) {
      var series = this.series;
      var serie = series[seriesIndex];
      var data = serie.data;
      var legend = this.component.legend;
      var itemName;
      var totalSelected = 0; // 迭代累计选中且非0个数

      var totalSelectedValue0 = 0; // 迭代累计选中0只个数

      var totalValue = 0; // 迭代累计

      var maxValue = Number.NEGATIVE_INFINITY;
      var singleShapeList = []; // 计算需要显示的个数和总值

      for (var i = 0, l = data.length; i < l; i++) {
        itemName = data[i].name;
        this.selectedMap[itemName] = legend ? legend.isSelected(itemName) : true;

        if (this.selectedMap[itemName] && !isNaN(data[i].value)) {
          if (+data[i].value !== 0) {
            totalSelected++;
          } else {
            totalSelectedValue0++;
          }

          totalValue += +data[i].value;
          maxValue = Math.max(maxValue, +data[i].value);
        }
      }

      if (totalValue === 0) {
        return;
      }

      var percent = 100;
      var clockWise = serie.clockWise;
      var startAngle = (serie.startAngle.toFixed(2) - 0 + 360) % 360;
      var endAngle;
      var minAngle = serie.minAngle || 0.01; // #bugfixed

      var totalAngle = 360 - minAngle * totalSelected - 0.01 * totalSelectedValue0;
      var defaultColor;
      var roseType = serie.roseType;
      var center;
      var radius;
      var r0; // 扇形内半径

      var r1; // 扇形外半径

      for (var i = 0, l = data.length; i < l; i++) {
        itemName = data[i].name;

        if (!this.selectedMap[itemName] || isNaN(data[i].value)) {
          continue;
        } // 默认颜色策略，有图例则从图例中获取颜色定义，没有就全局颜色定义


        defaultColor = legend ? legend.getColor(itemName) : this.zr.getColor(i);
        percent = data[i].value / totalValue;

        if (roseType != 'area') {
          endAngle = clockWise ? startAngle - percent * totalAngle - (percent !== 0 ? minAngle : 0.01) : percent * totalAngle + startAngle + (percent !== 0 ? minAngle : 0.01);
        } else {
          endAngle = clockWise ? startAngle - 360 / l : 360 / l + startAngle;
        }

        endAngle = endAngle.toFixed(2) - 0;
        percent = (percent * 100).toFixed(2);
        center = this.parseCenter(this.zr, serie.center);
        radius = this.parseRadius(this.zr, serie.radius);
        r0 = +radius[0];
        r1 = +radius[1];

        if (roseType === 'radius') {
          r1 = data[i].value / maxValue * (r1 - r0) * 0.8 + (r1 - r0) * 0.2 + r0;
        } else if (roseType === 'area') {
          r1 = Math.sqrt(data[i].value / maxValue) * (r1 - r0) + r0;
        }

        if (clockWise) {
          var temp;
          temp = startAngle;
          startAngle = endAngle;
          endAngle = temp;
        }

        this._buildItem(singleShapeList, seriesIndex, i, percent, data[i].selected, center, r0, r1, startAngle, endAngle, defaultColor);

        if (!clockWise) {
          startAngle = endAngle;
        }
      }

      this._autoLabelLayout(singleShapeList, center, r1);

      for (var i = 0, l = singleShapeList.length; i < l; i++) {
        this.shapeList.push(singleShapeList[i]);
      }

      singleShapeList = null;
    },

    /**
     * 构建单个扇形及指标
     */
    _buildItem: function (singleShapeList, seriesIndex, dataIndex, percent, isSelected, center, r0, r1, startAngle, endAngle, defaultColor) {
      var series = this.series;
      var midAngle = ((endAngle + startAngle) / 2 + 360) % 360; // 中值
      // 扇形

      var sector = this.getSector(seriesIndex, dataIndex, percent, isSelected, center, r0, r1, startAngle, endAngle, defaultColor); // 图形需要附加的私有数据

      ecData.pack(sector, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name, percent);
      singleShapeList.push(sector); // 文本标签，需要显示则会有返回

      var label = this.getLabel(seriesIndex, dataIndex, percent, center, midAngle, defaultColor, false); // 文本标签视觉引导线，需要显示则会有返回

      var labelLine = this.getLabelLine(seriesIndex, dataIndex, center, r0, r1, midAngle, defaultColor, false);

      if (labelLine) {
        ecData.pack(labelLine, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name, percent);
        singleShapeList.push(labelLine);
      }

      if (label) {
        ecData.pack(label, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name, percent);
        label._labelLine = labelLine;
        singleShapeList.push(label);
      }
    },

    /**
     * 构建扇形
     */
    getSector: function (seriesIndex, dataIndex, percent, isSelected, center, r0, r1, startAngle, endAngle, defaultColor) {
      var series = this.series;
      var serie = series[seriesIndex];
      var data = serie.data[dataIndex];
      var queryTarget = [data, serie]; // 多级控制

      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: serie.zlevel,
        z: serie.z,
        clickable: this.deepQuery(queryTarget, 'clickable'),
        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;
      } // “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;
    },

    /**
     * 需要显示则会有返回构建好的shape，否则返回undefined
     */
    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;
    },

    /**
     * 根据lable.format计算label text
     */
    getLabelText: function (seriesIndex, dataIndex, percent, status) {
      var series = this.series;
      var serie = series[seriesIndex];
      var data = serie.data[dataIndex];
      var formatter = this.deepQuery([data, serie], 'itemStyle.' + status + '.label.formatter');

      if (formatter) {
        if (typeof formatter === 'function') {
          return formatter.call(this.myChart, {
            seriesIndex: seriesIndex,
            seriesName: serie.name || '',
            series: serie,
            dataIndex: dataIndex,
            data: data,
            name: data.name,
            value: data.value,
            percent: percent
          });
        } else if (typeof formatter === 'string') {
          formatter = formatter.replace('{a}', '{a0}').replace('{b}', '{b0}').replace('{c}', '{c0}').replace('{d}', '{d0}');
          formatter = formatter.replace('{a0}', serie.name).replace('{b0}', data.name).replace('{c0}', data.value).replace('{d0}', percent);
          return formatter;
        }
      } else {
        return data.name;
      }
    },

    /**
     * 需要显示则会有返回构建好的shape，否则返回undefined
     */
    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;
      }
    },

    /**
     * 返回特定状态（normal or emphasis）下是否需要显示label标签文本
     * @param {Object} serie
     * @param {Object} data
     * @param {boolean} isEmphasis true is 'emphasis' and false is 'normal'
     */
    _needLabel: function (serie, data, isEmphasis) {
      return this.deepQuery([data, serie], 'itemStyle.' + (isEmphasis ? 'emphasis' : 'normal') + '.label.show');
    },

    /**
     * 返回特定状态（normal or emphasis）下是否需要显示labelLine标签视觉引导线
     * @param {Object} serie
     * @param {Object} data
     * @param {boolean} isEmphasis true is 'emphasis' and false is 'normal'
     */
    _needLabelLine: function (serie, data, isEmphasis) {
      return this.deepQuery([data, serie], 'itemStyle.' + (isEmphasis ? 'emphasis' : 'normal') + '.labelLine.show');
    },

    /**
     * @param {Array.<Object>} sList 单系列图形集合
     */
    _autoLabelLayout: function (sList, center, r) {
      var leftList = [];
      var rightList = [];

      for (var i = 0, l = sList.length; i < l; i++) {
        if (sList[i]._labelPosition === 'outer' || sList[i]._labelPosition === 'outside') {
          sList[i]._rect._y = sList[i]._rect.y;

          if (sList[i]._rect.x < center[0]) {
            leftList.push(sList[i]);
          } else {
            rightList.push(sList[i]);
          }
        }
      }

      this._layoutCalculate(leftList, center, r, -1);

      this._layoutCalculate(rightList, center, r, 1);
    },

    /**
     * @param {Array.<Object>} tList 单系列文本图形集合
     * @param {number} direction 水平方向参数，left为-1，right为1
     */
    _layoutCalculate: function (tList, center, r, direction) {
      tList.sort(function (a, b) {
        return a._rect.y - b._rect.y;
      }); // 压

      function _changeDown(start, end, delta, direction) {
        for (var j = start; j < end; j++) {
          tList[j]._rect.y += delta;
          tList[j].style.y += delta;

          if (tList[j]._labelLine) {
            tList[j]._labelLine.style.pointList[1][1] += delta;
            tList[j]._labelLine.style.pointList[2][1] += delta;
          }

          if (j > start && j + 1 < end && tList[j + 1]._rect.y > tList[j]._rect.y + tList[j]._rect.height) {
            _changeUp(j, delta / 2);

            return;
          }
        }

        _changeUp(end - 1, delta / 2);
      } // 弹


      function _changeUp(end, delta) {
        for (var j = end; j >= 0; j--) {
          tList[j]._rect.y -= delta;
          tList[j].style.y -= delta;

          if (tList[j]._labelLine) {
            tList[j]._labelLine.style.pointList[1][1] -= delta;
            tList[j]._labelLine.style.pointList[2][1] -= delta;
          }

          if (j > 0 && tList[j]._rect.y > tList[j - 1]._rect.y + tList[j - 1]._rect.height) {
            break;
          }
        }
      }

      function _changeX(sList, isDownList, center, r, direction) {
        var x = center[0];
        var y = center[1];
        var deltaX;
        var deltaY;
        var length;
        var lastDeltaX = direction > 0 ? isDownList // 右侧
        ? Number.MAX_VALUE // 下
        : 0 // 上
        : isDownList // 左侧
        ? Number.MAX_VALUE // 下
        : 0; // 上

        for (var i = 0, l = sList.length; i < l; i++) {
          deltaY = Math.abs(sList[i]._rect.y - y);
          length = sList[i]._radius - r;
          deltaX = deltaY < r + length ? Math.sqrt((r + length + 20) * (r + length + 20) - Math.pow(sList[i]._rect.y - y, 2)) : Math.abs(sList[i]._rect.x + (direction > 0 ? 0 : sList[i]._rect.width) - x);

          if (isDownList && deltaX >= lastDeltaX) {
            // 右下，左下
            deltaX = lastDeltaX - 10;
          }

          if (!isDownList && deltaX <= lastDeltaX) {
            // 右上，左上
            deltaX = lastDeltaX + 10;
          }

          sList[i]._rect.x = sList[i].style.x = x + deltaX * direction;

          if (sList[i]._labelLine) {
            sList[i]._labelLine.style.pointList[2][0] = x + (deltaX - 5) * direction;
            sList[i]._labelLine.style.pointList[1][0] = x + (deltaX - 20) * direction;
          }

          lastDeltaX = deltaX;
        }
      }

      var lastY = 0;
      var delta;
      var len = tList.length;
      var upList = [];
      var downList = [];

      for (var i = 0; i < len; i++) {
        delta = tList[i]._rect.y - lastY;

        if (delta < 0) {
          _changeDown(i, len, -delta, direction);
        }

        lastY = tList[i]._rect.y + tList[i]._rect.height;
      }

      if (this.zr.getHeight() - lastY < 0) {
        _changeUp(len - 1, lastY - this.zr.getHeight());
      }

      for (var i = 0; i < len; i++) {
        if (tList[i]._rect.y >= center[1]) {
          downList.push(tList[i]);
        } else {
          upList.push(tList[i]);
        }
      }

      _changeX(downList, true, center, r, direction);

      _changeX(upList, false, center, r, direction);
    },

    /**
     * 参数修正&默认值赋值，重载基类方法
     * @param {Object} opt 参数
     */
    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;
    },

    /**
     * 刷新
     */
    refresh: function (newOption) {
      if (newOption) {
        this.option = newOption;
        this.series = newOption.series;
      }

      this.backupShapeList();

      this._buildShape();
    },

    /**
     * 动态数据增加动画
     */
    addDataAnimation: function (params, done) {
      var series = this.series;
      var aniMap = {}; // seriesIndex索引参数

      for (var i = 0, l = params.length; i < l; i++) {
        aniMap[params[i][0]] = params[i];
      }

      var aniCount = 0;

      function animationDone() {
        aniCount--;

        if (aniCount === 0) {
          done && done();
        }
      } // 构建新的饼图匹配差异做动画


      var sectorMap = {};
      var textMap = {};
      var lineMap = {};
      var backupShapeList = this.shapeList;
      this.shapeList = [];
      var seriesIndex;
      var isHead;
      var dataGrow;
      var deltaIdxMap = {}; // 修正新增数据后会对dataIndex产生错位匹配

      for (var i = 0, l = params.length; i < l; i++) {
        seriesIndex = params[i][0];
        isHead = params[i][2];
        dataGrow = params[i][3];

        if (series[seriesIndex] && series[seriesIndex].type === ecConfig.CHART_TYPE_PIE) {
          if (isHead) {
            if (!dataGrow) {
              sectorMap[seriesIndex + '_' + series[seriesIndex].data.length] = 'delete';
            }

            deltaIdxMap[seriesIndex] = 1;
          } else {
            if (!dataGrow) {
              sectorMap[seriesIndex + '_-1'] = 'delete';
              deltaIdxMap[seriesIndex] = -1;
            } else {
              deltaIdxMap[seriesIndex] = 0;
            }
          }

          this._buildSinglePie(seriesIndex);
        }
      }

      var dataIndex;
      var key;

      for (var i = 0, l = this.shapeList.length; i < l; i++) {
        seriesIndex = this.shapeList[i]._seriesIndex;
        dataIndex = this.shapeList[i]._dataIndex;
        key = seriesIndex + '_' + dataIndex; // map映射让n*n变n

        switch (this.shapeList[i].type) {
          case 'sector':
            sectorMap[key] = this.shapeList[i];
            break;

          case 'text':
            textMap[key] = this.shapeList[i];
            break;

          case 'polyline':
            lineMap[key] = this.shapeList[i];
            break;
        }
      }

      this.shapeList = [];
      var targeSector;

      for (var i = 0, l = backupShapeList.length; i < l; i++) {
        seriesIndex = backupShapeList[i]._seriesIndex;

        if (aniMap[seriesIndex]) {
          dataIndex = backupShapeList[i]._dataIndex + deltaIdxMap[seriesIndex];
          key = seriesIndex + '_' + dataIndex;
          targeSector = sectorMap[key];

          if (!targeSector) {
            continue;
          }

          if (backupShapeList[i].type === 'sector') {
            if (targeSector != 'delete') {
              aniCount++; // 原有扇形

              this.zr.animate(backupShapeList[i].id, 'style').when(400, {
                startAngle: targeSector.style.startAngle,
                endAngle: targeSector.style.endAngle
              }).done(animationDone).start();
            } else {
              aniCount++; // 删除的扇形

              this.zr.animate(backupShapeList[i].id, 'style').when(400, deltaIdxMap[seriesIndex] < 0 ? {
                startAngle: backupShapeList[i].style.startAngle
              } : {
                endAngle: backupShapeList[i].style.endAngle
              }).done(animationDone).start();
            }
          } else if (backupShapeList[i].type === 'text' || backupShapeList[i].type === 'polyline') {
            if (targeSector === 'delete') {
              // 删除逻辑一样
              this.zr.delShape(backupShapeList[i].id);
            } else {
              // 懒得新建变量了，借用一下
              switch (backupShapeList[i].type) {
                case 'text':
                  aniCount++;
                  targeSector = textMap[key];
                  this.zr.animate(backupShapeList[i].id, 'style').when(400, {
                    x: targeSector.style.x,
                    y: targeSector.style.y
                  }).done(animationDone).start();
                  break;

                case 'polyline':
                  aniCount++;
                  targeSector = lineMap[key];
                  this.zr.animate(backupShapeList[i].id, 'style').when(400, {
                    pointList: targeSector.style.pointList
                  }).done(animationDone).start();
                  break;
              }
            }
          }
        }
      }

      this.shapeList = backupShapeList; // 没有动画

      if (!aniCount) {
        done && done();
      }
    },
    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);
        } 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.messageCenter.dispatch(ecConfig.EVENT.PIE_SELECTED, param.event, {
        selected: this._selected,
        target: ecData.get(target, 'name')
      }, this.myChart);
      this.zr.refreshNextFrame();
    }
  };
  zrUtil.inherits(Pie, ChartBase); // 图表注册

  require('../chart').define('pie', Pie);

  return Pie;
}(require);