/**
 * echarts组件类：极坐标
 *
 * @desc echarts基于Canvas，纯Javascript图表库，提供直观，生动，可交互，可个性化定制的数据统计图表。
 * @author Neil (杨骥, 511415343@qq.com)
 *
 */
define(function (require) {
    var Base = require('./base');

    // 图形依赖
    var TextShape = require('zrender/shape/Text');
    var LineShape = require('zrender/shape/Line');
    var PolygonShape = require('zrender/shape/Polygon');
    var Circle = require('zrender/shape/Circle');
    var Ring = require('zrender/shape/Ring');

    var ecConfig = require('../config');
    ecConfig.polar = {
        zlevel: 0,                  // 一级层叠
        z: 0,                       // 二级层叠
        center: ['50%', '50%'],    // 默认全局居中
        radius: '75%',
        startAngle: 90,
        boundaryGap: [0, 0],   // 数值起始和结束两端空白策略
        splitNumber: 5,
        name: {
            show: true,
            // formatter: null,
            textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                color: '#333'
            }
        },
        axisLine: {            // 坐标轴线
            show: true,        // 默认显示，属性show控制显示与否
            lineStyle: {       // 属性lineStyle控制线条样式
                color: '#ccc',
                width: 1,
                type: 'solid'
            }
        },
        axisLabel: {           // 坐标轴文本标签，详见axis.axisLabel
            show: false,
            // formatter: null,
            textStyle: {       // 其余属性默认使用全局文本样式，详见TEXTSTYLE
                color: '#333'
            }
        },
        splitArea: {
            show: true,
            areaStyle: {
                color: ['rgba(250,250,250,0.3)','rgba(200,200,200,0.3)']
            }
        },
        splitLine: {
            show: true,
            lineStyle: {
                width: 1,
                color: '#ccc'
            }
        },
        type: 'polygon'
        // indicator: []
    };

    var zrUtil = require('zrender/tool/util');
    var ecCoordinates = require('../util/coordinates');

    function Polar(ecTheme, messageCenter, zr, option, myChart) {
        Base.call(this, ecTheme, messageCenter, zr, option, myChart);

        this.refresh(option);
    }

    Polar.prototype = {
        type : ecConfig.COMPONENT_TYPE_POLAR,

        /**
         * 绘制图形
         */
        _buildShape : function () {
            for (var i = 0; i < this.polar.length; i ++) {
                this._index = i;
                this.reformOption(this.polar[i]);

                this._queryTarget = [this.polar[i], this.option];
                this._createVector(i);
                this._buildSpiderWeb(i);

                this._buildText(i);

                this._adjustIndicatorValue(i);
                this._addAxisLabel(i);
            }

            for (var i = 0; i < this.shapeList.length; i ++) {
                this.zr.addShape(this.shapeList[i]);
            }
        },

        /**
         * 生成蜘蛛网顶点坐标
         * @param {number} polar的index
         */
        _createVector : function (index) {
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
            var length = indicator.length;
            var startAngle = item.startAngle ;
            var dStep = 2 * Math.PI / length;
            var radius = this._getRadius();
            var __ecIndicator = item.__ecIndicator = [];
            var vector;

            for (var i = 0 ;i < length ; i ++) {
                vector = ecCoordinates.polar2cartesian(
                    radius, startAngle * Math.PI / 180 + dStep * i
                );
                __ecIndicator.push({
                    // 将图形翻转
                    vector : [vector[1], -vector[0]]
                });
            }
        },

        /**
         * 获取外圈的半径
         *
         * @return {number}
         */
        _getRadius : function () {
            var item = this.polar[this._index];
            return this.parsePercent(
                item.radius,
                Math.min(this.zr.getWidth(), this.zr.getHeight()) / 2
            );
        },

        /**
         * 构建蜘蛛网
         * @param {number} polar的index
         */
        _buildSpiderWeb : function (index) {
            var item = this.polar[index];
            var __ecIndicator = item.__ecIndicator;
            var splitArea = item.splitArea;
            var splitLine = item.splitLine;

            var center = this.getCenter(index);
            var splitNumber = item.splitNumber;

            var strokeColor = splitLine.lineStyle.color;
            var lineWidth = splitLine.lineStyle.width;
            var show = splitLine.show;

            var axisLine = this.deepQuery(this._queryTarget, 'axisLine');

            this._addArea(
                __ecIndicator, splitNumber, center,
                splitArea, strokeColor, lineWidth, show
            );

            axisLine.show && this._addLine(
                __ecIndicator, center, axisLine
            );
        },

        /**
         * 绘制axisLabel
         */
        _addAxisLabel : function (index) {
            var accMath = require('../util/accMath');
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
            var __ecIndicator = item.__ecIndicator;
            var axisLabel;
            var vector;
            var style;
            var newStyle;
            var splitNumber = this.deepQuery(this._queryTarget, 'splitNumber');
            var center = this.getCenter(index);
            var vector;
            var value;
            var text;
            var theta;
            // var startAngle = this.deepQuery(this._queryTarget, 'startAngle');
            var offset;
            var interval;

            for (var i = 0; i < indicator.length; i ++) {
                axisLabel = this.deepQuery(
                    [indicator[i], item, this.option], 'axisLabel'
                );

                if (axisLabel.show) {
                    var textStyle = this.deepQuery([axisLabel, item, this.option], 'textStyle');
                    style = {};
                    style.textFont = this.getFont(textStyle);
                    style.color = textStyle.color;

                    style = zrUtil.merge(style, axisLabel);
                    style.lineWidth = style.width;

                    vector = __ecIndicator[i].vector;
                    value = __ecIndicator[i].value;
                    theta = i / indicator.length * 2 * Math.PI;
                    offset = axisLabel.offset || 10;
                    interval = axisLabel.interval || 0;

                    if (!value) {
                        return;
                    }

                    for (var j = 1 ; j <= splitNumber; j += interval + 1) {
                        newStyle = zrUtil.merge({}, style);
                        text = accMath.accAdd(value.min, accMath.accMul(value.step, j));
                        newStyle.text = this.numAddCommas(text);
                        newStyle.x = j * vector[0] / splitNumber
                                     + Math.cos(theta) * offset + center[0];
                        newStyle.y = j * vector[1] / splitNumber
                                     + Math.sin(theta) * offset + center[1];

                        this.shapeList.push(new TextShape({
                            zlevel: this.getZlevelBase(),
                            z: this.getZBase(),
                            style : newStyle,
                            draggable : false,
                            hoverable : false
                        }));
                    }
                }
            }
        },

        /**
         * 绘制坐标头的文字
         * @param {number} polar的index
         */
        _buildText  : function (index) {
            var item = this.polar[index];
            var __ecIndicator = item.__ecIndicator;
            var vector;
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
            var center = this.getCenter(index);
            var style;
            var textAlign;
            var name;
            var rotation;
            var x = 0;
            var y = 0;
            var margin;
            var textStyle;

            for (var i = 0; i < indicator.length; i ++) {
                name = this.deepQuery(
                    [indicator[i], item, this.option], 'name'
                );

                if (!name.show) {
                    continue;
                }
                textStyle = this.deepQuery(
                    [name, item, this.option],
                    'textStyle'
                );

                style = {};

                style.textFont = this.getFont(textStyle);
                style.color = textStyle.color;

                if (typeof name.formatter == 'function') {
                    style.text = name.formatter.call(this.myChart, indicator[i].text, i);
                }
                else if (typeof name.formatter == 'string'){
                    style.text = name.formatter.replace(
                        '{value}', indicator[i].text
                    );
                }
                else {
                    style.text = indicator[i].text;
                }
                __ecIndicator[i].text = style.text;

                vector = __ecIndicator[i].vector;

                if (Math.round(vector[0]) > 0) {
                    textAlign = 'left';
                }
                else if (Math.round(vector[0]) < 0) {
                    textAlign = 'right';
                }
                else {
                    textAlign = 'center';
                }

                if (name.margin == null) {
                    vector = this._mapVector(vector, center, 1.1);
                }
                else {
                    margin = name.margin;
                    x = vector[0] > 0 ? margin : - margin;
                    y = vector[1] > 0 ? margin : - margin;

                    x = vector[0] === 0 ? 0 : x;
                    y = vector[1] === 0 ? 0 : y;
                    vector = this._mapVector(vector, center, 1);
                }


                style.textAlign = textAlign;
                style.x = vector[0] + x;
                style.y = vector[1] + y;

                if (name.rotate) {
                    rotation = [
                        name.rotate / 180 * Math.PI,
                        vector[0], vector[1]
                    ];
                }
                else {
                    rotation = [0, 0, 0];
                }

                this.shapeList.push(new TextShape({
                    zlevel: this.getZlevelBase(),
                    z: this.getZBase(),
                    style : style,
                    draggable : false,
                    hoverable : false,
                    rotation : rotation
                }));
            }
        },

        getIndicatorText : function(polarIndex, indicatorIndex) {
            return this.polar[polarIndex]
                   && this.polar[polarIndex].__ecIndicator[indicatorIndex]
                   && this.polar[polarIndex].__ecIndicator[indicatorIndex].text;
        },

        /**
         * 添加一个隐形的盒子 当做drop的容器 暴露给外部的图形类使用
         * @param {number} polar的index
         * @return {Object} 添加的盒子图形
         */
        getDropBox : function (index) {
            var index = index || 0;
            var item = this.polar[index];
            var center = this.getCenter(index);
            var __ecIndicator = item.__ecIndicator;
            var len = __ecIndicator.length;
            var pointList = [];
            var vector;
            var shape;
            var type = item.type;

            if (type == 'polygon') {
                for (var i = 0; i < len; i ++) {
                    vector = __ecIndicator[i].vector;
                    pointList.push(this._mapVector(vector, center, 1.2));
                }
                shape = this._getShape(
                    pointList, 'fill', 'rgba(0,0,0,0)', '', 1
                );
            } else if (type == 'circle') {
                shape = this._getCircle(
                    '', 1, 1.2, center, 'fill', 'rgba(0,0,0,0)'
                );
            }

            return shape;
        },

        /**
         * 绘制蜘蛛网的正n变形
         *
         * @param {Array<Object>} 指标数组
         * @param {number} 分割线数量
         * @param {Array<number>} 中点坐标
         * @param {Object} 分割区域对象
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         */
        _addArea : function (
            __ecIndicator, splitNumber, center,
            splitArea, strokeColor, lineWidth, show
        ) {
            var shape;
            var scale;
            var scale1;
            var pointList;
            var type = this.deepQuery(this._queryTarget, 'type');

            for (var i = 0; i < splitNumber ; i ++ ) {
                scale = (splitNumber - i) / splitNumber;

                if (show) {
                    if (type == 'polygon') {
                        pointList = this._getPointList(
                            __ecIndicator, scale, center);
                        shape = this._getShape(
                            pointList, 'stroke', '', strokeColor, lineWidth
                        );
                    } else if (type == 'circle') {
                        shape = this._getCircle(
                            strokeColor, lineWidth, scale, center, 'stroke'
                        );
                    }

                    this.shapeList.push(shape);
                }

                if (splitArea.show) {
                    scale1 = (splitNumber - i - 1) / splitNumber;
                    this._addSplitArea(
                        __ecIndicator, splitArea, scale, scale1, center, i
                    );
                }
            }
        },

        /**
         * 绘制圆
         *
         * @param {string} strokeColor
         * @param {number} lineWidth
         * @param {number} scale
         * @param {Array.<number>} center
         * @param {string} brushType
         * @param {string} color
         * @return {Circle}
         */
        _getCircle : function (
            strokeColor, lineWidth, scale, center, brushType, color
        ) {
            var radius = this._getRadius();
            return new Circle({
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style: {
                    x: center[0],
                    y: center[1],
                    r: radius * scale,
                    brushType: brushType,
                    strokeColor: strokeColor,
                    lineWidth: lineWidth,
                    color: color
                },
                hoverable : false,
                draggable : false
            });
        },

        /**
         * 绘制圆环
         *
         * @param {string} color  间隔颜色
         * @param {number} scale0  小圆的scale
         * @param {number} scale1  大圆的scale
         * @param {Array.<number>} center  圆点
         * @return {Ring}
         */
        _getRing : function (color, scale0, scale1, center) {
            var radius = this._getRadius();
            return new Ring({
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style : {
                    x : center[0],
                    y : center[1],
                    r : scale0 * radius,
                    r0 : scale1 * radius,
                    color : color,
                    brushType : 'fill'
                },
                hoverable : false,
                draggable : false
            });
        },

        /**
         * 获取需要绘制的多边形的点集
         * @param {Object} serie的指标参数
         * @param {number} 缩小的系数
         * @param {Array<number>} 中点坐标
         *
         * @return {Array<Array<number>>} 返回绘制的点集
         */
        _getPointList : function (__ecIndicator, scale, center) {
            var pointList = [];
            var len = __ecIndicator.length;
            var vector;

            for (var i = 0 ; i < len ; i ++ ) {
                vector = __ecIndicator[i].vector;

                pointList.push(this._mapVector(vector, center, scale));
            }
            return pointList;
        },

        /**
         * 获取绘制的图形
         * @param {Array<Array<number>>} 绘制的点集
         * @param {string} 绘制方式 stroke | fill | both 描边 | 填充 | 描边 + 填充
         * @param {string} 颜色
         * @param {string} 描边颜色
         * @param {number} 线条宽度
         * @return {Object} 绘制的图形对象
         */
        _getShape : function (
            pointList, brushType, color, strokeColor, lineWidth
        ) {
            return new PolygonShape({
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style : {
                    pointList   : pointList,
                    brushType   : brushType,
                    color       : color,
                    strokeColor : strokeColor,
                    lineWidth   : lineWidth
                },
                hoverable : false,
                draggable : false
            });
        },

        /**
         * 绘制填充区域
         */
        _addSplitArea : function (
            __ecIndicator, splitArea, scale, scale1, center, colorInd
        ) {
            var indLen = __ecIndicator.length;
            var color;
            var colorArr = splitArea.areaStyle.color;
            var colorLen;

            var vector;
            var vector1;
            var pointList = [];
            var indLen = __ecIndicator.length;
            var shape;

            var type = this.deepQuery(this._queryTarget, 'type');

            if (typeof colorArr == 'string') {
                colorArr = [colorArr];
            }
            colorLen = colorArr.length;
            color = colorArr[ colorInd % colorLen];

            if (type == 'polygon') {
                for (var i = 0; i < indLen ; i ++) {
                    pointList = [];
                    vector = __ecIndicator[i].vector;
                    vector1 = __ecIndicator[(i + 1) % indLen].vector;

                    pointList.push(this._mapVector(vector, center, scale));
                    pointList.push(this._mapVector(vector, center, scale1));
                    pointList.push(this._mapVector(vector1, center, scale1));
                    pointList.push(this._mapVector(vector1, center, scale));

                    shape = this._getShape(
                        pointList, 'fill', color, '', 1
                    );
                    this.shapeList.push(shape);
                }
            } else if (type == 'circle') {
                shape = this._getRing(color, scale, scale1, center);
                this.shapeList.push(shape);
            }
        },

        /**
         * 转换坐标
         *
         * @param {Array<number>} 原始坐标
         * @param {Array<number>} 中点坐标
         * @param {number} 缩小的倍数
         *
         * @return {Array<number>} 转换后的坐标
         */
        _mapVector : function (vector, center, scale) {
            return [
                vector[0] * scale + center[0],
                vector[1] * scale + center[1]
            ];
        },

        /**
         * 获取中心点位置 暴露给外部图形类使用
         * @param {number} polar的index
         */
        getCenter : function (index) {
            var index = index || 0;
            return this.parseCenter(this.zr, this.polar[index].center);
        },

        /**
         * 绘制从中点出发的线
         *
         * @param {Array<Object>} 指标对象
         * @param {Array<number>} 中点坐标
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         * @param {string} 线条绘制类型
         *              solid | dotted | dashed 实线 | 点线 | 虚线
         */
        _addLine : function (
            __ecIndicator, center, axisLine
        ) {
            var indLen = __ecIndicator.length;
            var line;
            var vector;
            var lineStyle = axisLine.lineStyle;
            var strokeColor = lineStyle.color;
            var lineWidth = lineStyle.width;
            var lineType = lineStyle.type;

            for (var i = 0; i < indLen ; i ++ ) {
                vector = __ecIndicator[i].vector;
                line = this._getLine(
                    center[0], center[1],
                    vector[0] + center[0],
                    vector[1] + center[1],
                    strokeColor, lineWidth, lineType
                );
                this.shapeList.push(line);
            }
        },

        /**
         * 获取线条对象
         * @param {number} 出发点横坐标
         * @param {number} 出发点纵坐标
         * @param {number} 终点横坐标
         * @param {number} 终点纵坐标
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         * @param {string} 线条类型
         *
         * @return {Object} 线条对象
         */
        _getLine : function (
            xStart, yStart, xEnd, yEnd, strokeColor, lineWidth, lineType
        ) {
            return new LineShape({
                zlevel: this.getZlevelBase(),
                z: this.getZBase(),
                style : {
                    xStart : xStart,
                    yStart : yStart,
                    xEnd   : xEnd,
                    yEnd   : yEnd,
                    strokeColor : strokeColor,
                    lineWidth   : lineWidth,
                    lineType    : lineType
                },
                hoverable : false
            });
        },

        /**
         * 调整指标的值，当indicator中存在max时设置为固定值
         * @param {number} polar的index
         */
        _adjustIndicatorValue : function (index) {
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
            var len = indicator.length;
            var __ecIndicator = item.__ecIndicator;
            var max;
            var min;
            var data = this._getSeriesData(index);

            var boundaryGap = item.boundaryGap;
            var splitNumber = item.splitNumber;
            var scale = item.scale;

            var smartSteps = require('../util/smartSteps');
            for (var i = 0; i < len ; i ++ ) {
                if (typeof indicator[i].max == 'number') {
                    max = indicator[i].max;
                    min = indicator[i].min || 0;
                }
                else {
                    var value = this._findValue(
                        data, i, splitNumber, boundaryGap
                    );
                    min = value.min;
                    max = value.max;
                }
                 // 非scale下双正，修正最小值为0
                if (!scale && min >= 0 && max >= 0) {
                    min = 0;
                }
                // 非scale下双负，修正最大值为0
                if (!scale && min <= 0 && max <= 0) {
                    max = 0;
                }
                var stepOpt = smartSteps(min, max, splitNumber);

                __ecIndicator[i].value = {
                    min: stepOpt.min,
                    max: stepOpt.max,
                    step: stepOpt.step
                };
            }
        },

        /**
         * 将series中的数据拿出来，如果没有polarIndex属性，默认为零
         * @param {number} polar 的index
         * @param {Array<Object>} 需要处理的数据
         */
        _getSeriesData : function (index) {
            var data = [];
            var serie;
            var serieData;
            var legend = this.component.legend;
            var polarIndex;

            for (var i = 0; i < this.series.length; i ++) {
                serie = this.series[i];
                if (serie.type != ecConfig.CHART_TYPE_RADAR) {
                    continue;
                }
                serieData = serie.data || [];
                for (var j = 0; j < serieData.length; j ++) {
                    polarIndex = this.deepQuery(
                        [serieData[j], serie, this.option], 'polarIndex'
                    ) || 0;
                    if (polarIndex == index
                        && (!legend || legend.isSelected(serieData[j].name))
                    ) {
                        data.push(serieData[j]);
                    }
                }
            }
            return data;
        },

        /**
         * 查找指标合适的值
         *
         * 如果只有一组数据以数据中的最大值作为最大值 0为最小值
         * 如果是多组，使用同一维度的进行比较 选出最大值最小值
         * 对它们进行处理
         * @param {Object} serie 的 data
         * @param {number} index 指标的序号
         * @param {number} splitNumber 分段格式
         * * @param {boolean} boundaryGap 两端留白
         */
        _findValue : function (data, index, splitNumber, boundaryGap) {
            var max;
            var min;
            var one;

            if (!data || data.length === 0) {
                return;
            }

            function _compare(item) {
                (item > max || max === undefined) && (max = item);
                (item < min || min === undefined) && (min = item);
            }

            if (data.length == 1) {
                min = 0;
            }
            if (data.length != 1) {
                for (var i = 0; i < data.length; i ++) {
                    _compare(this.getDataFromOption(data[i].value[index]));
                }
            }
            else {
                one = data[0];
                for (var i = 0; i < one.value.length; i ++) {
                    _compare(this.getDataFromOption(one.value[i]));
                }
            }

            var gap = Math.abs(max - min);
            min = min - Math.abs(gap * boundaryGap[0]);
            max = max + Math.abs(gap * boundaryGap[1]);
            if (min === max) {
                if (max === 0) {
                    // 修复全0数据
                    max = 1;
                }
                // 修复最大值==最小值时数据整形
                else if (max > 0) {
                    min = max / splitNumber;
                }
                else { // max < 0
                    max = max / splitNumber;
                }
            }

            return {
                max : max,
                min : min
            };
        },

        /**
         * 获取每个指标上某个value对应的坐标
         * @param {number} polarIndex
         * @param {number} indicatorIndex
         * @param {number} value
         * @return {Array<number>} 对应坐标
         */
        getVector : function (polarIndex, indicatorIndex, value) {
            polarIndex = polarIndex || 0;
            indicatorIndex = indicatorIndex || 0;
            var __ecIndicator = this.polar[polarIndex].__ecIndicator;

            if (indicatorIndex >= __ecIndicator.length) {
                return ;
            }

            var indicator = this.polar[polarIndex].__ecIndicator[indicatorIndex];
            var center = this.getCenter(polarIndex);
            var vector = indicator.vector;
            var max = indicator.value.max;
            var min = indicator.value.min;
            var alpha;

            if (typeof value == 'undefined') {
                return center;
            }

            switch (value) {
                case 'min' :
                    value = min;
                    break;
                case 'max' :
                    value = max;
                    break;
                case 'center' :
                    value = (max + min) / 2;
                    break;
            }

            if (max != min) {
                alpha = (value - min) / (max - min);
            }
            else {
                alpha = 0.5;
            }

            return this._mapVector(vector, center, alpha);
        },

        /**
         * 判断一个点是否在网内
         * @param {Array<number>} 坐标
         * @return {number} 返回polarindex  返回-1表示不在任何polar
         */
        isInside : function (vector) {
            var polar = this.getNearestIndex(vector);

            if (polar) {
                return polar.polarIndex;
            }
            return -1;
        },

        /**
         * 如果一个点在网内，返回离它最近的数据轴的index
         * @param {Array<number>} 坐标
         * @return {Object} | false
         *      polarIndex
         *      valueIndex
         */
        getNearestIndex : function (vector) {
            var item;
            var center;
            var radius;
            var polarVector;
            var startAngle;
            var indicator;
            var len;
            var angle;
            var finalAngle;
            for (var i = 0 ; i < this.polar.length; i ++) {
                item = this.polar[i];
                center = this.getCenter(i);
                if (vector[0] == center[0] && vector[1] == center[1]) {
                    return {
                        polarIndex : i,
                        valueIndex : 0
                    };
                }
                radius = this._getRadius();
                startAngle = item.startAngle;
                indicator = item.indicator;
                len = indicator.length;
                angle = 2 * Math.PI / len;
                // 注意y轴的翻转
                polarVector = ecCoordinates.cartesian2polar(
                    vector[0] - center[0], center[1] - vector[1]
                );
                if (vector[0] - center[0] < 0) {
                    polarVector[1] += Math.PI;
                }
                if (polarVector[1] < 0) {
                    polarVector[1] += 2 * Math.PI;
                }


                // 减去startAngle的偏移量 再加2PI变成正数
                finalAngle = polarVector[1] -
                    startAngle / 180 * Math.PI + Math.PI * 2;

                if (Math.abs(Math.cos(finalAngle % (angle / 2))) * radius
                    > polarVector[0])
                {
                    return {
                        polarIndex : i,
                        valueIndex : Math.floor(
                            (finalAngle + angle / 2 ) / angle
                            ) % len
                    };
                }
            }
        },

        /**
         * 获取指标信息
         * @param {number} polarIndex
         * @return {Array<Object>} indicator
         */
        getIndicator : function (index) {
            var index = index || 0;
            return this.polar[index].indicator;
        },

         /**
         * 刷新
         */
        refresh : function (newOption) {
            if (newOption) {
                this.option = newOption;
                this.polar = this.option.polar;
                this.series = this.option.series;
            }
            this.clear();
            this._buildShape();
        }
    };

    zrUtil.inherits(Polar, Base);

    require('../component').define('polar', Polar);

    return Polar;
});