line.js 43.1 KB
Newer Older
K
kener 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
/**
 * echarts图表类:折线图
 *
 * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
 *
 */
define(function(require) {
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} series 数据
     * @param {Object} component 组件
     */
    function Line(messageCenter, zr, option, component){
        // 基类装饰
        var ComponentBase = require('../component/base');
        ComponentBase.call(this, zr);
        // 可计算特性装饰
        var CalculableBase = require('./calculableBase');
        CalculableBase.call(this, zr, option);

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

        var zrColor = require('zrender/tool/color');

        var self = this;
        self.type = ecConfig.CHART_TYPE_LINE;

        var series;                 // 共享数据源,不要修改跟自己无关的项

        var _zlevelBase = self.getZlevelBase();

K
kener 已提交
36
        var finalPLMap = {}; // 完成的point list(PL)
K
kener 已提交
37
        var _sIndex2ColorMap = {};  // series默认颜色索引,seriesIndex索引到color
K
kener 已提交
38
        var _symbol = [
K
kener 已提交
39 40 41 42 43
              'circle', 'rectangle', 'triangle', 'diamond',
              'emptyCircle', 'emptyRectangle', 'emptyTriangle', 'emptyDiamond'
            ];
        var _sIndex2ShapeMap = {};  // series拐点图形类型,seriesIndex索引到shape type

44 45 46 47
        require('zrender/shape').get('icon').define(
            'legendLineIcon', legendLineIcon
        );
        
K
kener 已提交
48
        function _buildShape() {
K
kener 已提交
49
            finalPLMap = {};
K
kener 已提交
50 51 52 53 54 55 56 57 58 59 60 61 62 63
            self.selectedMap = {};

            // 水平垂直双向series索引 ,position索引到seriesIndex
            var _position2sIndexMap = {
                top : [],
                bottom : [],
                left : [],
                right : []
            };
            var xAxisIndex;
            var yAxisIndex;
            var xAxis;
            var yAxis;
            for (var i = 0, l = series.length; i < l; i++) {
K
kener 已提交
64
                if (series[i].type == self.type) {
K
kener 已提交
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
                    series[i] = self.reformOption(series[i]);
                    xAxisIndex = series[i].xAxisIndex;
                    yAxisIndex = series[i].yAxisIndex;
                    xAxis = component.xAxis.getAxis(xAxisIndex);
                    yAxis = component.yAxis.getAxis(yAxisIndex);
                    if (xAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY
                    ) {
                        _position2sIndexMap[xAxis.getPosition()].push(i);
                    }
                    else if (yAxis.type == ecConfig.COMPONENT_TYPE_AXIS_CATEGORY
                    ) {
                        _position2sIndexMap[yAxis.getPosition()].push(i);
                    }
                }
            }
            //console.log(_position2sIndexMap)
            for (var position in _position2sIndexMap) {
                if (_position2sIndexMap[position].length > 0) {
                    _buildSinglePosition(
                        position, _position2sIndexMap[position]
                    );
                }
            }

            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                self.shapeList[i].id = zr.newShapeId(self.type);
                zr.addShape(self.shapeList[i]);
            }
        }

        /**
         * 构建单个方向上的折线图
         *
         * @param {number} seriesIndex 系列索引
         */
        function _buildSinglePosition(position, seriesArray) {
            var mapData = _mapData(seriesArray);
            var locationMap = mapData.locationMap;
            var maxDataLength = mapData.maxDataLength;

            if (maxDataLength === 0 || locationMap.length === 0) {
                return;
            }

            switch (position) {
                case 'bottom' :
                case 'top' :
                    _buildHorizontal(maxDataLength, locationMap);
                    break;
                case 'left' :
                case 'right' :
                    _buildVertical(maxDataLength, locationMap);
                    break;
            }
        }

        /**
         * 数据整形
         * 数组位置映射到系列索引
         */
        function _mapData(seriesArray) {
            var serie;                              // 临时映射变量
            var dataIndex = 0;                      // 堆叠数据所在位置映射
            var stackMap = {};                      // 堆叠数据位置映射,堆叠组在二维中的第几项
            var magicStackKey = '__kener__stack__'; // 堆叠命名,非堆叠数据安单一堆叠处理
            var stackKey;                           // 临时映射变量
            var serieName;                          // 临时映射变量
            var legend = component.legend;
            var locationMap = [];                   // 需要返回的东西:数组位置映射到系列索引
            var maxDataLength = 0;                  // 需要返回的东西:最大数据长度
135
            var iconShape;
K
kener 已提交
136 137 138 139
            // 计算需要显示的个数和分配位置并记在下面这个结构里
            for (var i = 0, l = seriesArray.length; i < l; i++) {
                serie = series[seriesArray[i]];
                serieName = serie.name;
140 141 142 143 144 145
                
                _sIndex2ShapeMap[seriesArray[i]]
                    = _sIndex2ShapeMap[seriesArray[i]]
                      || self.deepQuery([serie],'symbol')
                      || _symbol[i % _symbol.length];
                      
K
kener 已提交
146 147
                if (legend){
                    self.selectedMap[serieName] = legend.isSelected(serieName);
148
                    
K
kener 已提交
149 150
                    _sIndex2ColorMap[seriesArray[i]]
                        = legend.getColor(serieName);
151 152 153 154 155 156 157 158 159 160
                        
                    iconShape = legend.getItemShape(serieName);
                    if (iconShape) {
                        // 回调legend,换一个更形象的icon
                        iconShape.shape = 'icon';
                        iconShape.style.iconType = 'legendLineIcon';
                        iconShape.style.symbol = 
                            _sIndex2ShapeMap[seriesArray[i]];
                        legend.setItemShape(serieName, iconShape);
                    }
K
kener 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
                } else {
                    self.selectedMap[serieName] = true;
                    _sIndex2ColorMap[seriesArray[i]]
                        = zr.getColor(seriesArray[i]);
                }

                if (self.selectedMap[serieName]) {
                    stackKey = serie.stack || (magicStackKey + seriesArray[i]);
                    if (typeof stackMap[stackKey] == 'undefined') {
                        stackMap[stackKey] = dataIndex;
                        locationMap[dataIndex] = [seriesArray[i]];
                        dataIndex++;
                    }
                    else {
                        // 已经分配了位置就推进去就行
                        locationMap[stackMap[stackKey]].push(seriesArray[i]);
                    }
                }
                // 兼职帮算一下最大长度
                maxDataLength = Math.max(maxDataLength, serie.data.length);
            }

            /* 调试输出
            var s = '';
            for (var i = 0, l = maxDataLength; i < l; i++) {
                s = '[';
                for (var j = 0, k = locationMap.length; j < k; j++) {
                    s +='['
                    for (var m = 0, n = locationMap[j].length - 1; m < n; m++) {
                        s += series[locationMap[j][m]].data[i] + ','
                    }
                    s += series[locationMap[j][locationMap[j].length - 1]]
                         .data[i];
                    s += ']'
                }
                s += ']';
                console.log(s);
            }
            console.log(locationMap)
            */

            return {
                locationMap : locationMap,
                maxDataLength : maxDataLength
            };
        }

        /**
         * 构建类目轴为水平方向的折线图系列
         */
        function _buildHorizontal(maxDataLength, locationMap) {
            // 确定类目轴和数值轴,同一方向随便找一个即可
            var seriesIndex = locationMap[0][0];
            var serie = series[seriesIndex];
            var xAxisIndex = serie.xAxisIndex;
            var categoryAxis = component.xAxis.getAxis(xAxisIndex);
            var yAxisIndex; // 数值轴各异
            var valueAxis;  // 数值轴各异

            var x;
            var y;
            var lastYP; // 正向堆叠处理
            var baseYP;
            var lastYN; // 负向堆叠处理
            var baseYN;
K
kener 已提交
226
            //var finalPLMap = {}; // 完成的point list(PL)
K
kener 已提交
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
            var curPLMap = {};   // 正在记录的point list(PL)
            var data;
            var value;
            for (var i = 0, l = maxDataLength; i < l; i++) {
                if (typeof categoryAxis.getNameByIndex(i) == 'undefined') {
                    // 系列数据超出类目轴长度
                    break;
                }
                x = categoryAxis.getCoordByIndex(i);
                for (var j = 0, k = locationMap.length; j < k; j++) {
                    // 堆叠数据用第一条valueAxis
                    yAxisIndex = series[locationMap[j][0]].yAxisIndex || 0;
                    valueAxis = component.yAxis.getAxis(yAxisIndex);
                    baseYP = lastYP = baseYN = lastYN = valueAxis.getCoord(0);
                    for (var m = 0, n = locationMap[j].length; m < n; m++) {
                        seriesIndex = locationMap[j][m];
                        serie = series[seriesIndex];
                        data = serie.data[i];
                        value = typeof data != 'undefined'
                                ? (typeof data.value != 'undefined'
                                  ? data.value
                                  : data)
                                : '-';
                        curPLMap[seriesIndex] = curPLMap[seriesIndex] || [];
                        if (value == '-') {
                            // 空数据则把正在记录的curPLMap添加到finalPLMap中
                            if (curPLMap[seriesIndex].length > 0) {
                                finalPLMap[seriesIndex] =
                                    finalPLMap[seriesIndex] || [];

                                finalPLMap[seriesIndex].push(
                                    curPLMap[seriesIndex]
                                );

                                curPLMap[seriesIndex] = [];
                            }
                            continue;
                        }
                        y = valueAxis.getCoord(value);
                        if (value >= 0) {
                            // 正向堆叠
                            lastYP -= (baseYP - y);
                            y = lastYP;
                        }
                        else if (value < 0){
                            // 负向堆叠
                            lastYN += y - baseYN;
                            y = lastYN;
                        }
                        curPLMap[seriesIndex].push(
                            [x, y, i, categoryAxis.getNameByIndex(i), x, baseYP]
                        );
                    }
                }
                // 补充空数据的拖拽提示
                lastYP = component.grid.getY();
K
kener 已提交
283
                var symbolSize;
K
kener 已提交
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
                for (var j = 0, k = locationMap.length; j < k; j++) {
                    for (var m = 0, n = locationMap[j].length; m < n; m++) {
                        seriesIndex = locationMap[j][m];
                        serie = series[seriesIndex];
                        data = serie.data[i];
                        value = typeof data != 'undefined'
                                ? (typeof data.value != 'undefined'
                                  ? data.value
                                  : data)
                                : '-';
                        if (value != '-') {
                            // 只关心空数据
                            continue;
                        }
                        if (self.deepQuery(
                                [data, serie, option], 'calculable'
                            )
                        ) {
K
kener 已提交
302
                            symbolSize = self.deepQuery(
K
kener 已提交
303
                                [data, serie],
K
kener 已提交
304
                                'symbolSize'
K
kener 已提交
305
                            );
K
kener 已提交
306
                            lastYP += symbolSize * 2 + 5;
K
kener 已提交
307 308 309
                            y = lastYP;
                            self.shapeList.push(_getCalculableItem(
                                seriesIndex, i, categoryAxis.getNameByIndex(i),
K
kener 已提交
310
                                x, y, 'horizontal'
K
kener 已提交
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
                            ));
                        }
                    }
                }
            }

            // 把剩余未完成的curPLMap全部添加到finalPLMap中
            for (var sId in curPLMap) {
                if (curPLMap[sId].length > 0) {
                    finalPLMap[sId] = finalPLMap[sId] || [];
                    finalPLMap[sId].push(curPLMap[sId]);
                    curPLMap[sId] = [];
                }
            }
            _buildBorkenLine(finalPLMap, categoryAxis, 'horizontal');
        }

        /**
         * 构建类目轴为垂直方向的折线图系列
         */
        function _buildVertical(maxDataLength, locationMap) {
            // 确定类目轴和数值轴,同一方向随便找一个即可
            var seriesIndex = locationMap[0][0];
            var serie = series[seriesIndex];
            var yAxisIndex = serie.yAxisIndex;
            var categoryAxis = component.yAxis.getAxis(yAxisIndex);
            var xAxisIndex; // 数值轴各异
            var valueAxis;  // 数值轴各异

            var x;
            var y;
            var lastXP; // 正向堆叠处理
            var baseXP;
            var lastXN; // 负向堆叠处理
            var baseXN;
K
kener 已提交
346
            //var finalPLMap = {}; // 完成的point list(PL)
K
kener 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
            var curPLMap = {};   // 正在记录的point list(PL)
            var data;
            var value;
            for (var i = 0, l = maxDataLength; i < l; i++) {
                if (typeof categoryAxis.getNameByIndex(i) == 'undefined') {
                    // 系列数据超出类目轴长度
                    break;
                }
                y = categoryAxis.getCoordByIndex(i);
                for (var j = 0, k = locationMap.length; j < k; j++) {
                    // 堆叠数据用第一条valueAxis
                    xAxisIndex = series[locationMap[j][0]].xAxisIndex || 0;
                    valueAxis = component.xAxis.getAxis(xAxisIndex);
                    baseXP = lastXP = baseXN = lastXN = valueAxis.getCoord(0);
                    for (var m = 0, n = locationMap[j].length; m < n; m++) {
                        seriesIndex = locationMap[j][m];
                        serie = series[seriesIndex];
                        data = serie.data[i];
                        value = typeof data != 'undefined'
                                ? (typeof data.value != 'undefined'
                                  ? data.value
                                  : data)
                                : '-';
                        curPLMap[seriesIndex] = curPLMap[seriesIndex] || [];
                        if (value == '-') {
                            // 空数据则把正在记录的curPLMap添加到finalPLMap中
                            if (curPLMap[seriesIndex].length > 0) {
                                finalPLMap[seriesIndex] =
                                    finalPLMap[seriesIndex] || [];

                                finalPLMap[seriesIndex].push(
                                    curPLMap[seriesIndex]
                                );

                                curPLMap[seriesIndex] = [];
                            }
                            continue;
                        }
                        x = valueAxis.getCoord(value);
                        if (value >= 0) {
                            // 正向堆叠
                            lastXP += x - baseXP;
                            x = lastXP;
                        }
                        else if (value < 0){
                            // 负向堆叠
                            lastXN -= baseXN - x;
                            x = lastXN;
                        }
                        curPLMap[seriesIndex].push(
                            [x, y, i, categoryAxis.getNameByIndex(i), baseXP, y]
                        );
                    }
                }
                // 补充空数据的拖拽提示
                lastXP = component.grid.getXend();
K
kener 已提交
403
                var symbolSize;
K
kener 已提交
404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421
                for (var j = 0, k = locationMap.length; j < k; j++) {
                    for (var m = 0, n = locationMap[j].length; m < n; m++) {
                        seriesIndex = locationMap[j][m];
                        serie = series[seriesIndex];
                        data = serie.data[i];
                        value = typeof data != 'undefined'
                                ? (typeof data.value != 'undefined'
                                  ? data.value
                                  : data)
                                : '-';
                        if (value != '-') {
                            // 只关心空数据
                            continue;
                        }
                        if (self.deepQuery(
                                [data, serie, option], 'calculable'
                            )
                        ) {
K
kener 已提交
422
                            symbolSize = self.deepQuery(
K
kener 已提交
423
                                [data, serie],
K
kener 已提交
424
                                'symbolSize'
K
kener 已提交
425
                            );
K
kener 已提交
426
                            lastXP -= symbolSize * 2 + 5;
K
kener 已提交
427 428 429
                            x = lastXP;
                            self.shapeList.push(_getCalculableItem(
                                seriesIndex, i, categoryAxis.getNameByIndex(i),
K
kener 已提交
430
                                x, y, 'vertical'
K
kener 已提交
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
                            ));
                        }
                    }
                }
            }

            // 把剩余未完成的curPLMap全部添加到finalPLMap中
            for (var sId in curPLMap) {
                if (curPLMap[sId].length > 0) {
                    finalPLMap[sId] = finalPLMap[sId] || [];
                    finalPLMap[sId].push(curPLMap[sId]);
                    curPLMap[sId] = [];
                }
            }
            _buildBorkenLine(finalPLMap, categoryAxis, 'vertical');
        }

        /**
         * 生成折线和折线上的拐点
         */
        function _buildBorkenLine(pointList, categoryAxis, orient) {
            var defaultColor;

            // 折线相关
            var lineWidth;
            var lineType;
            var lineColor;
            var normalColor;
            var emphasisColor;

            // 填充相关
            var isFill;
            var fillNormalColor;

            var serie;
            var data;
            var seriesPL;
            var singlePL;

            // 堆叠层叠需求,反顺序构建
            for (var seriesIndex = series.length - 1;
                seriesIndex >= 0;
                seriesIndex--
            ) {
                serie = series[seriesIndex];
                seriesPL = pointList[seriesIndex];
K
kener 已提交
477
                if (serie.type == self.type && typeof seriesPL != 'undefined') {
K
kener 已提交
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
                    defaultColor = _sIndex2ColorMap[seriesIndex];
                    // 多级控制
                    lineWidth = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.width'
                    );
                    lineType = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.type'
                    );
                    lineColor = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.color'
                    );
                    normalColor = self.deepQuery(
                        [serie], 'itemStyle.normal.color'
                    );
                    emphasisColor = self.deepQuery(
                        [serie], 'itemStyle.emphasis.color'
                    );

                    isFill = typeof self.deepQuery(
                        [serie], 'itemStyle.normal.areaStyle'
                    ) != 'undefined';

                    fillNormalColor = self.deepQuery(
                        [serie], 'itemStyle.normal.areaStyle.color'
                    );

                    for (var i = 0, l = seriesPL.length; i < l; i++) {
                        singlePL = seriesPL[i];
                        for (var j = 0, k = singlePL.length; j < k; j++) {
                            data = serie.data[singlePL[j][2]];
K
kener 已提交
508 509 510 511 512 513 514 515 516
                            if (self.deepQuery(
                                    [data, serie], 'showAllSymbol'
                                ) // 全显示
                                || (categoryAxis.isMainAxis(singlePL[j][2])
                                    && self.deepQuery(
                                           [data, serie], 'symbol'
                                       ) != 'none'
                                   ) // 主轴非空
                                || self.deepQuery(
K
kener 已提交
517 518
                                        [data, serie, option],
                                        'calculable'
K
kener 已提交
519
                                   ) // 可计算
K
kener 已提交
520
                            ) {
K
kener 已提交
521
                                self.shapeList.push(_getSymbol(
K
kener 已提交
522 523 524 525 526 527 528 529 530 531 532 533 534
                                    seriesIndex,
                                    singlePL[j][2], // dataIndex
                                    singlePL[j][3], // name
                                    singlePL[j][0], // x
                                    singlePL[j][1], // y
                                    self.deepQuery(
                                        [data], 'itemStyle.normal.color'
                                    ) || normalColor
                                      || defaultColor,
                                    self.deepQuery(
                                        [data], 'itemStyle.emphasis.color'
                                    ) || emphasisColor
                                      || normalColor
K
kener 已提交
535
                                      || defaultColor,
K
kener 已提交
536 537 538
                                    lineWidth,
                                    self.deepQuery(
                                        [data, serie], 'symbolRotate'
K
kener 已提交
539 540
                                    ),
                                    orient
K
kener 已提交
541 542 543 544
                                ));
                            }

                        }
K
kener 已提交
545 546 547 548 549 550 551 552 553 554 555
                        // 折线图
                        self.shapeList.push({
                            shape : 'brokenLine',
                            zlevel : _zlevelBase,
                            style : {
                                pointList : singlePL,
                                strokeColor : lineColor
                                              || normalColor
                                              || defaultColor,
                                lineWidth : lineWidth,
                                lineType : lineType,
K
kener 已提交
556
                                smooth : _getSmooth(serie.smooth),
K
kener 已提交
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
                                shadowColor : self.deepQuery(
                                  [serie],
                                  'itemStyle.normal.lineStyle.shadowColor'
                                ),
                                shadowBlur: self.deepQuery(
                                  [serie],
                                  'itemStyle.normal.lineStyle.shadowBlur'
                                ),
                                shadowOffsetX: self.deepQuery(
                                  [serie],
                                  'itemStyle.normal.lineStyle.shadowOffsetX'
                                ),
                                shadowOffsetY: self.deepQuery(
                                  [serie],
                                  'itemStyle.normal.lineStyle.shadowOffsetY'
                                )
                            },
                            hoverable : false,
                            _main : true,
                            _seriesIndex : seriesIndex,
                            _orient : orient
                        });
                        
K
kener 已提交
580 581
                        if (isFill) {
                            self.shapeList.push({
K
kener 已提交
582
                                shape : 'halfSmoothPolygon',
K
kener 已提交
583 584
                                zlevel : _zlevelBase,
                                style : {
K
kener 已提交
585 586 587 588 589 590 591 592 593 594 595
                                    pointList : singlePL.concat([
                                        [
                                            singlePL[singlePL.length - 1][4],
                                            singlePL[singlePL.length - 1][5] - 2
                                        ],
                                        [
                                            singlePL[0][4],
                                            singlePL[0][5] - 2
                                        ]
                                    ]),
                                    brushType : 'fill',
K
kener 已提交
596
                                    smooth : _getSmooth(serie.smooth),
K
kener 已提交
597 598
                                    color : fillNormalColor
                                            ? fillNormalColor
K
kener 已提交
599
                                            : zrColor.alpha(defaultColor,0.5)
K
kener 已提交
600 601 602
                                },
                                hoverable : false,
                                _main : true,
K
kener 已提交
603
                                _seriesIndex : seriesIndex,
K
kener 已提交
604 605 606 607
                                _orient : orient
                            });
                        }
                    }
K
kener 已提交
608
                }
K
kener 已提交
609 610
            }
        }
K
kener 已提交
611 612 613 614 615 616 617 618 619 620 621 622
        
        function _getSmooth(isSmooth/*, pointList, orient*/) {
            if (isSmooth) {
                /* 不科学啊,发现0.3通用了
                var delta;
                if (orient == 'horizontal') {
                    delta = Math.abs(pointList[0][0] - pointList[1][0]);
                }
                else {
                    delta = Math.abs(pointList[0][1] - pointList[1][1]);
                }
                */
K
kener 已提交
623
                return 0.3;
K
kener 已提交
624 625 626 627 628
            }
            else {
                return 0;
            }
        }
K
kener 已提交
629 630 631 632

        /**
         * 生成空数据所需的可计算提示图形
         */
K
kener 已提交
633 634 635
        function _getCalculableItem(
            seriesIndex, dataIndex, name, x, y, orient
        ) {
K
kener 已提交
636 637 638
            var color = series[seriesIndex].calculableHolderColor
                        || ecConfig.calculableHolderColor;

K
kener 已提交
639
            var itemShape = _getSymbol(
K
kener 已提交
640 641 642
                seriesIndex, dataIndex, name,
                x, y,
                color,
K
kener 已提交
643
                _sIndex2ColorMap[seriesIndex],
K
kener 已提交
644 645 646
                2,
                0,
                orient
K
kener 已提交
647 648 649 650
            );

            itemShape.hoverable = false;
            itemShape.draggable = false;
K
kener 已提交
651 652
            itemShape.style.text = undefined;
            //itemShape.highlightStyle.lineWidth = 20;
K
kener 已提交
653 654 655 656 657 658 659

            return itemShape;
        }

        /**
         * 生成折线图上的拐点图形
         */
K
kener 已提交
660
        function _getSymbol(
K
kener 已提交
661
            seriesIndex, dataIndex, name, x, y,
K
kener 已提交
662
            normalColor, emphasisColor, lineWidth, rotate, orient
K
kener 已提交
663 664 665
        ) {
            var serie = series[seriesIndex];
            var data = serie.data[dataIndex];
K
kener 已提交
666 667 668
            var symbol = self.deepQuery([data], 'symbol')
                         || _sIndex2ShapeMap[seriesIndex]
                         || 'cricle';
669 670 671 672 673 674 675 676 677 678 679 680 681 682
            var symbolSize = self.deepQuery([data, serie],'symbolSize');

            var itemShape = {
                shape : 'icon',
                zlevel : _zlevelBase + 1,
                style : {
                    iconType : symbol.replace('empty', '').toLowerCase(),
                    x : x - symbolSize,
                    y : y - symbolSize,
                    width : symbolSize * 2,
                    height : symbolSize * 2,
                    brushType : 'both',
                    color : symbol.match('empty') ? '#fff' : normalColor,
                    strokeColor : normalColor,
K
kener 已提交
683
                    lineWidth: lineWidth * 2
684 685
                },
                highlightStyle : {
K
kener 已提交
686
                    color : symbol.match('empty') ? '#fff' : emphasisColor,
K
kener 已提交
687 688
                    strokeColor : emphasisColor,
                    lineWidth: lineWidth * 2 + 2
689
                },
K
kener 已提交
690
                clickable : true
K
kener 已提交
691
            };
692
            
K
kener 已提交
693 694 695 696 697 698
            if (typeof rotate != 'undefined') {
                itemShape.rotation = [
                    rotate * Math.PI / 180, x, y
                ];
            }
            
699 700 701 702 703 704 705 706 707 708
            if (symbol.match('star')) {
                itemShape.style.iconType = 'star';
                itemShape.style.n = 
                    (symbol.replace('empty', '').replace('star','') - 0) || 5;
            }
            
            if (symbol == 'none') {
                itemShape.invisible = true;
                itemShape.hoverable = false;
            }
K
kener 已提交
709 710 711 712 713 714

            if (self.deepQuery([data, serie, option], 'calculable')) {
                self.setCalculable(itemShape);
                itemShape.draggable = true;
            }

K
kener 已提交
715 716 717 718 719 720 721 722 723
            itemShape = self.addLabel(
                itemShape, 
                series[seriesIndex], 
                series[seriesIndex].data[dataIndex], 
                name, 
                orient == 'vertical' ? 'horizontal' : 'vertical'
            );
            if (symbol.match('empty')) {
                if (typeof itemShape.style.textColor == 'undefined') {
K
kener 已提交
724
                    itemShape.style.textColor = itemShape.style.strokeColor;
K
kener 已提交
725 726 727
                }
                if (typeof itemShape.highlightStyle.textColor == 'undefined') {
                    itemShape.highlightStyle.textColor = 
K
kener 已提交
728
                        itemShape.highlightStyle.strokeColor;
K
kener 已提交
729 730 731
                }
            }
            
K
kener 已提交
732 733 734
            ecData.pack(
                itemShape,
                series[seriesIndex], seriesIndex,
K
kener 已提交
735
                series[seriesIndex].data[dataIndex], dataIndex,
K
kener 已提交
736 737 738 739 740
                name
            );

            itemShape._x = x;
            itemShape._y = y;
741 742
            itemShape._dataIndex = dataIndex;
            itemShape._seriesIndex = seriesIndex;
K
kener 已提交
743 744 745 746 747 748 749 750 751 752 753

            return itemShape;
        }

        /**
         * 构造函数默认执行的初始化方法,也用于创建实例后动态修改
         * @param {Object} newSeries
         * @param {Object} newComponent
         */
        function init(newOption, newComponent) {
            component = newComponent;
K
kener 已提交
754
            refresh(newOption);
K
kener 已提交
755 756 757 758 759
        }

        /**
         * 刷新
         */
K
kener 已提交
760 761 762 763 764
        function refresh(newOption) {
            if (newOption) {
                option = newOption;
                series = option.series;
            }
K
kener 已提交
765 766 767
            self.clear();
            _buildShape();
        }
K
kener 已提交
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
        
        function ontooltipHover(param, tipShape) {
            var seriesIndex = param.seriesIndex;
            var dataIndex = param.dataIndex;
            var seriesPL;
            var serie;
            var queryTarget;
            var len = seriesIndex.length;
            while (len--) {
                seriesPL = finalPLMap[seriesIndex[len]];
                if (seriesPL) {
                    serie = series[seriesIndex[len]];
                    queryTarget = [serie];
                    defaultColor = _sIndex2ColorMap[seriesIndex[len]];
                    // 多级控制
                    lineWidth = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.width'
                    );
                    lineType = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.type'
                    );
                    lineColor = self.deepQuery(
                        [serie], 'itemStyle.normal.lineStyle.color'
                    );
                    normalColor = self.deepQuery(
                        [serie], 'itemStyle.normal.color'
                    );
                    emphasisColor = self.deepQuery(
                        [serie], 'itemStyle.emphasis.color'
                    );
                    var shape;
                    for (var i = 0, l = seriesPL.length; i < l; i++) {
                        singlePL = seriesPL[i];
                        for (var j = 0, k = singlePL.length; j < k; j++) {
                            if (dataIndex == singlePL[j][2]) {
                                data = serie.data[singlePL[j][2]];
                                shape = _getSymbol(
                                    seriesIndex[len],
                                    singlePL[j][2], // dataIndex
                                    singlePL[j][3], // name
                                    singlePL[j][0], // x
                                    singlePL[j][1], // y
                                    self.deepQuery(
                                        [data], 'itemStyle.normal.color'
                                    ) || normalColor
                                      || defaultColor,
                                    self.deepQuery(
                                        [data], 'itemStyle.emphasis.color'
                                    ) || emphasisColor
                                      || normalColor
                                      || defaultColor,
                                    lineWidth,
                                    self.deepQuery(
                                        [data, serie], 'symbolRotate'
                                    ),
                                    'horizontal'
                                );
                                //console.log(shape)
                                //zr.addHoverShape(shape);
                                tipShape.push(shape);
                            }
                        }
                    }
                }
            }
        }
K
kener 已提交
834

835 836 837 838 839 840 841 842 843 844 845 846 847
        /**
         * 动态数据增加动画 
         */
        function addDataAnimation(params) {
            var aniMap = {}; // seriesIndex索引参数
            for (var i = 0, l = params.length; i < l; i++) {
                aniMap[params[i][0]] = params[i];
            }
            var x;
            var dx;
            var y;
            var dy;
            var seriesIndex;
K
kener 已提交
848 849
            var pointList;
            var isHorizontal; // 是否横向布局, isHorizontal;
850 851 852 853 854
            for (var i = self.shapeList.length - 1; i >= 0; i--) {
                seriesIndex = self.shapeList[i]._seriesIndex;
                if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) {
                    // 有数据删除才有移动的动画
                    if (self.shapeList[i]._main) {
K
kener 已提交
855
                        pointList = self.shapeList[i].style.pointList;
856
                        // 主线动画
K
kener 已提交
857 858 859 860 861
                        dx = Math.abs(pointList[0][0] - pointList[1][0]);
                        dy = Math.abs(pointList[0][1] - pointList[1][1]);
                        isHorizontal = 
                            self.shapeList[i]._orient == 'horizontal';
                            
862 863
                        if (aniMap[seriesIndex][2]) {
                            // 队头加入删除末尾
K
kener 已提交
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
                            if (self.shapeList[i].shape == 'polygon') {
                                //区域图
                                var len = pointList.length;
                                self.shapeList[i].style.pointList[len - 3]
                                    = pointList[len - 2];
                                isHorizontal
                                ? (self.shapeList[i].style.pointList[len - 3][0]
                                       = pointList[len - 4][0]
                                  )
                                : (self.shapeList[i].style.pointList[len - 3][1]
                                       = pointList[len - 4][1]
                                  );
                                self.shapeList[i].style.pointList[len - 2]
                                    = pointList[len - 1];
                            }
879
                            self.shapeList[i].style.pointList.pop();
K
kener 已提交
880 881
                            
                            isHorizontal ? (x = dx, y = 0) : (x = 0, y = -dy);
882 883 884 885
                        }
                        else {
                            // 队尾加入删除头部
                            self.shapeList[i].style.pointList.shift();
K
kener 已提交
886 887 888 889 890 891 892 893 894 895 896 897
                            if (self.shapeList[i].shape == 'polygon') {
                                //区域图
                                var targetPoint = 
                                    self.shapeList[i].style.pointList.pop();
                                isHorizontal
                                ? (targetPoint[0] = pointList[0][0])
                                : (targetPoint[1] = pointList[0][1]);
                                self.shapeList[i].style.pointList.push(
                                    targetPoint
                                );
                            }
                            isHorizontal ? (x = -dx, y = 0) : (x = 0, y = dy);
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915
                        }
                        zr.modShape(self.shapeList[i].id, {
                            style : {
                                pointList : self.shapeList[i].style.pointList
                            }
                        });
                    }
                    else {
                        // 拐点动画
                        if (aniMap[seriesIndex][2] 
                            && self.shapeList[i]._dataIndex 
                                == series[seriesIndex].data.length - 1
                        ) {
                            // 队头加入删除末尾
                            zr.delShape(self.shapeList[i].id);
                            continue;
                        }
                        else if (!aniMap[seriesIndex][2] 
K
kener 已提交
916
                                 && self.shapeList[i]._dataIndex === 0
917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932
                        ) {
                            // 队尾加入删除头部
                            zr.delShape(self.shapeList[i].id);
                            continue;
                        }
                    }
                    zr.animate(self.shapeList[i].id, '')
                        .when(
                            500,
                            {position : [x, y]}
                        )
                        .start();
                }
            }
        }
        
K
kener 已提交
933 934 935 936 937 938 939 940 941 942 943 944 945
        /**
         * 动画设定
         */
        function animation() {
            var duration = self.deepQuery([option], 'animationDuration');
            var easing = self.deepQuery([option], 'animationEasing');
            var x;
            var y;
            var serie;
            var dataIndex = 0;

            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                if (self.shapeList[i]._main) {
K
kener 已提交
946
                    serie = series[self.shapeList[i]._seriesIndex];
K
kener 已提交
947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964
                    dataIndex += 1;
                    x = self.shapeList[i].style.pointList[0][0];
                    y = self.shapeList[i].style.pointList[0][1];
                    if (self.shapeList[i]._orient == 'horizontal') {
                        zr.modShape(self.shapeList[i].id, {
                            scale : [0, 1, x, y]
                        });
                    }
                    else {
                        zr.modShape(self.shapeList[i].id, {
                            scale : [1, 0, x, y]
                        });
                    }
                    zr.animate(self.shapeList[i].id, '')
                        .when(
                            (self.deepQuery([serie],'animationDuration')
                            || duration)
                            + dataIndex * 100,
K
kener 已提交
965
                            {scale : [1, 1, x, y]}
K
kener 已提交
966
                        )
K
kener 已提交
967 968 969
                        .start(
                            self.deepQuery([serie], 'animationEasing') || easing
                        );
K
kener 已提交
970 971 972 973 974 975 976 977 978 979
                }
                else {
                    x = self.shapeList[i]._x || 0;
                    y = self.shapeList[i]._y || 0;
                    zr.modShape(self.shapeList[i].id, {
                        scale : [0, 0, x, y]
                    });
                    zr.animate(self.shapeList[i].id, '')
                        .when(
                            duration,
K
kener 已提交
980
                            {scale : [1, 1, x, y]}
K
kener 已提交
981
                        )
K
kener 已提交
982
                        .start('QuinticOut');
K
kener 已提交
983 984 985 986 987 988
                }
            }
        }

        self.init = init;
        self.refresh = refresh;
K
kener 已提交
989
        self.ontooltipHover = ontooltipHover;
990
        self.addDataAnimation = addDataAnimation;
K
kener 已提交
991 992 993 994 995
        self.animation = animation;

        init(option, component);
    }

996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
    function legendLineIcon(ctx, style) {
        var x = style.x;
        var y = style.y;
        var width = style.width;
        var height = style.height;
        
        var dy = height / 2;
        ctx.moveTo(x, y + dy);
        ctx.lineTo(x + width, y + dy);
        
        if (style.symbol.match('empty')) {
            ctx.fillStyle = '#fff';
        }
        style.brushType = 'both';
        
        var symbol = style.symbol.replace('empty', '').toLowerCase();
        if (symbol.match('star')) {
            dy = (symbol.replace('star','') - 0) || 5;
            y -= 1;
            symbol = 'star';
        } 
K
kener 已提交
1017
        else if (symbol == 'rectangle' || symbol == 'arrow') {
1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
            x += (width - height) / 2;
            width = height;
        }
        symbol = require('zrender/shape').get('icon').get(symbol);
        
        if (symbol) {
            symbol(ctx, {
                x : x + 3,
                y : y + 3,
                width : width - 6,
                height : height - 6,
                n : dy
            });
        }
    }
K
kener 已提交
1033 1034 1035 1036
    
    // 动态扩展zrender shape:halfSmoothPolygon
    require('../util/shape/halfSmoothPolygon');
    
1037 1038 1039
    // 图表注册
    require('../chart').define('line', Line);
    
K
kener 已提交
1040 1041
    return Line;
});