legend.js 32.5 KB
Newer Older
K
kener 已提交
1 2 3 4 5 6 7 8
/**
 * echarts组件:图例
 *
 * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
 * @author Kener (@Kener-林峰, linzhifeng@baidu.com)
 *
 */
define(function (require) {
K
kener 已提交
9 10
    var TextShape = require('zrender/shape/Text');
    var RectangleShape = require('zrender/shape/Rectangle');
K
kener 已提交
11 12
    var SectorShape = require('zrender/shape/Sector');
    var BeziercurveShape = require('zrender/shape/Beziercurve');
K
kener 已提交
13
    var IconShape = require('../util/shape/Icon');
K
kener 已提交
14
    var CandleShape = require('../util/shape/Candle');
K
kener 已提交
15
    
K
kener 已提交
16 17 18 19 20 21 22
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表参数
     * @param {Object=} selected 用于状态保持
     */
K
kener 已提交
23
    function Legend(ecConfig, messageCenter, zr, option, selected) {
K
kener 已提交
24
        var Base = require('./base');
K
kener 已提交
25
        Base.call(this, ecConfig, zr);
K
kener 已提交
26

27
        var zrUtil = require('zrender/tool/util');
K
kener 已提交
28
        var zrArea = require('zrender/tool/area');
29
        var zrColor = require('zrender/tool/color');
K
kener 已提交
30 31 32 33 34 35 36 37 38 39 40 41 42

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

        var legendOption;                       // 图例选项,共享数据源
        var _zlevelBase = self.getZlevelBase();

        var _itemGroupLocation = {};    // 图例元素组的位置参数,通过计算所得x, y, width, height

        var _colorIndex = 0;
        var _colorMap = {};
        var _selectedMap = {};

43
        for (var k in legendIcon) {
K
kener 已提交
44
            IconShape.prototype.iconLibrary['legendicon' + k] = legendIcon[k];
45 46
            //console.log('legendicon' + k, legendIcon[k])
        }
K
kener 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

        function _buildShape() {
            _itemGroupLocation = _getItemGroupLocation();

            _buildBackground();
            _buildItem();

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

        /**
         * 构建所有图例元素
         */
        function _buildItem() {
            var data = legendOption.data;
            var dataLength = data.length;
            var itemName;
            var itemType;
            var itemShape;
            var textShape;
69 70 71
            var textStyle  = legendOption.textStyle;
            var dataTextStyle;
            var dataFont;
K
kener 已提交
72 73

            var zrWidth = zr.getWidth();
K
kener 已提交
74
            var zrHeight = zr.getHeight();
K
kener 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
            var lastX = _itemGroupLocation.x;
            var lastY = _itemGroupLocation.y;
            var itemWidth = legendOption.itemWidth;
            var itemHeight = legendOption.itemHeight;
            var itemGap = legendOption.itemGap;
            var color;

            if (legendOption.orient == 'vertical'
                && legendOption.x == 'right'
            ) {
                lastX = _itemGroupLocation.x
                        + _itemGroupLocation.width
                        - itemWidth;
            }

            for (var i = 0; i < dataLength; i++) {
91 92
                dataTextStyle = zrUtil.merge(
                    data[i].textStyle || {},
K
kener 已提交
93
                    textStyle
94 95 96 97
                );
                dataFont = self.getFont(dataTextStyle);
                
                itemName = data[i].name || data[i];
K
kener 已提交
98
                if (itemName === '') {
K
kener 已提交
99 100 101 102 103 104 105 106 107 108 109 110
                    if (legendOption.orient == 'horizontal') {
                        lastX = _itemGroupLocation.x;
                        lastY += itemHeight + itemGap;
                    }
                    else {
                        legendOption.x == 'right'
                        ? lastX -= _itemGroupLocation.maxWidth + itemGap
                        : lastX += _itemGroupLocation.maxWidth + itemGap;
                        lastY = _itemGroupLocation.y;
                    }
                    continue;
                }
K
kener 已提交
111 112
                itemType = _getSomethingByName(itemName).type;
                
K
kener 已提交
113 114 115 116 117
                color = getColor(itemName);

                if (legendOption.orient == 'horizontal') {
                    if (zrWidth - lastX < 200   // 最后200px做分行预判
                        && (itemWidth + 5
118 119 120 121
                            + zrArea.getTextWidth(
                                itemName, 
                                dataFont
                            )
K
kener 已提交
122
                            // 分行的最后一个不用算itemGap
K
kener 已提交
123
                            + (i == dataLength - 1 || data[i+1] === ''
K
kener 已提交
124 125
                               ? 0 : itemGap))
                            >= zrWidth - lastX
K
kener 已提交
126
                    ) {
K
kener 已提交
127
                        lastX = _itemGroupLocation.x;
K
kener 已提交
128 129 130
                        lastY += itemHeight + itemGap;
                    }
                }
K
kener 已提交
131 132 133 134
                else {
                    if (zrHeight - lastY < 200   // 最后200px做分行预判
                        && (itemHeight
                            // 分行的最后一个不用算itemGap
K
kener 已提交
135
                            + (i == dataLength - 1 || data[i+1] === ''
K
kener 已提交
136 137 138 139 140 141 142 143 144
                               ? 0 : itemGap))
                            >= zrHeight - lastY
                    ) {
                        legendOption.x == 'right'
                        ? lastX -= _itemGroupLocation.maxWidth + itemGap
                        : lastX += _itemGroupLocation.maxWidth + itemGap;
                        lastY = _itemGroupLocation.y;
                    }
                }
K
kener 已提交
145 146 147 148 149

                // 图形
                itemShape = _getItemShapeByType(
                    lastX, lastY,
                    itemWidth, itemHeight,
150
                    (_selectedMap[itemName] ? color : '#ccc'),
151 152
                    itemType,
                    color
K
kener 已提交
153 154
                );
                itemShape._name = itemName;
155 156 157
                if (legendOption.selectedMode) {
                    itemShape.onclick = _legendSelected;
                }
K
kener 已提交
158
                self.shapeList.push(new IconShape(itemShape));
K
kener 已提交
159 160 161 162 163 164 165 166 167

                // 文字
                textShape = {
                    shape : 'text',
                    zlevel : _zlevelBase,
                    style : {
                        x : lastX + itemWidth + 5,
                        y : lastY,
                        color : _selectedMap[itemName]
168
                                ? (dataTextStyle.color === 'auto' ? color : dataTextStyle.color)
K
kener 已提交
169 170
                                : '#ccc',
                        text: itemName,
171
                        textFont: dataFont,
K
kener 已提交
172 173
                        textBaseline: 'top'
                    },
174 175 176 177
                    highlightStyle : {
                        color : color,
                        brushType: 'fill'
                    },
K
kener 已提交
178 179
                    hoverable : !!legendOption.selectedMode,
                    clickable : !!legendOption.selectedMode
K
kener 已提交
180 181 182 183 184 185 186 187 188 189
                };

                if (legendOption.orient == 'vertical'
                    && legendOption.x == 'right'
                ) {
                    textShape.style.x -= (itemWidth + 10);
                    textShape.style.textAlign = 'right';
                }

                textShape._name = itemName;
190 191 192
                if (legendOption.selectedMode) {
                    textShape.onclick = _legendSelected;
                }
K
kener 已提交
193
                self.shapeList.push(new TextShape(textShape));
K
kener 已提交
194 195 196

                if (legendOption.orient == 'horizontal') {
                    lastX += itemWidth + 5
197
                             + zrArea.getTextWidth(itemName, dataFont)
K
kener 已提交
198 199 200 201 202 203
                             + itemGap;
                }
                else {
                    lastY += itemHeight + itemGap;
                }
            }
K
kener 已提交
204 205 206 207 208 209
        
            if (legendOption.orient == 'horizontal'
                && legendOption.x == 'center'
                && lastY != _itemGroupLocation.y
            ) {
                // 多行橫排居中优化
K
kener 已提交
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
                _mLineOptimize();
            }
        }
        
        // 多行橫排居中优化
        function _mLineOptimize() {
            var lineOffsetArray = []; // 每行宽度
            var lastX = _itemGroupLocation.x;
            for (var i = 2, l = self.shapeList.length; i < l; i++) {
                if (self.shapeList[i].style.x == lastX) {
                    lineOffsetArray.push(
                        (
                            _itemGroupLocation.width 
                            - (
                                self.shapeList[i - 1].style.x
                                + zrArea.getTextWidth(
226 227
                                      self.shapeList[i - 1].style.text,
                                      self.shapeList[i - 1].style.textFont
K
kener 已提交
228 229 230 231 232
                                  )
                                - lastX
                            )
                        ) / 2
                    );
K
kener 已提交
233
                }
K
kener 已提交
234 235 236 237 238 239 240
                else if (i == l - 1) {
                    lineOffsetArray.push(
                        (
                            _itemGroupLocation.width 
                            - (
                                self.shapeList[i].style.x
                                + zrArea.getTextWidth(
241 242
                                      self.shapeList[i].style.text,
                                      self.shapeList[i].style.textFont
K
kener 已提交
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
                                  )
                                - lastX
                            )
                        ) / 2
                    );
                }
            }
            var curLineIndex = -1;
            for (var i = 1, l = self.shapeList.length; i < l; i++) {
                if (self.shapeList[i].style.x == lastX) {
                    curLineIndex++;
                }
                if (lineOffsetArray[curLineIndex] === 0) {
                    continue;
                }
                else {
                    self.shapeList[i].style.x += 
                        lineOffsetArray[curLineIndex];
K
kener 已提交
261 262
                }
            }
K
kener 已提交
263 264 265 266 267 268 269 270
        }

        function _buildBackground() {
            var pTop = legendOption.padding[0];
            var pRight = legendOption.padding[1];
            var pBottom = legendOption.padding[2];
            var pLeft = legendOption.padding[3];

K
kener 已提交
271
            self.shapeList.push(new RectangleShape({
K
kener 已提交
272 273 274 275 276 277 278 279 280 281 282 283 284
                zlevel : _zlevelBase,
                hoverable :false,
                style : {
                    x : _itemGroupLocation.x - pLeft,
                    y : _itemGroupLocation.y - pTop,
                    width : _itemGroupLocation.width + pLeft + pRight,
                    height : _itemGroupLocation.height + pTop + pBottom,
                    brushType : legendOption.borderWidth === 0
                                ? 'fill' : 'both',
                    color : legendOption.backgroundColor,
                    strokeColor : legendOption.borderColor,
                    lineWidth : legendOption.borderWidth
                }
K
kener 已提交
285
            }));
K
kener 已提交
286 287 288 289 290 291 292 293 294 295 296
        }

        /**
         * 根据选项计算图例实体的位置坐标
         */
        function _getItemGroupLocation() {
            var data = legendOption.data;
            var dataLength = data.length;
            var itemGap = legendOption.itemGap;
            var itemWidth = legendOption.itemWidth + 5; // 5px是图形和文字的间隔,不可配
            var itemHeight = legendOption.itemHeight;
297 298
            var textStyle  = legendOption.textStyle;
            var font = self.getFont(textStyle);
K
kener 已提交
299 300
            var totalWidth = 0;
            var totalHeight = 0;
K
kener 已提交
301 302 303 304 305 306
            var padding = legendOption.padding;
            var zrWidth = zr.getWidth() - padding[1] - padding[3];
            var zrHeight = zr.getHeight() - padding[0] - padding[2];
            
            var temp = 0; // 宽高计算,用于多行判断
            var maxWidth = 0; // 垂直布局有用
K
kener 已提交
307 308
            if (legendOption.orient == 'horizontal') {
                // 水平布局,计算总宽度
K
kener 已提交
309
                totalHeight = itemHeight;
K
kener 已提交
310
                for (var i = 0; i < dataLength; i++) {
K
kener 已提交
311
                    if (data[i] === '') {
K
kener 已提交
312 313 314 315 316 317 318 319 320 321 322 323
                        temp -= itemGap;
                        if (temp > zrWidth) {
                            totalWidth = zrWidth;
                            totalHeight += itemHeight + itemGap;
                        }
                        else {
                            totalWidth = Math.max(totalWidth, temp);
                        }
                        totalHeight += itemHeight + itemGap;
                        temp = 0;
                        continue;
                    }
324 325
                    dataTextStyle = zrUtil.merge(
                        data[i].textStyle || {},
K
kener 已提交
326
                        textStyle
327
                    );
K
kener 已提交
328 329
                    temp += itemWidth
                            + zrArea.getTextWidth(
330 331 332 333
                                  data[i].name || data[i],
                                  data[i].textStyle 
                                  ? self.getFont(zrUtil.merge(
                                        data[i].textStyle || {},
K
kener 已提交
334
                                        textStyle
335 336
                                    ))
                                  : font
K
kener 已提交
337 338 339 340 341 342 343 344 345 346
                              )
                            + itemGap;
                }
                totalHeight = Math.max(totalHeight, itemHeight);
                temp -= itemGap;    // 减去最后一个的itemGap
                if (temp > zrWidth) {
                    totalWidth = zrWidth;
                    totalHeight += itemHeight + itemGap;
                } else {
                    totalWidth = Math.max(totalWidth, temp);
K
kener 已提交
347 348 349 350 351 352 353 354
                }
            }
            else {
                // 垂直布局,计算总高度
                for (var i = 0; i < dataLength; i++) {
                    maxWidth = Math.max(
                        maxWidth,
                        zrArea.getTextWidth(
355 356 357 358
                            data[i].name || data[i],
                            data[i].textStyle 
                            ? self.getFont(zrUtil.merge(
                                  data[i].textStyle || {},
K
kener 已提交
359
                                  textStyle
360 361
                              ))
                            : font
K
kener 已提交
362 363 364
                        )
                    );
                }
K
kener 已提交
365 366 367
                maxWidth += itemWidth;
                totalWidth = maxWidth;
                for (var i = 0; i < dataLength; i++) {
K
kener 已提交
368
                    if (data[i] === '') {
K
kener 已提交
369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
                        temp -= itemGap;
                        if (temp > zrHeight) {
                            totalHeight = zrHeight;
                            totalWidth += maxWidth + itemGap;
                        }
                        else {
                            totalHeight = Math.max(totalHeight, temp);
                        }
                        totalWidth += maxWidth + itemGap;
                        temp = 0;
                        continue;
                    }
                    temp += itemHeight + itemGap;
                }
                totalWidth = Math.max(totalWidth, maxWidth);
                temp -= itemGap;    // 减去最后一个的itemGap
                if (temp > zrHeight) {
                    totalHeight = zrHeight;
                    totalWidth += maxWidth + itemGap;
                } else {
                    totalHeight = Math.max(totalHeight, temp);
                }
K
kener 已提交
391 392
            }

K
kener 已提交
393 394
            zrWidth = zr.getWidth();
            zrHeight = zr.getHeight();
K
kener 已提交
395 396 397 398 399 400 401 402 403 404 405 406
            var x;
            switch (legendOption.x) {
                case 'center' :
                    x = Math.floor((zrWidth - totalWidth) / 2);
                    break;
                case 'left' :
                    x = legendOption.padding[3] + legendOption.borderWidth;
                    break;
                case 'right' :
                    x = zrWidth
                        - totalWidth
                        - legendOption.padding[1]
K
kener 已提交
407 408
                        - legendOption.padding[3]
                        - legendOption.borderWidth * 2;
K
kener 已提交
409 410 411
                    break;
                default :
                    x = legendOption.x - 0;
K
kener 已提交
412
                    x = isNaN(x) ? 0 : x;
K
kener 已提交
413 414 415 416 417 418 419 420 421 422 423
                    break;
            }

            var y;
            switch (legendOption.y) {
                case 'top' :
                    y = legendOption.padding[0] + legendOption.borderWidth;
                    break;
                case 'bottom' :
                    y = zrHeight
                        - totalHeight
K
kener 已提交
424
                        - legendOption.padding[0]
K
kener 已提交
425
                        - legendOption.padding[2]
K
kener 已提交
426
                        - legendOption.borderWidth * 2;
K
kener 已提交
427 428 429 430 431 432
                    break;
                case 'center' :
                    y = Math.floor((zrHeight - totalHeight) / 2);
                    break;
                default :
                    y = legendOption.y - 0;
K
kener 已提交
433
                    y = isNaN(y) ? 0 : y;
K
kener 已提交
434 435 436 437 438 439 440
                    break;
            }

            return {
                x : x,
                y : y,
                width : totalWidth,
K
kener 已提交
441 442
                height : totalHeight,
                maxWidth : maxWidth
K
kener 已提交
443 444 445 446
            };
        }

        /**
K
kener 已提交
447
         * 根据名称返回series数据或data
K
kener 已提交
448
         */
K
kener 已提交
449
        function _getSomethingByName(name) {
K
kener 已提交
450
            var series = option.series;
K
kener 已提交
451
            var data;
K
kener 已提交
452 453 454
            for (var i = 0, l = series.length; i < l; i++) {
                if (series[i].name == name) {
                    // 系列名称优先
K
kener 已提交
455 456 457 458 459 460
                    return {
                        type : series[i].type,
                        series : series[i],
                        seriesIndex : i,
                        data : null,
                        dataIndex : -1
K
kener 已提交
461
                    };
K
kener 已提交
462 463
                }

K
kener 已提交
464 465 466
                if (
                    series[i].type == ecConfig.CHART_TYPE_PIE 
                    || series[i].type == ecConfig.CHART_TYPE_RADAR
L
lang 已提交
467
                    || series[i].type == ecConfig.CHART_TYPE_CHORD
K
kener 已提交
468
                    || series[i].type == ecConfig.CHART_TYPE_FORCE
K
kener 已提交
469
                ) {
K
kener 已提交
470 471 472
                    data = series[i].type != ecConfig.CHART_TYPE_FORCE
                           ? series[i].data         // 饼图、雷达图、和弦图得查找里面的数据名字
                           : series[i].categories;  // 力导布局查找categories配置
K
kener 已提交
473 474
                    for (var j = 0, k = data.length; j < k; j++) {
                        if (data[j].name == name) {
K
kener 已提交
475 476 477 478 479 480
                            return {
                                type : series[i].type,
                                series : series[i],
                                seriesIndex : i,
                                data : data[j],
                                dataIndex : j
K
kener 已提交
481
                            };
K
kener 已提交
482 483
                        }
                    }
K
kener 已提交
484
                }
K
kener 已提交
485
            }
K
kener 已提交
486 487 488 489 490 491
            return {
                type : 'bar',
                series : null,
                seriesIndex : -1,
                data : null,
                dataIndex : -1
K
kener 已提交
492
            };
K
kener 已提交
493
        }
K
kener 已提交
494
        
495 496 497 498 499
        function _getItemShapeByType(x, y, width, height, color, itemType, defaultColor) {
            var highlightColor = color === '#ccc' 
                                 ? defaultColor 
                                 : typeof color == 'string' && color != '#ccc' 
                                   ? zrColor.lift(color, -0.3) : color;
500 501 502
            var itemShape = {
                zlevel : _zlevelBase,
                style : {
K
kener 已提交
503 504 505
                    iconType : 'legendicon' 
                               + (itemType != ecConfig.CHART_TYPE_CHORD   // 和弦复用饼图
                                  ? itemType : ecConfig.CHART_TYPE_PIE),
506 507 508 509 510 511
                    x : x,
                    y : y,
                    width : width,
                    height : height,
                    color : color,
                    strokeColor : color,
512 513 514 515 516 517
                    lineWidth : 2
                },
                highlightStyle: {
                    color : highlightColor,
                    strokeColor : highlightColor,
                    lineWidth : 1
518
                },
519 520
                hoverable : legendOption.selectedMode,
                clickable : legendOption.selectedMode
521 522
            };
            // 特殊设置
K
kener 已提交
523 524
            switch (itemType) {
                case 'line' :
525
                    itemShape.style.brushType = 'stroke';
526 527 528 529 530
                    itemShape.highlightStyle.lineWidth = 3;
                    break;
                case 'radar' :
                case 'scatter' :   
                    itemShape.highlightStyle.lineWidth = 3;
531
                    break;
K
kener 已提交
532
                case 'k' :
533
                    itemShape.style.brushType = 'both';
534 535
                    itemShape.highlightStyle.lineWidth = 3;
                    itemShape.highlightStyle.color =
536 537
                    itemShape.style.color = self.query(
                        ecConfig, 'k.itemStyle.normal.color'
538 539
                    ) || '#fff';
                    itemShape.style.strokeColor = color != '#ccc' 
540 541
                        ? self.query(
                              ecConfig, 'k.itemStyle.normal.lineStyle.color'
542 543
                          ) || '#ff3200'
                        : color;
K
kener 已提交
544
            }
545
            return itemShape;
K
kener 已提交
546 547 548 549
        }

        function _legendSelected(param) {
            var itemName = param.target._name;
K
kener 已提交
550 551 552 553 554
            if (legendOption.selectedMode === 'single') {
                for (var k in _selectedMap) {
                    _selectedMap[k] = false;
                }
            }
K
kener 已提交
555 556 557 558
            _selectedMap[itemName] = !_selectedMap[itemName];
            messageCenter.dispatch(
                ecConfig.EVENT.LEGEND_SELECTED,
                param.event,
K
kener 已提交
559 560 561 562
                {
                    selected : _selectedMap,
                    target : itemName
                }
K
kener 已提交
563 564 565 566
            );
        }

        function init(newOption) {
567
            if (!self.query(newOption, 'legend.data')) {
K
kener 已提交
568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586
                return;
            }

            option = newOption;

            option.legend = self.reformOption(option.legend);
            // 补全padding属性
            option.legend.padding = self.reformCssArray(
                option.legend.padding
            );

            legendOption = option.legend;

            self.clear();

            _selectedMap = {};

            var data = legendOption.data || [];
            var itemName;
K
kener 已提交
587
            var something;
K
kener 已提交
588
            var color;
K
kener 已提交
589
            var queryTarget;
K
kener 已提交
590
            for (var i = 0, dataLength = data.length; i < dataLength; i++) {
591
                itemName = data[i].name || data[i];
K
kener 已提交
592
                if (itemName === '') {
K
kener 已提交
593 594
                    continue;
                }
K
kener 已提交
595 596
                something = _getSomethingByName(itemName);
                if (!something.series) {
K
kener 已提交
597 598 599
                    _selectedMap[itemName] = false;
                } 
                else {
K
kener 已提交
600 601 602 603
                    if (something.data
                        && (something.type == ecConfig.CHART_TYPE_PIE
                            || something.type == ecConfig.CHART_TYPE_FORCE)
                        
K
kener 已提交
604
                    ) {
K
kener 已提交
605 606 607 608 609
                        queryTarget = [something.data, something.series];
                    }
                    else {
                        queryTarget = [something.series];
                    }
K
kener 已提交
610
                    
K
kener 已提交
611 612 613 614 615 616 617
                    color = self.getItemStyleColor(
                        self.deepQuery(
                            queryTarget, 'itemStyle.normal.color'
                        ),
                        something.seriesIndex,
                        something.dataIndex,
                        something.data
K
kener 已提交
618
                    );
K
kener 已提交
619
                    if (color && something.type != ecConfig.CHART_TYPE_K) {
K
kener 已提交
620 621 622 623 624
                        setColor(itemName, color);
                    }
                    _selectedMap[itemName] = true;
                }
            }
K
kener 已提交
625 626 627
            if (selected) {
                for (var k in selected) {
                    _selectedMap[k] = selected[k];
K
kener 已提交
628 629
                }
            }
K
kener 已提交
630
            _buildShape();
K
kener 已提交
631 632 633 634 635
        }

        /**
         * 刷新
         */
K
kener 已提交
636 637 638 639 640 641 642 643
        function refresh(newOption) {
            if (newOption) {
                option = newOption;
                option.legend = self.reformOption(option.legend);
                // 补全padding属性
                option.legend.padding = self.reformCssArray(
                    option.legend.padding
                );
644 645 646 647 648
                if (option.legend.selected) {
                    for (var k in option.legend.selected) {
                        _selectedMap[k] = option.legend.selected[k];
                    }
                }
K
kener 已提交
649
            }
K
kener 已提交
650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
            legendOption = option.legend;
            self.clear();
            _buildShape();
        }

        function setColor(legendName, color) {
            _colorMap[legendName] = color;
        }

        function getColor(legendName) {
            if (!_colorMap[legendName]) {
                _colorMap[legendName] = zr.getColor(_colorIndex++);
            }
            return _colorMap[legendName];
        }
K
kener 已提交
665 666 667 668
        
        function hasColor(legendName) {
            return _colorMap[legendName] ? _colorMap[legendName] : false;
        }
K
kener 已提交
669

K
kener 已提交
670
        function add(name, color){
K
kener 已提交
671 672 673 674 675 676 677 678 679 680 681 682
            legendOption.data.push(name);
            setColor(name,color);
            _selectedMap[name] = true;
        }

        function del(name){
            var data = legendOption.data;
            var finalData = [];
            var found = false;
            for (var i = 0, dataLength = data.length; i < dataLength; i++) {
                if (found || data[i] != name) {
                    finalData.push(data[i]);
K
kener 已提交
683 684
                }
                else {
K
kener 已提交
685 686 687 688 689 690
                    found = true;
                    continue;
                }
            }
            legendOption.data = finalData;
        }
691 692 693 694 695 696 697
        
        /**
         * 特殊图形元素回调设置
         * @param {Object} name
         * @param {Object} itemShape
         */
        function getItemShape(name) {
K
kener 已提交
698 699 700
            if (typeof name == 'undefined') {
                return;
            }
701 702 703
            var shape;
            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                shape = self.shapeList[i];
K
kener 已提交
704
                if (shape._name == name && shape.type != 'text') {
705 706 707 708 709 710 711 712 713 714 715 716 717 718
                    return shape;
                }
            }
        }
        
        /**
         * 特殊图形元素回调设置
         * @param {Object} name
         * @param {Object} itemShape
         */
        function setItemShape(name, itemShape) {
            var shape;
            for (var i = 0, l = self.shapeList.length; i < l; i++) {
                shape = self.shapeList[i];
K
kener 已提交
719
                if (shape._name == name && shape.type != 'text') {
720 721 722 723
                    if (!_selectedMap[name]) {
                        itemShape.style.color = '#ccc';
                        itemShape.style.strokeColor = '#ccc';
                    }
K
kener 已提交
724
                    zr.modShape(shape.id, itemShape);
725 726 727
                }
            }
        }
K
kener 已提交
728 729 730 731 732 733 734 735 736 737

        function isSelected(itemName) {
            if (typeof _selectedMap[itemName] != 'undefined') {
                return _selectedMap[itemName];
            }
            else {
                // 没在legend里定义的都为true啊~
                return true;
            }
        }
K
kener 已提交
738 739 740 741
        
        function getSelectedMap() {
            return _selectedMap;
        }
K
kener 已提交
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
        
        /**
         * 图例选择
         */
        function onlegendSelected(param, status) {
            var legendSelected = param.selected;
            for (var itemName in _selectedMap) {
                if (_selectedMap[itemName] != legendSelected[itemName]) {
                    // 有一项不一致都需要重绘
                    status.needRefresh = true;
                }
                _selectedMap[itemName] = legendSelected[itemName];
            }
            return;
        }
K
kener 已提交
757 758 759 760 761

        self.init = init;
        self.refresh = refresh;
        self.setColor = setColor;
        self.getColor = getColor;
K
kener 已提交
762
        self.hasColor = hasColor;
K
kener 已提交
763 764
        self.add = add;
        self.del = del;
765 766
        self.getItemShape = getItemShape;
        self.setItemShape = setItemShape;
K
kener 已提交
767
        self.isSelected = isSelected;
K
kener 已提交
768
        self.getSelectedMap = getSelectedMap;
K
kener 已提交
769
        self.onlegendSelected = onlegendSelected;
K
kener 已提交
770 771 772

        init(option);
    }
773 774 775 776 777 778 779 780 781 782 783 784
    
    var legendIcon = {
        line : function (ctx, style) {
            var dy = style.height / 2;
            ctx.moveTo(style.x,     style.y + dy);
            ctx.lineTo(style.x + style.width,style.y + dy);
        },
        pie : function (ctx, style) {
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
K
kener 已提交
785
            SectorShape.prototype.buildPath(ctx, {
786 787 788 789 790 791 792
                x : x + width / 2,
                y : y + height + 2,
                r : height + 2,
                r0 : 6,
                startAngle : 45,
                endAngle : 135
            });
K
kener 已提交
793
        }, 
K
kener 已提交
794 795 796 797 798 799
        chord : function(ctx, style) {
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
            ctx.moveTo(x, y + height);
K
kener 已提交
800
            BeziercurveShape.prototype.buildPath(ctx, {
K
kener 已提交
801 802 803 804 805 806 807
                xStart : x,
                yStart : y + height,
                cpX1 : x + width,
                cpY1 : y + height,
                cpX2 : x,
                cpY2 : y + 4,
                xEnd : x + width,
K
,号  
kener 已提交
808
                yEnd : y + 4
K
kener 已提交
809 810
            });
            ctx.lineTo(x + width, y);
K
kener 已提交
811
            BeziercurveShape.prototype.buildPath(ctx, {
K
kener 已提交
812 813 814 815 816 817 818
                xStart : x + width,
                yStart : y,
                cpX1 : x,
                cpY1 : y,
                cpX2 : x + width,
                cpY2 : y + height - 4,
                xEnd : x,
K
,号  
kener 已提交
819
                yEnd : y + height - 4
K
kener 已提交
820 821 822
            });
            ctx.lineTo(x, y + height);
        },
823 824 825 826 827
        k : function (ctx, style) {
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
K
kener 已提交
828
            CandleShape.prototype.buildPath(ctx, {
829 830 831 832 833 834
                x : x + width / 2,
                y : [y + 1, y + 1, y + height - 6, y + height],
                width : width - 6
            });
        },
        bar : function (ctx, style) {
K
kener 已提交
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
            var x = style.x;
            var y = style.y +1;
            var width = style.width;
            var height = style.height - 2;
            var r = 3;
            
            ctx.moveTo(x + r, y);
            ctx.lineTo(x + width - r, y);
            ctx.quadraticCurveTo(
                x + width, y, x + width, y + r
            );
            ctx.lineTo(x + width, y + height - r);
            ctx.quadraticCurveTo(
                x + width, y + height, x + width - r, y + height
            );
            ctx.lineTo(x + r, y + height);
            ctx.quadraticCurveTo(
                x, y + height, x, y + height - r
            );
            ctx.lineTo(x, y + r);
            ctx.quadraticCurveTo(x, y, x + r, y);
K
kener 已提交
856 857
        },
        force : function(ctx, style) {
K
kener 已提交
858
            IconShape.prototype.iconLibrary.circle(ctx, style);
K
kener 已提交
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
        },
        radar: function(ctx, style) {
            var n = 6;
            var x = style.x + style.width / 2;
            var y = style.y + style.height / 2;
            var r = style.height / 2;

            var dStep = 2 * Math.PI / n;
            var deg = -Math.PI / 2;
            var xStart = x + r * Math.cos(deg);
            var yStart = y + r * Math.sin(deg);
            
            ctx.moveTo(xStart, yStart);
            deg += dStep;
            for (var i = 0, end = n - 1; i < end; i ++) {
                ctx.lineTo(x + r * Math.cos(deg), y + r * Math.sin(deg));
                deg += dStep;
            }
            ctx.lineTo(xStart, yStart);
878
        }
K
kener 已提交
879
    };
880
    
881 882
    require('../component').define('legend', Legend);
    
K
kener 已提交
883 884 885 886
    return Legend;
});