polar.js 30.9 KB
Newer Older
K
kener 已提交
1 2 3 4 5 6 7
/**
 * echarts组件类:极坐标
 *
 * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
 * @author Neil (杨骥, yangji01@baidu.com)
 *
 */
K
kener 已提交
8 9 10 11
define(function (require) {
    var Base = require('./base');
    
    // 图形依赖
K
kener 已提交
12 13
    var TextShape = require('zrender/shape/Text');
    var LineShape = require('zrender/shape/Line');
K
kener 已提交
14
    var PolygonShape = require('zrender/shape/Polygon');
K
kener 已提交
15

K
kener 已提交
16 17 18
    var ecConfig = require('../config');
    var zrUtil = require('zrender/tool/util');
    var ecCoordinates = require('../util/coordinates');
K
kener 已提交
19

K
kener 已提交
20 21 22 23 24 25 26 27 28
    function Polar(ecTheme, messageCenter, zr, option, component) {
        Base.call(this, ecTheme, zr, option);
        
        this.init(option, component);
    }
    
    Polar.prototype = {
        type : ecConfig.COMPONENT_TYPE_POLAR,
        init : function (newOption, newComponent) {
K
kener 已提交
29 30 31
            this.component = newComponent || this.component;
            
            this.refresh(newOption);
K
kener 已提交
32
        },
K
kener 已提交
33 34 35 36
        
        /**
         * 绘制图形
         */
K
kener 已提交
37 38 39
        _buildShape : function () {
            for (var i = 0; i < this.polar.length; i ++) {
                this.reformOption(this.polar[i]);
K
kener 已提交
40

K
kener 已提交
41 42 43
                this._queryTarget = [this.polar[i], this.option];
                this._createVector(i);
                this._buildSpiderWeb(i);
K
kener 已提交
44

K
kener 已提交
45
                this._buildText(i);
K
kener 已提交
46

K
kener 已提交
47 48
                this._adjustIndicatorValue(i);
                this._addAxisLabel(i);
K
kener 已提交
49
            }
K
kener 已提交
50

K
kener 已提交
51 52
            for (var i = 0; i < this.shapeList.length; i ++) {
                this.zr.addShape(this.shapeList[i]);
K
kener 已提交
53
            }
K
kener 已提交
54
        },
K
kener 已提交
55

K
kener 已提交
56 57 58 59
        /**
         * 生成蜘蛛网顶点坐标
         * @param {number} polar的index
         */
K
kener 已提交
60 61 62
        _createVector : function (index) {
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
K
kener 已提交
63 64 65
            var length = indicator.length;
            var startAngle = item.startAngle ;
            var dStep = 2 * Math.PI / length;
K
kener 已提交
66
            var radius = this.parsePercent(
K
kener 已提交
67
                item.radius,
K
kener 已提交
68
                Math.min(this.zr.getWidth(), this.zr.getHeight()) / 2
K
kener 已提交
69 70 71 72 73 74 75
            );
            var __ecIndicator = item.__ecIndicator = [];
            var vector;

            for (var i = 0 ;i < length ; i ++) {
                vector = ecCoordinates.polar2cartesian(
                    radius, startAngle * Math.PI / 180 + dStep * i
K
kener 已提交
76
                );
K
kener 已提交
77 78 79 80
                __ecIndicator.push({
                    // 将图形翻转
                    vector : [vector[1], -vector[0]]
                });
K
kener 已提交
81
            }
K
kener 已提交
82
        },
K
kener 已提交
83

K
kener 已提交
84 85 86 87
        /**
         * 构建蜘蛛网
         * @param {number} polar的index
         */
K
kener 已提交
88 89
        _buildSpiderWeb : function (index) {
            var item = this.polar[index];
K
kener 已提交
90 91 92
            var __ecIndicator = item.__ecIndicator;
            var splitArea = item.splitArea;
            var splitLine = item.splitLine;
K
kener 已提交
93

K
kener 已提交
94
            var center = this.getCenter(index);
K
kener 已提交
95
            var splitNumber = item.splitNumber;
K
kener 已提交
96

K
kener 已提交
97 98 99
            var strokeColor = splitLine.lineStyle.color;
            var lineWidth = splitLine.lineStyle.width;
            var show = splitLine.show;
K
kener 已提交
100

K
kener 已提交
101
            var axisLine = this.deepQuery(this._queryTarget, 'axisLine');
K
kener 已提交
102

K
kener 已提交
103
            this._addArea(
K
kener 已提交
104 105 106 107
                __ecIndicator, splitNumber, center, 
                splitArea, strokeColor, lineWidth, show
            );
            
K
kener 已提交
108
            this._addLine(
K
kener 已提交
109 110
                __ecIndicator, center, axisLine
            );
K
kener 已提交
111
        },
K
kener 已提交
112 113 114 115

        /**
         * 绘制axisLabel
         */
K
kener 已提交
116 117 118
        _addAxisLabel : function (index) {
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
K
kener 已提交
119 120 121 122 123
            var __ecIndicator = item.__ecIndicator;
            var axisLabel;
            var vector;
            var style;
            var newStyle;
K
kener 已提交
124 125
            var splitNumber = this.deepQuery(this._queryTarget, 'splitNumber');
            var center = this.getCenter(index);
K
kener 已提交
126 127 128 129
            var vector;
            var value;
            var text;
            var theta;
K
kener 已提交
130
            // var startAngle = this.deepQuery(this._queryTarget, 'startAngle');
K
kener 已提交
131
            var offset;
K
kener 已提交
132
            var precision = this.deepQuery(this._queryTarget, 'precision');
K
kener 已提交
133 134

            for (var i = 0; i < indicator.length; i ++) {
K
kener 已提交
135 136
                axisLabel = this.deepQuery(
                    [indicator[i], item, this.option], 'axisLabel'
K
kener 已提交
137 138
                );

K
kener 已提交
139 140
                if (axisLabel.show) {
                    style = {};
K
kener 已提交
141
                    style.textFont = this.getFont();
K
kener 已提交
142 143 144
                    //Todo: bug fix
                    style = zrUtil.merge(style, axisLabel);
                    style.lineWidth = style.width;
K
kener 已提交
145

K
kener 已提交
146 147 148 149 150 151 152 153 154 155 156 157
                    vector = __ecIndicator[i].vector;
                    value = __ecIndicator[i].value;
                    theta = i / indicator.length * 2 * Math.PI;
                    offset = axisLabel.offset || 10;

                    for (var j = 1 ; j <= splitNumber; j ++) {
                        newStyle = zrUtil.merge({}, style);
                        text = 
                            j * (value.max - value.min) / splitNumber
                                + value.min;
                        if (precision) {
                            text  = text.toFixed(precision);
K
kener 已提交
158
                        }
K
kener 已提交
159
                        newStyle.text = this.numAddCommas(text);
K
kener 已提交
160 161 162 163 164
                        newStyle.x = j * vector[0] / splitNumber 
                                     + Math.cos(theta) * offset + center[0];
                        newStyle.y = j * vector[1] / splitNumber
                                     + Math.sin(theta) * offset + center[1];

K
kener 已提交
165 166
                        this.shapeList.push(new TextShape({
                            zlevel : this._zlevelBase,
K
kener 已提交
167 168 169 170
                            style : newStyle,
                            draggable : false,
                            hoverable : false
                        }));
K
kener 已提交
171 172 173
                    }
                }
            }
K
kener 已提交
174
        },
K
kener 已提交
175

K
kener 已提交
176 177 178 179
        /**
         * 绘制坐标头的文字
         * @param {number} polar的index
         */
K
kener 已提交
180 181
        _buildText  : function (index) {
            var item = this.polar[index];
K
kener 已提交
182 183
            var __ecIndicator = item.__ecIndicator;
            var vector;
K
kener 已提交
184 185
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
            var center = this.getCenter(index);
K
kener 已提交
186 187 188 189 190 191 192 193 194 195
            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 ++) {
K
kener 已提交
196 197
                name = this.deepQuery(
                    [indicator[i], item, this.option], 'name'
K
kener 已提交
198
                );
K
kener 已提交
199

K
kener 已提交
200 201 202
                if (!name.show) {
                    continue;
                } 
K
kener 已提交
203 204
                textStyle = this.deepQuery(
                    [name, item, this.option], 
K
kener 已提交
205 206
                    'textStyle'
                );
K
kener 已提交
207

K
kener 已提交
208
                style = {};
K
kener 已提交
209

K
kener 已提交
210
                style.textFont = this.getFont(textStyle);
K
kener 已提交
211 212 213 214
                style.color = textStyle.color;
                
                if (typeof name.formatter == 'function') {
                    style.text = name.formatter(indicator[i].text, i);
K
kener 已提交
215
                }
K
kener 已提交
216 217 218 219 220 221 222
                else if (typeof name.formatter == 'string'){
                    style.text = name.formatter.replace(
                        '{value}', indicator[i].text
                    );
                }
                else {
                    style.text = indicator[i].text;
K
kener 已提交
223 224
                }
                
K
kener 已提交
225
                vector = __ecIndicator[i].vector;
K
kener 已提交
226

K
kener 已提交
227 228 229 230 231 232 233 234 235
                if (Math.round(vector[0]) > 0) {
                    textAlign = 'left';
                }
                else if (Math.round(vector[0]) < 0) {
                    textAlign = 'right';
                }
                else {
                    textAlign = 'center';
                }
K
kener 已提交
236

K
kener 已提交
237
                if (!name.margin) {
K
kener 已提交
238
                    vector = this._mapVector(vector, center, 1.2);
K
kener 已提交
239
                }
K
kener 已提交
240 241 242 243
                else {
                    margin = name.margin;
                    x = vector[0] > 0 ? margin : - margin;
                    y = vector[1] > 0 ? margin : - margin;
K
kener 已提交
244

K
kener 已提交
245 246
                    x = vector[0] === 0 ? 0 : x;
                    y = vector[1] === 0 ? 0 : y;
K
kener 已提交
247
                    vector = this._mapVector(vector, center, 1); 
K
kener 已提交
248
                }
K
kener 已提交
249 250 251 252 253 254 255 256 257 258 259 260
                
                
                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]
                    ];
                }
K
kener 已提交
261 262 263
                else {
                    rotation = [0, 0, 0];
                }
K
kener 已提交
264
                
K
kener 已提交
265 266
                this.shapeList.push(new TextShape({
                    zlevel : this._zlevelBase,
K
kener 已提交
267 268 269 270 271
                    style : style,
                    draggable : false,
                    hoverable : false,
                    rotation : rotation
                }));
K
kener 已提交
272
            }
K
kener 已提交
273
        },
K
kener 已提交
274

K
kener 已提交
275 276 277 278 279
        /**
         * 添加一个隐形的盒子 当做drop的容器 暴露给外部的图形类使用
         * @param {number} polar的index
         * @return {Object} 添加的盒子图形 
         */
K
kener 已提交
280
        getDropBox : function (index) {
K
kener 已提交
281
            var index = index || 0;
K
kener 已提交
282 283
            var item = this.polar[index];
            var center = this.getCenter(index);
K
kener 已提交
284 285 286 287 288 289 290 291
            var __ecIndicator = item.__ecIndicator;
            var len = __ecIndicator.length;
            var pointList = [];
            var vector;
            var shape;

            for (var i = 0; i < len; i ++) {
                vector = __ecIndicator[i].vector;
K
kener 已提交
292
                pointList.push(this._mapVector(vector, center, 1.2));
K
kener 已提交
293
            }
K
kener 已提交
294
            
K
kener 已提交
295
            shape = this._getShape(
K
kener 已提交
296 297 298
                pointList, 'fill', 'rgba(0,0,0,0)', '', 1
            );
            return shape;
K
kener 已提交
299
        },
K
kener 已提交
300

K
kener 已提交
301 302 303 304 305 306 307 308 309 310
        /**
         * 绘制蜘蛛网的正n变形
         *
         * @param {Array<Object>} 指标数组
         * @param {number} 分割线数量
         * @param {Array<number>} 中点坐标
         * @param {Object} 分割区域对象
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         */ 
K
kener 已提交
311
        _addArea : function (
K
kener 已提交
312 313 314 315 316 317 318 319 320 321
            __ecIndicator, splitNumber, center,
            splitArea, strokeColor, lineWidth, show
        ) {
            var shape;
            var scale;
            var scale1;
            var pointList;

            for (var i = 0; i < splitNumber ; i ++ ) {
                scale = (splitNumber - i) / splitNumber;
K
kener 已提交
322
                pointList = this._getPointList(__ecIndicator, scale, center);
K
kener 已提交
323
                
K
kener 已提交
324
                if (show) {
K
kener 已提交
325
                    shape = this._getShape(
K
kener 已提交
326
                        pointList, 'stroke', '', strokeColor, lineWidth
K
kener 已提交
327
                    );
K
kener 已提交
328
                    this.shapeList.push(shape);
K
kener 已提交
329
                }
K
kener 已提交
330 331 332

                if (splitArea.show) {
                    scale1 = (splitNumber - i - 1) / splitNumber;
K
kener 已提交
333
                    this._addSplitArea(
K
kener 已提交
334 335 336
                        __ecIndicator, splitArea, scale, scale1, center, i
                    ); 
                }  
K
kener 已提交
337
            }
K
kener 已提交
338
        },
K
kener 已提交
339

K
kener 已提交
340 341 342 343 344 345 346 347
        /**
         * 获取需要绘制的多边形的点集
         * @param {Object} serie的指标参数
         * @param {number} 缩小的系数
         * @param {Array<number>} 中点坐标
         *
         * @return {Array<Array<number>>} 返回绘制的点集
         */
K
kener 已提交
348
        _getPointList : function (__ecIndicator, scale, center) {
K
kener 已提交
349 350 351 352 353 354 355
            var pointList = [];
            var len = __ecIndicator.length;
            var vector;

            for (var i = 0 ; i < len ; i ++ ) {
                vector = __ecIndicator[i].vector;
                
K
kener 已提交
356
                pointList.push(this._mapVector(vector, center, scale));
K
kener 已提交
357
            }
K
kener 已提交
358
            return pointList;
K
kener 已提交
359
        },
K
kener 已提交
360 361 362 363 364 365 366 367 368 369 370 371

        /**
         * 获取绘制的图形
         * @param {Array<Array<number>>} 绘制的点集
         * @param {string} 绘制方式 stroke | fill | both 描边 | 填充 | 描边 + 填充
         * @param {string} 颜色
         * @param {string} 描边颜色
         * @param {number} 线条宽度
         * @param {boolean=} hoverable
         * @param {boolean=} draggable
         * @return {Object} 绘制的图形对象
         */ 
K
kener 已提交
372
        _getShape : function (
K
kener 已提交
373 374 375 376
            pointList, brushType, color, strokeColor, lineWidth, 
            hoverable, draggable
        ) {
            return new PolygonShape({
K
kener 已提交
377
                zlevel : this._zlevelBase,
K
kener 已提交
378 379 380 381 382 383 384 385 386 387
                style : {
                    pointList   : pointList,
                    brushType   : brushType,
                    color       : color,
                    strokeColor : strokeColor,
                    lineWidth   : lineWidth
                },
                hoverable : hoverable || false,
                draggable : draggable || false
            });
K
kener 已提交
388
        },
K
kener 已提交
389

K
kener 已提交
390 391 392
        /**
         * 绘制填充区域
         */
K
kener 已提交
393
        _addSplitArea : function (
K
kener 已提交
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
            __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;
            
            if (typeof colorArr == 'string') {
                colorArr = [colorArr];
K
kener 已提交
409
            }
K
kener 已提交
410 411
            colorLen = colorArr.length;
            color = colorArr[ colorInd % colorLen];
K
kener 已提交
412

K
kener 已提交
413 414 415 416 417
            for (var i = 0; i < indLen ; i ++) {
                pointList = [];
                vector = __ecIndicator[i].vector;
                vector1 = __ecIndicator[(i + 1) % indLen].vector;

K
kener 已提交
418 419 420 421
                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));
K
kener 已提交
422

K
kener 已提交
423
                shape = this._getShape(
K
kener 已提交
424 425
                    pointList, 'fill', color, '', 1
                );
K
kener 已提交
426
                this.shapeList.push(shape);
K
kener 已提交
427
            }
K
kener 已提交
428
            
K
kener 已提交
429
        },
K
kener 已提交
430 431 432 433 434 435 436 437 438 439

        /**
         * 转换坐标
         *
         * @param {Array<number>} 原始坐标
         * @param {Array<number>} 中点坐标
         * @param {number} 缩小的倍数
         *
         * @return {Array<number>} 转换后的坐标
         */
K
kener 已提交
440
        _mapVector : function (vector, center, scale) {
K
kener 已提交
441 442 443 444
            return [
                vector[0] * scale + center[0],
                vector[1] * scale + center[1]
            ];
K
kener 已提交
445
        },
K
kener 已提交
446 447 448 449 450

        /**
         * 获取中心点位置 暴露给外部图形类使用
         * @param {number} polar的index
         */
K
kener 已提交
451
        getCenter : function (index) {
K
kener 已提交
452
            var index = index || 0;
K
kener 已提交
453 454
            return this.parseCenter(this.zr, this.polar[index].center);
        },
K
kener 已提交
455

K
kener 已提交
456 457 458 459 460 461 462 463 464 465
        /**
         * 绘制从中点出发的线
         * 
         * @param {Array<Object>} 指标对象
         * @param {Array<number>} 中点坐标
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         * @param {string} 线条绘制类型 
         *              solid | dotted | dashed 实线 | 点线 | 虚线
         */
K
kener 已提交
466
        _addLine : function (
K
kener 已提交
467 468 469 470 471 472 473 474 475 476 477 478
            __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;
K
kener 已提交
479
                line = this._getLine(
K
kener 已提交
480 481 482 483 484
                    center[0], center[1],
                    vector[0] + center[0], 
                    vector[1] + center[1],
                    strokeColor, lineWidth, lineType
                );
K
kener 已提交
485
                this.shapeList.push(line);
K
kener 已提交
486
            }
K
kener 已提交
487
        },
K
kener 已提交
488

K
kener 已提交
489 490 491 492 493 494 495 496 497 498 499 500
        /** 
         * 获取线条对象
         * @param {number} 出发点横坐标
         * @param {number} 出发点纵坐标
         * @param {number} 终点横坐标
         * @param {number} 终点纵坐标
         * @param {string} 线条颜色
         * @param {number} 线条宽度
         * @param {string} 线条类型
         *
         * @return {Object} 线条对象
         */
K
kener 已提交
501
        _getLine : function (
K
kener 已提交
502 503 504
            xStart, yStart, xEnd, yEnd, strokeColor, lineWidth, lineType
        ) {
            return new LineShape({
K
kener 已提交
505
                zlevel : this._zlevelBase,
K
kener 已提交
506 507 508 509 510 511 512 513 514 515 516
                style : {
                    xStart : xStart,
                    yStart : yStart,
                    xEnd   : xEnd,
                    yEnd   : yEnd,
                    strokeColor : strokeColor,
                    lineWidth   : lineWidth,
                    lineType    : lineType
                },
                hoverable : false
            });
K
kener 已提交
517
        },
K
kener 已提交
518

K
kener 已提交
519 520 521 522
        /**
         * 调整指标的值,当indicator中存在max时设置为固定值
         * @param {number} polar的index
         */
K
kener 已提交
523 524 525
        _adjustIndicatorValue : function (index) {
            var item = this.polar[index];
            var indicator = this.deepQuery(this._queryTarget, 'indicator');
K
kener 已提交
526 527 528 529 530
            var len = indicator.length;
            var __ecIndicator = item.__ecIndicator;
            var value;
            var max;
            var min;
K
kener 已提交
531
            var data = this._getSeriesData(index);
K
kener 已提交
532 533
            var splitNumber = item.splitNumber;

K
kener 已提交
534 535 536 537
            var boundaryGap = this.deepQuery(this._queryTarget, 'boundaryGap');
            var precision = this.deepQuery(this._queryTarget, 'precision');
            var power = this.deepQuery(this._queryTarget, 'power');
            var scale = this.deepQuery(this._queryTarget, 'scale');
K
kener 已提交
538 539 540 541 542 543 544 545 546

            for (var i = 0; i < len ; i ++ ) {
                if (typeof indicator[i].max == 'number') {
                    max = indicator[i].max;
                    min = indicator[i].min || 0;
                    value = {
                        max : max,
                        min : min
                    };
K
kener 已提交
547
                }
K
kener 已提交
548
                else {
K
kener 已提交
549
                    value = this._findValue(
K
kener 已提交
550 551 552 553 554 555
                        data, i, splitNumber,
                        boundaryGap, precision, power, scale
                    );
                }

                __ecIndicator[i].value = value;
K
kener 已提交
556
            }
K
kener 已提交
557
        },
K
kener 已提交
558

K
kener 已提交
559 560 561 562 563
        /**
         * 将series中的数据拿出来,如果没有polarIndex属性,默认为零
         * @param {number} polar 的index
         * @param {Array<Object>} 需要处理的数据
         */
K
kener 已提交
564
        _getSeriesData : function (index) {
K
kener 已提交
565 566 567
            var data = [];
            var serie;
            var serieData;
K
kener 已提交
568
            var legend = this.component.legend;
K
kener 已提交
569

K
kener 已提交
570 571
            for (var i = 0; i < this.series.length; i ++) {
                serie = this.series[i];
K
kener 已提交
572 573 574 575 576
                if (serie.type != ecConfig.CHART_TYPE_RADAR) {
                    continue;
                }
                serieData = serie.data || [];
                for (var j = 0; j < serieData.length; j ++) {
K
kener 已提交
577 578
                    polarIndex = this.deepQuery(
                        [serieData[j], serie, this.option], 'polarIndex'
K
kener 已提交
579 580 581 582 583
                    ) || 0;
                    if (polarIndex == index
                        && (!legend || legend.isSelected(serieData[j].name))
                    ) {
                        data.push(serieData[j]);
K
kener 已提交
584 585 586
                    }
                }
            }
K
kener 已提交
587
            return data;
K
kener 已提交
588
        },
K
kener 已提交
589

K
kener 已提交
590 591 592 593 594 595 596 597 598 599 600 601 602
        /**
         * 查找指标合适的值
         *
         * 如果只有一组数据以数据中的最大值作为最大值 0为最小值
         * 如果是多组,使用同一维度的进行比较 选出最大值最小值 
         * 对它们进行处理  
         * @param {Object} serie 的 data
         * @param {number} 指标的序号
         * @param {boolean} boundaryGap 两端留白
         * @param {number} precision 小数精度
         * @param {number} power 整数精度
         * @return {Object} 指标的最大值最小值
         */ 
K
kener 已提交
603
        _findValue : function (
K
kener 已提交
604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
            data, index, splitNumber, boundaryGap, precision, power, scale
        ) {
            var max;
            var min;
            var value;
            var delta;
            var str;
            var len = 0;
            var max0;
            var min0;
            var one;

            if (!data || data.length === 0) {
                return;
            }
K
kener 已提交
619

K
kener 已提交
620 621 622 623
            function _compare(item) {         
                (item > max || max === undefined) && (max = item);
                (item < min || min === undefined) && (min = item);
            }
K
kener 已提交
624

K
kener 已提交
625 626 627 628 629 630 631
            if (data.length == 1) {
                min = 0;
            }
            if (data.length != 1) {
                for (var i = 0; i < data.length; i ++) {
                    value = data[i].value[index];
                    _compare(value);
K
kener 已提交
632
                }
K
kener 已提交
633 634 635 636 637
            }
            else {
                one = data[0];
                for (var i = 0; i < one.value.length; i ++) {
                    _compare(one.value[i]);
K
kener 已提交
638
                }
K
kener 已提交
639
            }
K
kener 已提交
640

K
kener 已提交
641 642
            if (data.length != 1) {
                if (scale) {
K
kener 已提交
643
                    delta = this._getDelta(
K
kener 已提交
644 645
                        max, min, splitNumber, precision, power
                    );
K
kener 已提交
646

K
kener 已提交
647 648 649 650 651 652 653
                    if (delta >= 1) {
                        min = Math.floor(min / delta) * delta - delta;
                    }
                    else if (delta === 0) {
                        if (max > 0) {
                            min0 = 0;
                            max0 = 2 * max;
K
kener 已提交
654
                        }
K
kener 已提交
655 656 657
                        else if (max === 0) {
                            min0 = 0;
                            max0 = 100;
K
kener 已提交
658 659
                        }
                        else {
K
kener 已提交
660 661
                            max0 = 0;
                            min0 = 2 * min;
K
kener 已提交
662 663
                        }

K
kener 已提交
664 665 666 667
                        return {
                            max : max0,
                            min : min0
                        };
K
kener 已提交
668 669
                    }
                    else {
K
kener 已提交
670 671 672 673 674
                        str = (delta + '').split('.')[1];
                        len = str.length;
                        min = Math.floor(
                                min * Math.pow(10, len)) / Math.pow(10, len
                              ) - delta;
K
kener 已提交
675 676
                    }

K
kener 已提交
677 678 679 680 681 682 683 684 685
                    if (Math.abs(min) <= delta) {
                        min = 0;
                    }
                    
                    max = min + Math.floor(delta * Math.pow(10, len) 
                        * (splitNumber + 1)) / Math.pow(10, len) ;
                }
                else {
                    min = min > 0 ? 0 : min;
K
kener 已提交
686
                }
K
kener 已提交
687
            }
K
kener 已提交
688

K
kener 已提交
689 690 691
            if (boundaryGap) {
                max = max > 0 ? max * 1.2 : max * 0.8;
                min = min > 0 ? min * 0.8 : min * 1.2;
K
kener 已提交
692 693
            }

K
kener 已提交
694 695 696 697
            return {
                max : max,
                min : min
            };
K
kener 已提交
698
        },
K
kener 已提交
699 700 701 702 703 704 705 706 707

        /**
         * 获取最大值与最小值中间比较合适的差值
         * @param {number} max;
         * @param {number} min
         * @param {number} precision 小数精度
         * @param {number} power 整数精度
         * @return {number} delta
         */
K
kener 已提交
708
        _getDelta : function (max , min, splitNumber, precision, power) {
K
kener 已提交
709 710 711 712 713 714 715 716 717 718
            var delta = (max - min) / splitNumber;
            var str;
            var n;

            if (delta > 1) {
                if (!power) {
                    str = (delta + '').split('.')[0];
                    n = str.length;
                    if (str.charAt(0) >= 5) {
                        return Math.pow(10, n);
K
kener 已提交
719 720
                    }
                    else {
K
kener 已提交
721
                        return (str.charAt(0) - 0 + 1 ) * Math.pow(10, n - 1);
K
kener 已提交
722 723
                    }
                }
K
kener 已提交
724
                else {
K
kener 已提交
725 726 727 728
                    delta = Math.ceil(delta);
                    if (delta % power > 0) {
                        return (Math.ceil(delta / power) + 1) * power;
                    }
K
kener 已提交
729
                    else {
K
kener 已提交
730
                        return delta;
K
kener 已提交
731 732 733
                    }
                }
            }
K
kener 已提交
734 735 736 737 738 739 740 741 742 743 744 745 746
            else if (delta == 1) {
                return 1;
            }
            else if (delta === 0) {
                return 0;
            } 
            else {
                if (!precision) {
                    str = (delta + '').split('.')[1];
                    n = 0;
                    while (str[n] == '0') {
                        n ++ ;
                    }
K
kener 已提交
747

K
kener 已提交
748 749 750 751 752 753 754 755 756
                    if (str[n] >= 5) {
                        return '0.' + str.substring(0, n + 1) - 0 
                            + 1 / Math.pow(10, n);
                    }
                    else {
                        return '0.' + str.substring(0, n + 1) - 0 
                            + 1 / Math.pow(10, n + 1);
                    }
                } 
K
kener 已提交
757
                else {
K
kener 已提交
758 759
                    return Math.ceil(delta * Math.pow(10, precision)) 
                        / Math.pow(10, precision);
K
kener 已提交
760 761
                }
            }
K
kener 已提交
762
        },
K
kener 已提交
763

K
kener 已提交
764 765 766 767 768 769 770
        /**
         * 获取每个指标上某个value对应的坐标
         * @param {number} polarIndex
         * @param {number} indicatorIndex 
         * @param {number} value
         * @return {Array<number>} 对应坐标
         */
K
kener 已提交
771
        getVector : function (polarIndex, indicatorIndex, value) {
K
kener 已提交
772 773
            polarIndex = polarIndex || 0;
            indicatorIndex = indicatorIndex || 0;
K
kener 已提交
774
            var __ecIndicator = this.polar[polarIndex].__ecIndicator;
K
kener 已提交
775 776 777

            if (indicatorIndex >= __ecIndicator.length) {
                return ;
K
kener 已提交
778 779
            }

K
kener 已提交
780 781
            var indicator = this.polar[polarIndex].__ecIndicator[indicatorIndex];
            var center = this.getCenter(polarIndex);
K
kener 已提交
782 783 784 785
            var vector = indicator.vector;
            var max = indicator.value.max;
            var min = indicator.value.min;
            var alpha;
K
kener 已提交
786

K
kener 已提交
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
            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;
            }
            
K
kener 已提交
810 811
            return this._mapVector(vector, center, alpha);
        },
K
kener 已提交
812

K
kener 已提交
813 814 815 816 817
        /**
         * 判断一个点是否在网内
         * @param {Array<number>} 坐标
         * @return {number} 返回polarindex  返回-1表示不在任何polar
         */ 
K
kener 已提交
818 819
        isInside : function (vector) {
            var polar = this.getNearestIndex(vector);
K
kener 已提交
820

K
kener 已提交
821 822
            if (polar) {
                return polar.polarIndex;
K
kener 已提交
823
            }
K
kener 已提交
824
            return -1;
K
kener 已提交
825
        },
K
kener 已提交
826 827 828 829 830 831 832 833

        /**
         * 如果一个点在网内,返回离它最近的数据轴的index
         * @param {Array<number>} 坐标
         * @return {Object} | false
         *      polarIndex 
         *      valueIndex
         */
K
kener 已提交
834
        getNearestIndex : function (vector) {
K
kener 已提交
835 836 837 838 839 840 841 842 843
            var item;
            var center;
            var radius;
            var polarVector;
            var startAngle;
            var indicator;
            var len;
            var angle;
            var finalAngle;
K
kener 已提交
844 845 846 847
            var zrSize = Math.min(this.zr.getWidth(), this.zr.getHeight()) / 2;
            for (var i = 0 ; i < this.polar.length; i ++) {
                item = this.polar[i];
                center = this.getCenter(i);
K
kener 已提交
848 849 850 851 852 853
                if (vector[0] == center[0] && vector[1] == center[1]) {
                    return {
                        polarIndex : i,
                        valueIndex : 0
                    };
                }
K
kener 已提交
854
                radius = this.parsePercent(item.radius, zrSize);
K
kener 已提交
855 856 857 858 859 860 861 862 863 864 865 866 867 868
                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;
                }
K
kener 已提交
869

K
kener 已提交
870

K
kener 已提交
871 872 873 874 875 876 877 878 879 880 881 882 883
                // 减去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
                    };
K
kener 已提交
884
                }
K
kener 已提交
885
            }
K
kener 已提交
886
        },
K
kener 已提交
887

K
kener 已提交
888 889 890 891 892
        /**
         * 获取指标信息 
         * @param {number} polarIndex
         * @return {Array<Object>} indicator
         */
K
kener 已提交
893
        getIndicator : function (index) {
K
kener 已提交
894
            var index = index || 0;
K
kener 已提交
895 896
            return this.polar[index].indicator;
        },
K
kener 已提交
897 898 899 900

         /**
         * 刷新
         */
K
kener 已提交
901
        refresh : function (newOption) {
K
kener 已提交
902 903
            if (newOption) {
                this.option = newOption;
K
kener 已提交
904 905
                this.polar = this.option.polar;
                this.series = this.option.series;
K
kener 已提交
906
            }
K
kener 已提交
907 908
            this.clear();
            this._buildShape();
K
kener 已提交
909
        }
K
kener 已提交
910 911 912 913
    };
    
    zrUtil.inherits(Polar, Base);
    
K
kener 已提交
914 915 916 917
    require('../component').define('polar', Polar);
 
    return Polar;
});