legend.js 35.9 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 11
    var Base = require('./base');
    
    // 图形依赖
K
kener 已提交
12 13
    var TextShape = require('zrender/shape/Text');
    var RectangleShape = require('zrender/shape/Rectangle');
K
kener 已提交
14
    var SectorShape = require('zrender/shape/Sector');
K
kener 已提交
15
    //var BeziercurveShape = require('zrender/shape/Beziercurve');
K
kener 已提交
16
    var IconShape = require('../util/shape/Icon');
K
kener 已提交
17
    var CandleShape = require('../util/shape/Candle');
K
kener 已提交
18
    
K
kener 已提交
19 20 21 22
    var ecConfig = require('../config');
    var zrUtil = require('zrender/tool/util');
    var zrArea = require('zrender/tool/area');

K
kener 已提交
23 24 25 26 27 28
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表参数
     */
K
kener 已提交
29 30
    function Legend(ecTheme, messageCenter, zr, option, myChart) {
        if (!this.query(option, 'legend.data')) {
K
jshint  
kener 已提交
31
            console.error('option.legend.data has not been defined.');
K
kener 已提交
32 33 34 35
            return;
        }
        
        Base.call(this, ecTheme, messageCenter, zr, option, myChart);
K
kener 已提交
36
        
K
jshint  
kener 已提交
37 38 39 40 41
        var self = this;
        self._legendSelected = function (param) {
            self.__legendSelected(param);
        };
        
K
kener 已提交
42 43 44 45 46
        this._colorIndex = 0;
        this._colorMap = {};
        this._selectedMap = {};
        
        this.refresh(option);
K
kener 已提交
47 48 49 50 51
    }
    
    Legend.prototype = {
        type : ecConfig.COMPONENT_TYPE_LEGEND,
        _buildShape : function () {
K
kener 已提交
52
            // 图例元素组的位置参数,通过计算所得x, y, width, height
K
kener 已提交
53
            this._itemGroupLocation = this._getItemGroupLocation();
K
kener 已提交
54

K
kener 已提交
55 56
            this._buildBackground();
            this._buildItem();
K
kener 已提交
57

K
kener 已提交
58 59
            for (var i = 0, l = this.shapeList.length; i < l; i++) {
                this.zr.addShape(this.shapeList[i]);
K
kener 已提交
60
            }
K
kener 已提交
61
        },
K
kener 已提交
62 63 64 65

        /**
         * 构建所有图例元素
         */
K
kener 已提交
66 67
        _buildItem : function () {
            var data = this.legendOption.data;
K
kener 已提交
68 69 70 71 72
            var dataLength = data.length;
            var itemName;
            var itemType;
            var itemShape;
            var textShape;
K
kener 已提交
73
            var textStyle  = this.legendOption.textStyle;
74 75
            var dataTextStyle;
            var dataFont;
F
fanlia 已提交
76
	    var formattedName;
K
kener 已提交
77

K
kener 已提交
78 79 80 81 82 83 84
            var zrWidth = this.zr.getWidth();
            var zrHeight = this.zr.getHeight();
            var lastX = this._itemGroupLocation.x;
            var lastY = this._itemGroupLocation.y;
            var itemWidth = this.legendOption.itemWidth;
            var itemHeight = this.legendOption.itemHeight;
            var itemGap = this.legendOption.itemGap;
K
kener 已提交
85 86
            var color;

K
kener 已提交
87
            if (this.legendOption.orient == 'vertical' && this.legendOption.x == 'right') {
K
kener 已提交
88 89
                lastX = this._itemGroupLocation.x
                        + this._itemGroupLocation.width
K
kener 已提交
90 91 92 93
                        - itemWidth;
            }

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

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

                // 图形
K
kener 已提交
145
                itemShape = this._getItemShapeByType(
K
kener 已提交
146 147
                    lastX, lastY,
                    itemWidth, itemHeight,
K
kener 已提交
148
                    (this._selectedMap[itemName] ? color : '#ccc'),
149 150
                    itemType,
                    color
K
kener 已提交
151 152
                );
                itemShape._name = itemName;
K
kener 已提交
153
                itemShape = new IconShape(itemShape);
K
kener 已提交
154 155 156

                // 文字
                textShape = {
K
kener 已提交
157
                    // shape : 'text',
K
kener 已提交
158
                    zlevel : this._zlevelBase,
K
kener 已提交
159 160
                    style : {
                        x : lastX + itemWidth + 5,
K
kener 已提交
161
                        y : lastY + itemHeight / 2,
K
kener 已提交
162
                        color : this._selectedMap[itemName]
163
                                ? (dataTextStyle.color === 'auto' ? color : dataTextStyle.color)
K
kener 已提交
164
                                : '#ccc',
F
fanlia 已提交
165
                        text: formattedName,
166
                        textFont: dataFont,
K
kener 已提交
167
                        textBaseline: 'middle'
K
kener 已提交
168
                    },
169 170 171 172
                    highlightStyle : {
                        color : color,
                        brushType: 'fill'
                    },
K
kener 已提交
173 174
                    hoverable : !!this.legendOption.selectedMode,
                    clickable : !!this.legendOption.selectedMode
K
kener 已提交
175 176
                };

K
kener 已提交
177 178
                if (this.legendOption.orient == 'vertical'
                    && this.legendOption.x == 'right'
K
kener 已提交
179 180 181 182 183 184
                ) {
                    textShape.style.x -= (itemWidth + 10);
                    textShape.style.textAlign = 'right';
                }

                textShape._name = itemName;
K
kener 已提交
185 186
                textShape = new TextShape(textShape);
                
K
kener 已提交
187
                if (this.legendOption.selectedMode) {
K
jshint  
kener 已提交
188
                    itemShape.onclick = textShape.onclick = this._legendSelected;
K
kener 已提交
189 190 191
                    itemShape.onmouseover =  textShape.onmouseover = this.hoverConnect;
                    itemShape.hoverConnect = textShape.id;
                    textShape.hoverConnect = itemShape.id;
192
                }
K
kener 已提交
193 194
                this.shapeList.push(itemShape);
                this.shapeList.push(textShape);
K
kener 已提交
195

K
kener 已提交
196
                if (this.legendOption.orient == 'horizontal') {
K
kener 已提交
197
                    lastX += itemWidth + 5
F
fanlia 已提交
198
                             + zrArea.getTextWidth(formattedName, dataFont)
K
kener 已提交
199 200 201 202 203 204
                             + itemGap;
                }
                else {
                    lastY += itemHeight + itemGap;
                }
            }
K
kener 已提交
205
        
K
kener 已提交
206 207 208
            if (this.legendOption.orient == 'horizontal'
                && this.legendOption.x == 'center'
                && lastY != this._itemGroupLocation.y
K
kener 已提交
209 210
            ) {
                // 多行橫排居中优化
K
kener 已提交
211
                this._mLineOptimize();
K
kener 已提交
212
            }
K
kener 已提交
213
        },
K
kener 已提交
214
        
K
kener 已提交
215 216 217
        _getName : function(data) {
            return typeof data.name != 'undefined' ? data.name : data;
        },
F
fanlia 已提交
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

        _getFormatterName: function(itemName) {
            var formatter = this.legendOption.formatter;
            var formattedName;
            if (typeof formatter == 'function') {
                formattedName = formatter.call(this.myChart, itemName);
            }
            else if (typeof formatter == 'string') {
                formattedName = formatter.replace('{name}', itemName);
            }
            else {
                formattedName = itemName;
            }
            return formattedName;
        },

        _getFormatterNameFromData: function(data) {
            var itemName = this._getName(data);
            return this._getFormatterName(itemName);
        },
K
kener 已提交
238
        
K
kener 已提交
239
        // 多行橫排居中优化
K
kener 已提交
240
        _mLineOptimize : function () {
K
kener 已提交
241
            var lineOffsetArray = []; // 每行宽度
K
kener 已提交
242 243 244
            var lastX = this._itemGroupLocation.x;
            for (var i = 2, l = this.shapeList.length; i < l; i++) {
                if (this.shapeList[i].style.x == lastX) {
K
kener 已提交
245 246
                    lineOffsetArray.push(
                        (
K
kener 已提交
247
                            this._itemGroupLocation.width 
K
kener 已提交
248
                            - (
K
kener 已提交
249
                                this.shapeList[i - 1].style.x
K
kener 已提交
250
                                + zrArea.getTextWidth(
K
kener 已提交
251 252
                                      this.shapeList[i - 1].style.text,
                                      this.shapeList[i - 1].style.textFont
K
kener 已提交
253 254 255 256 257
                                  )
                                - lastX
                            )
                        ) / 2
                    );
K
kener 已提交
258
                }
K
kener 已提交
259 260 261
                else if (i == l - 1) {
                    lineOffsetArray.push(
                        (
K
kener 已提交
262
                            this._itemGroupLocation.width 
K
kener 已提交
263
                            - (
K
kener 已提交
264
                                this.shapeList[i].style.x
K
kener 已提交
265
                                + zrArea.getTextWidth(
K
kener 已提交
266 267
                                      this.shapeList[i].style.text,
                                      this.shapeList[i].style.textFont
K
kener 已提交
268 269 270 271 272 273 274 275
                                  )
                                - lastX
                            )
                        ) / 2
                    );
                }
            }
            var curLineIndex = -1;
K
kener 已提交
276 277
            for (var i = 1, l = this.shapeList.length; i < l; i++) {
                if (this.shapeList[i].style.x == lastX) {
K
kener 已提交
278 279 280 281 282 283
                    curLineIndex++;
                }
                if (lineOffsetArray[curLineIndex] === 0) {
                    continue;
                }
                else {
K
kener 已提交
284
                    this.shapeList[i].style.x += lineOffsetArray[curLineIndex];
K
kener 已提交
285 286
                }
            }
K
kener 已提交
287
        },
K
kener 已提交
288

K
kener 已提交
289 290 291 292 293
        _buildBackground : function () {
            var pTop = this.legendOption.padding[0];
            var pRight = this.legendOption.padding[1];
            var pBottom = this.legendOption.padding[2];
            var pLeft = this.legendOption.padding[3];
K
kener 已提交
294

K
kener 已提交
295 296
            this.shapeList.push(new RectangleShape({
                zlevel : this._zlevelBase,
K
kener 已提交
297 298
                hoverable :false,
                style : {
K
kener 已提交
299 300 301 302
                    x : this._itemGroupLocation.x - pLeft,
                    y : this._itemGroupLocation.y - pTop,
                    width : this._itemGroupLocation.width + pLeft + pRight,
                    height : this._itemGroupLocation.height + pTop + pBottom,
K
kener 已提交
303
                    brushType : this.legendOption.borderWidth === 0 ? 'fill' : 'both',
K
kener 已提交
304 305 306
                    color : this.legendOption.backgroundColor,
                    strokeColor : this.legendOption.borderColor,
                    lineWidth : this.legendOption.borderWidth
K
kener 已提交
307
                }
K
kener 已提交
308
            }));
K
kener 已提交
309
        },
K
kener 已提交
310 311 312 313

        /**
         * 根据选项计算图例实体的位置坐标
         */
K
kener 已提交
314 315
        _getItemGroupLocation : function () {
            var data = this.legendOption.data;
K
kener 已提交
316
            var dataLength = data.length;
K
kener 已提交
317 318 319 320 321
            var itemGap = this.legendOption.itemGap;
            var itemWidth = this.legendOption.itemWidth + 5; // 5px是图形和文字的间隔,不可配
            var itemHeight = this.legendOption.itemHeight;
            var textStyle  = this.legendOption.textStyle;
            var font = this.getFont(textStyle);
K
kener 已提交
322 323
            var totalWidth = 0;
            var totalHeight = 0;
K
kener 已提交
324 325 326
            var padding = this.legendOption.padding;
            var zrWidth = this.zr.getWidth() - padding[1] - padding[3];
            var zrHeight = this.zr.getHeight() - padding[0] - padding[2];
K
kener 已提交
327 328 329
            
            var temp = 0; // 宽高计算,用于多行判断
            var maxWidth = 0; // 垂直布局有用
K
kener 已提交
330
            if (this.legendOption.orient == 'horizontal') {
K
kener 已提交
331
                // 水平布局,计算总宽度
K
kener 已提交
332
                totalHeight = itemHeight;
K
kener 已提交
333
                for (var i = 0; i < dataLength; i++) {
K
kener 已提交
334
                    if (this._getName(data[i]) === '') {
K
kener 已提交
335 336 337 338 339 340 341 342 343 344 345 346 347 348
                        temp -= itemGap;
                        if (temp > zrWidth) {
                            totalWidth = zrWidth;
                            totalHeight += itemHeight + itemGap;
                        }
                        else {
                            totalWidth = Math.max(totalWidth, temp);
                        }
                        totalHeight += itemHeight + itemGap;
                        temp = 0;
                        continue;
                    }
                    temp += itemWidth
                            + zrArea.getTextWidth(
F
fanlia 已提交
349
                                  this._getFormatterNameFromData(data[i]),
350
                                  data[i].textStyle 
K
kener 已提交
351
                                  ? this.getFont(zrUtil.merge(
352
                                        data[i].textStyle || {},
K
kener 已提交
353
                                        textStyle
354 355
                                    ))
                                  : font
K
kener 已提交
356 357 358 359 360 361 362 363 364 365
                              )
                            + 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 已提交
366 367 368 369 370 371 372 373
                }
            }
            else {
                // 垂直布局,计算总高度
                for (var i = 0; i < dataLength; i++) {
                    maxWidth = Math.max(
                        maxWidth,
                        zrArea.getTextWidth(
F
fanlia 已提交
374
                            this._getFormatterNameFromData(data[i]),
375
                            data[i].textStyle 
K
kener 已提交
376
                            ? this.getFont(zrUtil.merge(
377
                                  data[i].textStyle || {},
K
kener 已提交
378
                                  textStyle
379 380
                              ))
                            : font
K
kener 已提交
381 382 383
                        )
                    );
                }
K
kener 已提交
384 385 386
                maxWidth += itemWidth;
                totalWidth = maxWidth;
                for (var i = 0; i < dataLength; i++) {
K
kener 已提交
387
                    if (this._getName(data[i]) === '') {
K
kener 已提交
388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
                        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 已提交
410 411
            }

K
kener 已提交
412 413
            zrWidth = this.zr.getWidth();
            zrHeight = this.zr.getHeight();
K
kener 已提交
414
            var x;
K
kener 已提交
415
            switch (this.legendOption.x) {
K
kener 已提交
416 417 418 419
                case 'center' :
                    x = Math.floor((zrWidth - totalWidth) / 2);
                    break;
                case 'left' :
K
kener 已提交
420
                    x = this.legendOption.padding[3] + this.legendOption.borderWidth;
K
kener 已提交
421 422 423 424
                    break;
                case 'right' :
                    x = zrWidth
                        - totalWidth
K
kener 已提交
425 426 427
                        - this.legendOption.padding[1]
                        - this.legendOption.padding[3]
                        - this.legendOption.borderWidth * 2;
K
kener 已提交
428 429
                    break;
                default :
K
kener 已提交
430
                    x = this.parsePercent(this.legendOption.x, zrWidth);
K
kener 已提交
431 432
                    break;
            }
K
kener 已提交
433
            
K
kener 已提交
434
            var y;
K
kener 已提交
435
            switch (this.legendOption.y) {
K
kener 已提交
436
                case 'top' :
K
kener 已提交
437
                    y = this.legendOption.padding[0] + this.legendOption.borderWidth;
K
kener 已提交
438 439 440 441
                    break;
                case 'bottom' :
                    y = zrHeight
                        - totalHeight
K
kener 已提交
442 443 444
                        - this.legendOption.padding[0]
                        - this.legendOption.padding[2]
                        - this.legendOption.borderWidth * 2;
K
kener 已提交
445 446 447 448 449
                    break;
                case 'center' :
                    y = Math.floor((zrHeight - totalHeight) / 2);
                    break;
                default :
K
kener 已提交
450
                    y = this.parsePercent(this.legendOption.y, zrHeight);
K
kener 已提交
451 452 453 454 455 456 457
                    break;
            }

            return {
                x : x,
                y : y,
                width : totalWidth,
K
kener 已提交
458 459
                height : totalHeight,
                maxWidth : maxWidth
K
kener 已提交
460
            };
K
kener 已提交
461
        },
K
kener 已提交
462 463

        /**
K
kener 已提交
464
         * 根据名称返回series数据或data
K
kener 已提交
465
         */
K
kener 已提交
466 467
        _getSomethingByName : function (name) {
            var series = this.option.series;
K
kener 已提交
468
            var data;
K
kener 已提交
469 470 471
            for (var i = 0, l = series.length; i < l; i++) {
                if (series[i].name == name) {
                    // 系列名称优先
K
kener 已提交
472 473 474 475 476 477
                    return {
                        type : series[i].type,
                        series : series[i],
                        seriesIndex : i,
                        data : null,
                        dataIndex : -1
K
kener 已提交
478
                    };
K
kener 已提交
479 480
                }

K
kener 已提交
481 482 483
                if (
                    series[i].type == ecConfig.CHART_TYPE_PIE 
                    || series[i].type == ecConfig.CHART_TYPE_RADAR
L
lang 已提交
484
                    || series[i].type == ecConfig.CHART_TYPE_CHORD
K
kener 已提交
485
                    || series[i].type == ecConfig.CHART_TYPE_FORCE
K
kener 已提交
486
                    || series[i].type == ecConfig.CHART_TYPE_FUNNEL
K
kener 已提交
487
                ) {
K
kener 已提交
488 489 490
                    data = series[i].type != ecConfig.CHART_TYPE_FORCE
                           ? series[i].data         // 饼图、雷达图、和弦图得查找里面的数据名字
                           : series[i].categories;  // 力导布局查找categories配置
K
kener 已提交
491 492
                    for (var j = 0, k = data.length; j < k; j++) {
                        if (data[j].name == name) {
K
kener 已提交
493 494 495 496 497 498
                            return {
                                type : series[i].type,
                                series : series[i],
                                seriesIndex : i,
                                data : data[j],
                                dataIndex : j
K
kener 已提交
499
                            };
K
kener 已提交
500 501
                        }
                    }
K
kener 已提交
502
                }
K
kener 已提交
503
            }
K
kener 已提交
504 505 506 507 508 509
            return {
                type : 'bar',
                series : null,
                seriesIndex : -1,
                data : null,
                dataIndex : -1
K
kener 已提交
510
            };
K
kener 已提交
511
        },
K
kener 已提交
512
        
K
kener 已提交
513
        _getItemShapeByType : function (x, y, width, height, color, itemType, defaultColor) {
K
kener 已提交
514
            var highlightColor = color === '#ccc' ? defaultColor : color;
515
            var itemShape = {
K
kener 已提交
516
                zlevel : this._zlevelBase,
517
                style : {
K
kener 已提交
518
                    iconType : 'legendicon' + itemType,
519 520 521 522 523 524
                    x : x,
                    y : y,
                    width : width,
                    height : height,
                    color : color,
                    strokeColor : color,
525 526 527 528 529 530
                    lineWidth : 2
                },
                highlightStyle: {
                    color : highlightColor,
                    strokeColor : highlightColor,
                    lineWidth : 1
531
                },
K
kener 已提交
532 533
                hoverable : this.legendOption.selectedMode,
                clickable : this.legendOption.selectedMode
534
            };
K
kener 已提交
535 536 537 538 539 540 541 542
            
            var imageLocation;
            if (itemType.match('image')) {
                var imageLocation = itemType.replace(
                    new RegExp('^image:\\/\\/'), ''
                );
                itemType = 'image';
            }
543
            // 特殊设置
K
kener 已提交
544 545
            switch (itemType) {
                case 'line' :
546
                    itemShape.style.brushType = 'stroke';
547 548 549 550 551
                    itemShape.highlightStyle.lineWidth = 3;
                    break;
                case 'radar' :
                case 'scatter' :   
                    itemShape.highlightStyle.lineWidth = 3;
552
                    break;
K
kener 已提交
553
                case 'k' :
554
                    itemShape.style.brushType = 'both';
555 556
                    itemShape.highlightStyle.lineWidth = 3;
                    itemShape.highlightStyle.color =
K
kener 已提交
557 558
                    itemShape.style.color = this.query(this.ecTheme, 'k.itemStyle.normal.color') 
                                            || '#fff';
559
                    itemShape.style.strokeColor = color != '#ccc' 
K
kener 已提交
560 561
                        ? (this.query(this.ecTheme, 'k.itemStyle.normal.lineStyle.color') 
                           || '#ff3200')
562
                        : color;
K
kener 已提交
563 564 565 566 567 568 569 570
                    break;
                case 'image' :
                    itemShape.style.iconType = 'image';
                    itemShape.style.image = imageLocation;
                    if (color === '#ccc') {
                        itemShape.style.opacity = 0.5;
                    }
                    break;
K
kener 已提交
571
            }
572
            return itemShape;
K
kener 已提交
573
        },
K
kener 已提交
574

K
jshint  
kener 已提交
575
        __legendSelected : function (param) {
K
kener 已提交
576
            var itemName = param.target._name;
K
kener 已提交
577 578 579
            if (this.legendOption.selectedMode === 'single') {
                for (var k in this._selectedMap) {
                    this._selectedMap[k] = false;
K
kener 已提交
580 581
                }
            }
K
kener 已提交
582 583
            this._selectedMap[itemName] = !this._selectedMap[itemName];
            this.messageCenter.dispatch(
K
kener 已提交
584 585
                ecConfig.EVENT.LEGEND_SELECTED,
                param.event,
K
kener 已提交
586
                {
K
kener 已提交
587
                    selected : this._selectedMap,
K
kener 已提交
588
                    target : itemName
K
kener 已提交
589 590
                },
                this.myChart
K
kener 已提交
591
            );
K
kener 已提交
592
        },
K
kener 已提交
593 594 595 596

        /**
         * 刷新
         */
K
kener 已提交
597 598
        refresh : function (newOption) {
            if (newOption) {
K
kener 已提交
599
                this.option = newOption || this.option;
K
kener 已提交
600
                this.option.legend = this.reformOption(this.option.legend);
K
kener 已提交
601
                // 补全padding属性
K
kener 已提交
602 603
                this.option.legend.padding = this.reformCssArray(
                    this.option.legend.padding
K
kener 已提交
604
                );
K
kener 已提交
605 606 607 608 609 610 611
                this.legendOption = this.option.legend;
                
                var data = this.legendOption.data || [];
                var itemName;
                var something;
                var color;
                var queryTarget;
K
kener 已提交
612 613 614 615 616 617 618
                if (this.legendOption.selected) {
                    for (var k in this.legendOption.selected) {
                        this._selectedMap[k] = typeof this._selectedMap[k] != 'undefined'
                                               ? this._selectedMap[k]
                                               : this.legendOption.selected[k];
                    }
                }
K
kener 已提交
619
                for (var i = 0, dataLength = data.length; i < dataLength; i++) {
K
kener 已提交
620
                    itemName = this._getName(data[i]);
K
kener 已提交
621 622 623 624 625 626 627 628 629 630
                    if (itemName === '') {
                        continue;
                    }
                    something = this._getSomethingByName(itemName);
                    if (!something.series) {
                        this._selectedMap[itemName] = false;
                    } 
                    else {
                        if (something.data
                            && (something.type == ecConfig.CHART_TYPE_PIE
K
kener 已提交
631 632
                                || something.type == ecConfig.CHART_TYPE_FORCE
                                || something.type == ecConfig.CHART_TYPE_FUNNEL)
K
kener 已提交
633 634 635 636 637 638 639 640
                        ) {
                            queryTarget = [something.data, something.series];
                        }
                        else {
                            queryTarget = [something.series];
                        }
                        
                        color = this.getItemStyleColor(
K
kener 已提交
641
                            this.deepQuery(queryTarget, 'itemStyle.normal.color'),
K
kener 已提交
642 643 644 645 646 647 648
                            something.seriesIndex,
                            something.dataIndex,
                            something.data
                        );
                        if (color && something.type != ecConfig.CHART_TYPE_K) {
                            this.setColor(itemName, color);
                        }
K
kener 已提交
649 650 651
                        this._selectedMap[itemName] = 
                            typeof this._selectedMap[itemName] != 'undefined'
                            ? this._selectedMap[itemName] : true; 
K
kener 已提交
652 653
                    }
                }
K
kener 已提交
654
            }
K
kener 已提交
655 656 657
            this.clear();
            this._buildShape();
        },
K
kener 已提交
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
        
        getRelatedAmount : function(name) {
            var amount = 0;
            var series = this.option.series;
            var data;
            for (var i = 0, l = series.length; i < l; i++) {
                if (series[i].name == name) {
                    // 系列名称优先
                    amount++;
                }

                if (
                    series[i].type == ecConfig.CHART_TYPE_PIE 
                    || series[i].type == ecConfig.CHART_TYPE_RADAR
                    || series[i].type == ecConfig.CHART_TYPE_CHORD
                    || series[i].type == ecConfig.CHART_TYPE_FORCE
                    || series[i].type == ecConfig.CHART_TYPE_FUNNEL
                ) {
                    data = series[i].type != ecConfig.CHART_TYPE_FORCE
                           ? series[i].data         // 饼图、雷达图、和弦图得查找里面的数据名字
                           : series[i].categories;  // 力导布局查找categories配置
                    for (var j = 0, k = data.length; j < k; j++) {
                        if (data[j].name == name && data[j].value != '-') {
K
kener 已提交
681
                            amount++;
K
kener 已提交
682 683 684 685 686 687
                        }
                    }
                }
            }
            return amount;
        },
K
kener 已提交
688

K
kener 已提交
689 690 691
        setColor : function (legendName, color) {
            this._colorMap[legendName] = color;
        },
K
kener 已提交
692

K
kener 已提交
693 694 695
        getColor : function (legendName) {
            if (!this._colorMap[legendName]) {
                this._colorMap[legendName] = this.zr.getColor(this._colorIndex++);
K
kener 已提交
696
            }
K
kener 已提交
697 698
            return this._colorMap[legendName];
        },
K
kener 已提交
699
        
K
kener 已提交
700 701 702
        hasColor : function (legendName) {
            return this._colorMap[legendName] ? this._colorMap[legendName] : false;
        },
K
kener 已提交
703

K
kener 已提交
704
        add : function (name, color){
K
kener 已提交
705 706 707 708 709 710 711
            var data = this.legendOption.data;
            for (var i = 0, dataLength = data.length; i < dataLength; i++) {
                if (this._getName(data[i]) == name) {
                    // 已有就不重复加了
                    return;
                }
            }
K
kener 已提交
712 713 714 715
            this.legendOption.data.push(name);
            this.setColor(name,color);
            this._selectedMap[name] = true;
        },
K
kener 已提交
716

K
kener 已提交
717 718
        del : function (name){
            var data = this.legendOption.data;
K
kener 已提交
719
            for (var i = 0, dataLength = data.length; i < dataLength; i++) {
K
kener 已提交
720 721
                if (this._getName(data[i]) == name) {
                    return this.legendOption.data.splice(i, 1);
K
kener 已提交
722 723
                }
            }
K
kener 已提交
724
        },
725 726 727 728 729 730
        
        /**
         * 特殊图形元素回调设置
         * @param {Object} name
         * @param {Object} itemShape
         */
K
kener 已提交
731
        getItemShape : function (name) {
K
kener 已提交
732 733 734
            if (typeof name == 'undefined') {
                return;
            }
735
            var shape;
K
kener 已提交
736 737
            for (var i = 0, l = this.shapeList.length; i < l; i++) {
                shape = this.shapeList[i];
K
kener 已提交
738
                if (shape._name == name && shape.type != 'text') {
739 740 741
                    return shape;
                }
            }
K
kener 已提交
742
        },
743 744 745 746 747 748
        
        /**
         * 特殊图形元素回调设置
         * @param {Object} name
         * @param {Object} itemShape
         */
K
kener 已提交
749
        setItemShape : function (name, itemShape) {
750
            var shape;
K
kener 已提交
751 752
            for (var i = 0, l = this.shapeList.length; i < l; i++) {
                shape = this.shapeList[i];
K
kener 已提交
753
                if (shape._name == name && shape.type != 'text') {
K
kener 已提交
754
                    if (!this._selectedMap[name]) {
755 756 757
                        itemShape.style.color = '#ccc';
                        itemShape.style.strokeColor = '#ccc';
                    }
K
kener 已提交
758
                    this.zr.modShape(shape.id, itemShape);
759 760
                }
            }
K
kener 已提交
761
        },
K
kener 已提交
762

K
kener 已提交
763 764 765
        isSelected : function (itemName) {
            if (typeof this._selectedMap[itemName] != 'undefined') {
                return this._selectedMap[itemName];
K
kener 已提交
766 767 768 769 770
            }
            else {
                // 没在legend里定义的都为true啊~
                return true;
            }
K
kener 已提交
771
        },
K
kener 已提交
772
        
K
kener 已提交
773 774 775
        getSelectedMap : function () {
            return this._selectedMap;
        },
K
kener 已提交
776
        
K
kener 已提交
777 778 779 780 781 782 783 784 785
        setSelected : function(itemName, selectStatus) {
            if (this.legendOption.selectedMode === 'single') {
                for (var k in this._selectedMap) {
                    this._selectedMap[k] = false;
                }
            }
            this._selectedMap[itemName] = selectStatus;
            this.messageCenter.dispatch(
                ecConfig.EVENT.LEGEND_SELECTED,
K
kener 已提交
786
                null,
K
kener 已提交
787 788 789
                {
                    selected : this._selectedMap,
                    target : itemName
K
kener 已提交
790 791
                },
                this.myChart
K
kener 已提交
792 793 794
            );
        },
        
K
kener 已提交
795 796 797
        /**
         * 图例选择
         */
K
kener 已提交
798
        onlegendSelected : function (param, status) {
K
kener 已提交
799
            var legendSelected = param.selected;
K
kener 已提交
800
            for (var itemName in legendSelected) {
K
kener 已提交
801
                if (this._selectedMap[itemName] != legendSelected[itemName]) {
K
kener 已提交
802 803 804
                    // 有一项不一致都需要重绘
                    status.needRefresh = true;
                }
K
kener 已提交
805
                this._selectedMap[itemName] = legendSelected[itemName];
K
kener 已提交
806 807 808
            }
            return;
        }
K
jshint  
kener 已提交
809
    };
810 811 812 813 814 815 816
    
    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);
        },
K
kener 已提交
817
        
818 819 820 821 822
        pie : function (ctx, style) {
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
K
kener 已提交
823
            SectorShape.prototype.buildPath(ctx, {
824 825 826 827 828 829 830
                x : x + width / 2,
                y : y + height + 2,
                r : height + 2,
                r0 : 6,
                startAngle : 45,
                endAngle : 135
            });
K
kener 已提交
831
        },
K
kener 已提交
832
        /*
K
kener 已提交
833
        chord : function (ctx, style) {
K
kener 已提交
834 835 836 837 838
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
            ctx.moveTo(x, y + height);
K
kener 已提交
839
            BeziercurveShape.prototype.buildPath(ctx, {
K
kener 已提交
840 841 842 843 844 845 846
                xStart : x,
                yStart : y + height,
                cpX1 : x + width,
                cpY1 : y + height,
                cpX2 : x,
                cpY2 : y + 4,
                xEnd : x + width,
K
,号  
kener 已提交
847
                yEnd : y + 4
K
kener 已提交
848 849
            });
            ctx.lineTo(x + width, y);
K
kener 已提交
850
            BeziercurveShape.prototype.buildPath(ctx, {
K
kener 已提交
851 852 853 854 855 856 857
                xStart : x + width,
                yStart : y,
                cpX1 : x,
                cpY1 : y,
                cpX2 : x + width,
                cpY2 : y + height - 4,
                xEnd : x,
K
,号  
kener 已提交
858
                yEnd : y + height - 4
K
kener 已提交
859 860 861
            });
            ctx.lineTo(x, y + height);
        },
K
kener 已提交
862
        */
863 864 865 866 867
        k : function (ctx, style) {
            var x = style.x;
            var y = style.y;
            var width = style.width;
            var height = style.height;
K
kener 已提交
868
            CandleShape.prototype.buildPath(ctx, {
869 870 871 872 873
                x : x + width / 2,
                y : [y + 1, y + 1, y + height - 6, y + height],
                width : width - 6
            });
        },
K
kener 已提交
874
        
875
        bar : function (ctx, style) {
K
kener 已提交
876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
            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 已提交
897
        },
K
kener 已提交
898
        
K
kener 已提交
899
        force : function (ctx, style) {
K
kener 已提交
900
            IconShape.prototype.iconLibrary.circle(ctx, style);
K
kener 已提交
901
        },
K
kener 已提交
902
        
K
kener 已提交
903
        radar: function (ctx, style) {
K
kener 已提交
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
            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);
921
        }
K
kener 已提交
922
    };
K
kener 已提交
923 924
    legendIcon.chord = legendIcon.pie;
    legendIcon.map = legendIcon.bar;
925
    
K
kener 已提交
926 927 928 929
    for (var k in legendIcon) {
        IconShape.prototype.iconLibrary['legendicon' + k] = legendIcon[k];
    }
    
K
kener 已提交
930 931
    zrUtil.inherits(Legend, Base);
    
932 933
    require('../component').define('legend', Legend);
    
K
kener 已提交
934 935 936 937
    return Legend;
});