categoryAxis.js 32.1 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 14 15
    var TextShape = require('zrender/shape/Text');
    var LineShape = require('zrender/shape/Line');
    var RectangleShape = require('zrender/shape/Rectangle');
    
K
kener 已提交
16 17 18 19
    var ecConfig = require('../config');
    var zrUtil = require('zrender/tool/util');
    var zrArea = require('zrender/tool/area');
    
K
kener 已提交
20 21 22 23 24
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 类目轴参数
K
kener 已提交
25
     * @param {Grid} component 组件
K
kener 已提交
26
     */
K
kener 已提交
27 28 29
    function CategoryAxis(ecTheme, messageCenter, zr, option, component) {
        Base.call(this, ecTheme, zr, option);
        
K
kener 已提交
30
        this.init(option, component);
K
kener 已提交
31 32 33 34 35 36 37
    }
    
    CategoryAxis.prototype = {
        type : ecConfig.COMPONENT_TYPE_AXIS_CATEGORY,
        _reformLabel : function () {
            var data = zrUtil.clone(this.option.data);
            var axisFormatter = this.option.axisLabel.formatter;
K
kener 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
            var formatter;
            for (var i = 0, l = data.length; i < l; i++) {
                formatter = data[i].formatter || axisFormatter;
                if (formatter) {
                    if (typeof formatter == 'function') {
                        if (typeof data[i].value != 'undefined') {
                            data[i].value = formatter(data[i].value);
                        }
                        else {
                            data[i] = formatter(data[i]);
                        }
                    }
                    else if (typeof formatter == 'string') {
                        if (typeof data[i].value != 'undefined') {
                            data[i].value = formatter.replace(
                                '{value}',data[i].value
                            );
                        }
                        else {
                            data[i] = formatter.replace('{value}',data[i]);
                        }
                    }
                }
            }
            return data;
K
kener 已提交
63
        },
K
kener 已提交
64 65 66 67

        /**
         * 计算标签显示挑选间隔
         */
K
kener 已提交
68 69
        _getInterval : function () {
            var interval   = this.option.axisLabel.interval;
K
kener 已提交
70 71
            if (interval == 'auto') {
                // 麻烦的自适应计算
K
kener 已提交
72 73 74 75
                var fontSize = this.option.axisLabel.textStyle.fontSize;
                var font = this.getFont(this.option.axisLabel.textStyle);
                var data = this.option.data;
                var dataLength = this.option.data.length;
K
kener 已提交
76

K
kener 已提交
77
                if (this.option.position == 'bottom' || this.option.position == 'top') {
K
kener 已提交
78 79
                    // 横向
                    if (dataLength > 3) {
K
kener 已提交
80
                        var gap = this.getGap();
K
kener 已提交
81 82 83 84 85 86 87 88 89
                        var isEnough = false;
                        var labelSpace;
                        var labelSize;
                        interval = 0;
                        while (!isEnough && interval < dataLength) {
                            interval++;
                            isEnough = true;
                            labelSpace = gap * interval - 10; // 标签左右至少间隔为5px
                            for (var i = 0; i < dataLength; i += interval) {
K
kener 已提交
90
                                if (this.option.axisLabel.rotate !== 0) {
K
kener 已提交
91 92 93 94 95
                                    // 有旋转
                                    labelSize = fontSize;
                                }
                                else if (data[i].textStyle) {
                                    labelSize = zrArea.getTextWidth(
K
kener 已提交
96 97
                                        this._labelData[i].value || this._labelData[i],
                                        this.getFont(
K
kener 已提交
98 99
                                            zrUtil.merge(
                                                data[i].textStyle,
K
kener 已提交
100
                                                this.option.axisLabel.textStyle
K
kener 已提交
101 102 103 104 105 106
                                           )
                                        )
                                    );
                                }
                                else {
                                    labelSize = zrArea.getTextWidth(
K
kener 已提交
107
                                        this._labelData[i].value || this._labelData[i],
K
kener 已提交
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
                                        font
                                    );
                                }

                                if (labelSpace < labelSize) {
                                    // 放不下,中断循环让interval++
                                    isEnough = false;
                                    break;
                                }
                            }
                        }
                    }
                    else {
                        // 少于3个则全部显示
                        interval = 1;
                    }
                }
                else {
                    // 纵向
                    if (dataLength > 3) {
K
kener 已提交
128
                        var gap = this.getGap();
K
kener 已提交
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
                        interval = 1;
                        // 标签上下至少间隔为3px
                        while ((gap * interval - 6) < fontSize
                                && interval < dataLength
                        ) {
                            interval++;
                        }
                    }
                    else {
                        // 少于3个则全部显示
                        interval = 1;
                    }
                }
            }
            else {
                // 用户自定义间隔
                interval += 1;
            }

            return interval;
K
kener 已提交
149
        },
K
kener 已提交
150 151 152 153
        
        /**
         * 绘制图形
         */
K
kener 已提交
154 155 156 157 158 159 160 161 162 163 164 165 166 167
        _buildShape : function () {
            // 标签文字格式化
            this._labelData = this._reformLabel();
            // 标签显示的挑选间隔
            this._interval = this._getInterval();
            
            this.option.splitArea.show && this._buildSplitArea();
            this.option.splitLine.show && this._buildSplitLine();
            this.option.axisLine.show && this._buildAxisLine();
            this.option.axisTick.show && this._buildAxisTick();
            this.option.axisLabel.show && this._buildAxisLabel();

            for (var i = 0, l = this.shapeList.length; i < l; i++) {
                this.zr.addShape(this.shapeList[i]);
K
kener 已提交
168
            }
K
kener 已提交
169
        },
K
kener 已提交
170 171

        // 轴线
K
kener 已提交
172 173
        _buildAxisLine : function () {
            var lineWidth = this.option.axisLine.lineStyle.width;
K
kener 已提交
174
            var halfLineWidth = lineWidth / 2;
K
kener 已提交
175 176
            var axShape = {
                shape : 'line',
K
kener 已提交
177
                zlevel : this._zlevelBase + 1,
K
kener 已提交
178
                hoverable : false
K
kener 已提交
179
            };
K
kener 已提交
180
            switch (this.option.position) {
K
kener 已提交
181
                case 'left' :
K
kener 已提交
182
                    axShape.style = {
K
kener 已提交
183 184 185 186
                        xStart : this.grid.getX() - halfLineWidth,
                        yStart : this.grid.getYend() + halfLineWidth,
                        xEnd : this.grid.getX() - halfLineWidth,
                        yEnd : this.grid.getY() - halfLineWidth
K
kener 已提交
187 188
                    };
                    break;
K
kener 已提交
189
                case 'right' :
K
kener 已提交
190
                    axShape.style = {
K
kener 已提交
191 192 193 194
                        xStart : this.grid.getXend() + halfLineWidth,
                        yStart : this.grid.getYend() + halfLineWidth,
                        xEnd : this.grid.getXend() + halfLineWidth,
                        yEnd : this.grid.getY() - halfLineWidth
K
kener 已提交
195 196
                    };
                    break;
K
kener 已提交
197
                case 'bottom' :
K
kener 已提交
198
                    axShape.style = {
K
kener 已提交
199 200 201 202
                        xStart : this.grid.getX() - halfLineWidth,
                        yStart : this.grid.getYend() + halfLineWidth,
                        xEnd : this.grid.getXend() + halfLineWidth,
                        yEnd : this.grid.getYend() + halfLineWidth
K
kener 已提交
203 204
                    };
                    break;
K
kener 已提交
205
                case 'top' :
K
kener 已提交
206
                    axShape.style = {
K
kener 已提交
207 208 209 210
                        xStart : this.grid.getX() - halfLineWidth,
                        yStart : this.grid.getY() - halfLineWidth,
                        xEnd : this.grid.getXend() + halfLineWidth,
                        yEnd : this.grid.getY() - halfLineWidth
K
kener 已提交
211 212 213
                    };
                    break;
            }
K
kener 已提交
214 215 216 217 218 219
            if (this.option.name !== '') {
                axShape.style.text = this.option.name;
                axShape.style.textPosition = this.option.nameLocation;
                axShape.style.textFont = this.getFont(this.option.nameTextStyle);
                if (this.option.nameTextStyle.align) {
                    axShape.style.textAlign = this.option.nameTextStyle.align;
K
kener 已提交
220
                }
K
kener 已提交
221 222
                if (this.option.nameTextStyle.baseline) {
                    axShape.style.textBaseline = this.option.nameTextStyle.baseline;
K
kener 已提交
223
                }
K
kener 已提交
224 225
                if (this.option.nameTextStyle.color) {
                    axShape.style.textColor = this.option.nameTextStyle.color;
K
kener 已提交
226 227
                }
            }
K
kener 已提交
228
            axShape.style.strokeColor = this.option.axisLine.lineStyle.color;
K
kener 已提交
229 230 231
            
            axShape.style.lineWidth = lineWidth;
            // 亚像素优化
K
kener 已提交
232
            if (this.option.position == 'left' || this.option.position == 'right') {
K
kener 已提交
233 234 235
                // 纵向布局,优化x
                axShape.style.xStart 
                    = axShape.style.xEnd 
K
kener 已提交
236
                    = this.subPixelOptimize(axShape.style.xEnd, lineWidth);
K
kener 已提交
237 238 239 240 241
            }
            else {
                // 横向布局,优化y
                axShape.style.yStart 
                    = axShape.style.yEnd 
K
kener 已提交
242
                    = this.subPixelOptimize(axShape.style.yEnd, lineWidth);
K
kener 已提交
243 244
            }
            
K
kener 已提交
245
            axShape.style.lineType = this.option.axisLine.lineStyle.type;
K
kener 已提交
246 247
            
            axShape = new LineShape(axShape);
K
kener 已提交
248 249
            this.shapeList.push(axShape);
        },
K
kener 已提交
250 251

        // 小标记
K
kener 已提交
252
        _buildAxisTick : function () {
K
kener 已提交
253
            var axShape;
K
kener 已提交
254 255 256
            //var data       = this.option.data;
            var dataLength = this.option.data.length;
            var tickOption = this.option.axisTick;
K
kener 已提交
257 258 259 260
            var length     = tickOption.length;
            var color      = tickOption.lineStyle.color;
            var lineWidth  = tickOption.lineStyle.width;
            var interval   = tickOption.interval == 'auto' 
K
kener 已提交
261
                             ? this._interval : (tickOption.interval - 0 + 1);
K
kener 已提交
262 263
            var onGap      = tickOption.onGap;
            var optGap     = onGap 
K
kener 已提交
264
                             ? (this.getGap() / 2) 
K
kener 已提交
265
                             : typeof onGap == 'undefined'
K
kener 已提交
266
                                   ? (this.option.boundaryGap ? (this.getGap() / 2) : 0)
K
kener 已提交
267
                                   : 0;
K
kener 已提交
268
            var startIndex = optGap > 0 ? -interval : 0;                       
K
kener 已提交
269
            if (this.option.position == 'bottom' || this.option.position == 'top') {
K
kener 已提交
270
                // 横向
K
kener 已提交
271 272 273
                var yPosition = this.option.position == 'bottom'
                        ? (tickOption.inside ? (this.grid.getYend() - length) : this.grid.getYend())
                        : (tickOption.inside ? this.grid.getY() : (this.grid.getY() - length));
K
kener 已提交
274
                var x;
K
kener 已提交
275
                for (var i = startIndex; i < dataLength; i += interval) {
K
kener 已提交
276
                    // 亚像素优化
K
kener 已提交
277 278
                    x = this.subPixelOptimize(
                        this.getCoordByIndex(i) + (i >= 0 ? optGap : 0), lineWidth
K
kener 已提交
279
                    );
K
kener 已提交
280 281
                    axShape = {
                        shape : 'line',
K
kener 已提交
282
                        zlevel : this._zlevelBase,
K
kener 已提交
283 284
                        hoverable : false,
                        style : {
K
kener 已提交
285
                            xStart : x,
K
kener 已提交
286
                            yStart : yPosition,
K
kener 已提交
287
                            xEnd : x,
K
kener 已提交
288 289 290 291 292
                            yEnd : yPosition + length,
                            strokeColor : color,
                            lineWidth : lineWidth
                        }
                    };
K
kener 已提交
293
                    this.shapeList.push(new LineShape(axShape));
K
kener 已提交
294 295 296
                }
            }
            else {
K
kener 已提交
297
                // 纵向
K
kener 已提交
298 299 300
                var xPosition = this.option.position == 'left'
                        ? (tickOption.inside ? this.grid.getX() : (this.grid.getX() - length))
                        : (tickOption.inside ? (this.grid.getXend() - length) : this.grid.getXend());
K
kener 已提交
301
                        
K
kener 已提交
302
                var y;
K
kener 已提交
303
                for (var i = startIndex; i < dataLength; i += interval) {
K
kener 已提交
304
                    // 亚像素优化
K
kener 已提交
305 306
                    y = this.subPixelOptimize(
                        this.getCoordByIndex(i) - (i >= 0 ? optGap : 0), lineWidth
K
kener 已提交
307
                    );
K
kener 已提交
308 309
                    axShape = {
                        shape : 'line',
K
kener 已提交
310
                        zlevel : this._zlevelBase,
K
kener 已提交
311 312 313
                        hoverable : false,
                        style : {
                            xStart : xPosition,
K
kener 已提交
314
                            yStart : y,
K
kener 已提交
315
                            xEnd : xPosition + length,
K
kener 已提交
316
                            yEnd : y,
K
kener 已提交
317 318 319 320
                            strokeColor : color,
                            lineWidth : lineWidth
                        }
                    };
K
kener 已提交
321
                    this.shapeList.push(new LineShape(axShape));
K
kener 已提交
322 323
                }
            }
K
kener 已提交
324
        },
K
kener 已提交
325 326

        // 坐标轴文本
K
kener 已提交
327
        _buildAxisLabel : function () {
K
kener 已提交
328
            var axShape;
K
kener 已提交
329 330 331 332 333
            var data       = this.option.data;
            var dataLength = this.option.data.length;
            var rotate     = this.option.axisLabel.rotate;
            var margin     = this.option.axisLabel.margin;
            var textStyle  = this.option.axisLabel.textStyle;
K
kener 已提交
334 335
            var dataTextStyle;

K
kener 已提交
336
            if (this.option.position == 'bottom' || this.option.position == 'top') {
K
kener 已提交
337 338 339
                // 横向
                var yPosition;
                var baseLine;
K
kener 已提交
340 341
                if (this.option.position == 'bottom') {
                    yPosition = this.grid.getYend() + margin;
K
kener 已提交
342 343 344
                    baseLine = 'top';
                }
                else {
K
kener 已提交
345
                    yPosition = this.grid.getY() - margin;
K
kener 已提交
346 347 348
                    baseLine = 'bottom';
                }

K
kener 已提交
349 350
                for (var i = 0; i < dataLength; i += this._interval) {
                    if ((this._labelData[i].value || this._labelData[i]) === '') {
K
kener 已提交
351 352 353
                        // 空文本优化
                        continue;
                    }
K
kener 已提交
354 355
                    dataTextStyle = zrUtil.merge(
                        data[i].textStyle || {},
K
kener 已提交
356
                        textStyle
K
kener 已提交
357 358 359
                    );
                    axShape = {
                        shape : 'text',
K
kener 已提交
360
                        zlevel : this._zlevelBase,
K
kener 已提交
361 362
                        hoverable : false,
                        style : {
K
kener 已提交
363
                            x : this.getCoordByIndex(i),
K
kener 已提交
364 365
                            y : yPosition,
                            color : dataTextStyle.color,
K
kener 已提交
366 367
                            text : this._labelData[i].value || this._labelData[i],
                            textFont : this.getFont(dataTextStyle),
K
kener 已提交
368 369 370 371 372 373
                            textAlign : 'center',
                            textBaseline : baseLine
                        }
                    };
                    if (rotate) {
                        axShape.style.textAlign = rotate > 0
K
kener 已提交
374
                                                  ? (this.option.position == 'bottom'
K
kener 已提交
375
                                                    ? 'right' : 'left')
K
kener 已提交
376
                                                  : (this.option.position == 'bottom'
K
kener 已提交
377 378 379 380 381 382 383
                                                    ? 'left' : 'right');
                        axShape.rotation = [
                            rotate * Math.PI / 180,
                            axShape.style.x,
                            axShape.style.y
                        ];
                    }
K
kener 已提交
384
                    this.shapeList.push(new TextShape(axShape));
K
kener 已提交
385 386 387 388 389 390
                }
            }
            else {
                // 纵向
                var xPosition;
                var align;
K
kener 已提交
391 392
                if (this.option.position == 'left') {
                    xPosition = this.grid.getX() - margin;
K
kener 已提交
393 394 395
                    align = 'right';
                }
                else {
K
kener 已提交
396
                    xPosition = this.grid.getXend() + margin;
K
kener 已提交
397 398 399
                    align = 'left';
                }

K
kener 已提交
400 401
                for (var i = 0; i < dataLength; i += this._interval) {
                    if ((this._labelData[i].value || this._labelData[i]) === '') {
K
kener 已提交
402 403 404
                        // 空文本优化
                        continue;
                    }
K
kener 已提交
405 406
                    dataTextStyle = zrUtil.merge(
                        data[i].textStyle || {},
K
kener 已提交
407
                        textStyle
K
kener 已提交
408 409 410
                    );
                    axShape = {
                        shape : 'text',
K
kener 已提交
411
                        zlevel : this._zlevelBase,
K
kener 已提交
412 413 414
                        hoverable : false,
                        style : {
                            x : xPosition,
K
kener 已提交
415
                            y : this.getCoordByIndex(i),
K
kener 已提交
416
                            color : dataTextStyle.color,
K
kener 已提交
417 418
                            text : this._labelData[i].value || this._labelData[i],
                            textFont : this.getFont(dataTextStyle),
K
kener 已提交
419
                            textAlign : align,
K
kener 已提交
420
                            textBaseline : (i === 0 && this.option.name !== '')
K
kener 已提交
421 422
                                           ? 'bottom'
                                           : (i == (dataLength - 1) 
K
kener 已提交
423
                                              && this.option.name !== '')
K
kener 已提交
424 425
                                             ? 'top'
                                             : 'middle'
K
kener 已提交
426 427
                        }
                    };
K
kener 已提交
428
                    
K
kener 已提交
429 430 431 432 433 434 435
                    if (rotate) {
                        axShape.rotation = [
                            rotate * Math.PI / 180,
                            axShape.style.x,
                            axShape.style.y
                        ];
                    }
K
kener 已提交
436
                    this.shapeList.push(new TextShape(axShape));
K
kener 已提交
437 438
                }
            }
K
kener 已提交
439
        },
K
kener 已提交
440

K
kener 已提交
441
        _buildSplitLine : function () {
K
kener 已提交
442
            var axShape;
K
kener 已提交
443 444 445
            //var data       = this.option.data;
            var dataLength  = this.option.data.length;
            var sLineOption = this.option.splitLine;
K
kener 已提交
446 447 448
            var lineType    = sLineOption.lineStyle.type;
            var lineWidth   = sLineOption.lineStyle.width;
            var color       = sLineOption.lineStyle.color;
449 450
            color = color instanceof Array ? color : [color];
            var colorLength = color.length;
K
kener 已提交
451 452 453
            
            var onGap      = sLineOption.onGap;
            var optGap     = onGap 
K
kener 已提交
454
                             ? (this.getGap() / 2) 
K
kener 已提交
455
                             : typeof onGap == 'undefined'
K
kener 已提交
456
                                   ? (this.option.boundaryGap ? (this.getGap() / 2) : 0)
K
kener 已提交
457
                                   : 0;
K
kener 已提交
458 459
            dataLength -= (onGap || (typeof onGap == 'undefined' && this.option.boundaryGap)) ? 1 : 0;
            if (this.option.position == 'bottom' || this.option.position == 'top') {
K
kener 已提交
460
                // 横向
K
kener 已提交
461 462
                var sy = this.grid.getY();
                var ey = this.grid.getYend();
K
kener 已提交
463 464
                var x;

K
kener 已提交
465
                for (var i = 0; i < dataLength; i += this._interval) {
K
kener 已提交
466
                    // 亚像素优化
K
kener 已提交
467 468
                    x = this.subPixelOptimize(
                        this.getCoordByIndex(i) + optGap, lineWidth
K
kener 已提交
469
                    );
K
kener 已提交
470 471
                    axShape = {
                        shape : 'line',
K
kener 已提交
472
                        zlevel : this._zlevelBase,
K
kener 已提交
473 474 475 476 477 478
                        hoverable : false,
                        style : {
                            xStart : x,
                            yStart : sy,
                            xEnd : x,
                            yEnd : ey,
K
kener 已提交
479
                            strokeColor : color[(i / this._interval) % colorLength],
K
kener 已提交
480 481
                            lineType : lineType,
                            lineWidth : lineWidth
K
kener 已提交
482 483
                        }
                    };
K
kener 已提交
484
                    this.shapeList.push(new LineShape(axShape));
K
kener 已提交
485 486 487 488 489
                }

            }
            else {
                // 纵向
K
kener 已提交
490 491
                var sx = this.grid.getX();
                var ex = this.grid.getXend();
K
kener 已提交
492 493
                var y;

K
kener 已提交
494
                for (var i = 0; i < dataLength; i += this._interval) {
K
kener 已提交
495
                    // 亚像素优化
K
kener 已提交
496 497
                    y = this.subPixelOptimize(
                        this.getCoordByIndex(i) - optGap, lineWidth
K
kener 已提交
498
                    );
K
kener 已提交
499 500
                    axShape = {
                        shape : 'line',
K
kener 已提交
501
                        zlevel : this._zlevelBase,
K
kener 已提交
502 503 504 505 506 507
                        hoverable : false,
                        style : {
                            xStart : sx,
                            yStart : y,
                            xEnd : ex,
                            yEnd : y,
K
kener 已提交
508
                            strokeColor : color[(i / this._interval) % colorLength],
K
kener 已提交
509 510
                            linetype : lineType,
                            lineWidth : lineWidth
K
kener 已提交
511 512
                        }
                    };
K
kener 已提交
513
                    this.shapeList.push(new LineShape(axShape));
K
kener 已提交
514 515
                }
            }
K
kener 已提交
516
        },
K
kener 已提交
517

K
kener 已提交
518
        _buildSplitArea : function () {
K
kener 已提交
519
            var axShape;
K
kener 已提交
520
            var sAreaOption = this.option.splitArea;
K
kener 已提交
521
            var color = sAreaOption.areaStyle.color;
K
kener 已提交
522 523 524 525
            if (!(color instanceof Array)) {
                // 非数组一律认为是单一颜色的字符串,单一颜色则用一个背景,颜色错误不负责啊!!!
                axShape = {
                    shape : 'rectangle',
K
kener 已提交
526
                    zlevel : this._zlevelBase,
K
kener 已提交
527 528
                    hoverable : false,
                    style : {
K
kener 已提交
529 530 531 532
                        x : this.grid.getX(),
                        y : this.grid.getY(),
                        width : this.grid.getWidth(),
                        height : this.grid.getHeight(),
K
kener 已提交
533
                        color : color
K
kener 已提交
534
                        // type : this.option.splitArea.areaStyle.type,
K
kener 已提交
535 536
                    }
                };
K
kener 已提交
537
                this.shapeList.push(new RectangleShape(axShape));
K
kener 已提交
538 539
            }
            else {
K
kener 已提交
540 541
                // 多颜色
                var colorLength = color.length;
K
kener 已提交
542
                var dataLength  = this.option.data.length;
K
kener 已提交
543 544 545
        
                var onGap      = sAreaOption.onGap;
                var optGap     = onGap 
K
kener 已提交
546
                                 ? (this.getGap() / 2) 
K
kener 已提交
547
                                 : typeof onGap == 'undefined'
K
kener 已提交
548
                                       ? (this.option.boundaryGap ? (this.getGap() / 2) : 0)
K
kener 已提交
549
                                       : 0;
K
kener 已提交
550
                if (this.option.position == 'bottom' || this.option.position == 'top') {
K
kener 已提交
551
                    // 横向
K
kener 已提交
552 553 554
                    var y = this.grid.getY();
                    var height = this.grid.getHeight();
                    var lastX = this.grid.getX();
K
kener 已提交
555 556
                    var curX;
    
K
kener 已提交
557
                    for (var i = 0; i <= dataLength; i += this._interval) {
K
kener 已提交
558
                        curX = i < dataLength
K
kener 已提交
559 560
                               ? (this.getCoordByIndex(i) + optGap)
                               : this.grid.getXend();
K
kener 已提交
561 562
                        axShape = {
                            shape : 'rectangle',
K
kener 已提交
563
                            zlevel : this._zlevelBase,
K
kener 已提交
564 565 566 567 568 569
                            hoverable : false,
                            style : {
                                x : lastX,
                                y : y,
                                width : curX - lastX,
                                height : height,
K
kener 已提交
570 571
                                color : color[(i / this._interval) % colorLength]
                                // type : this.option.splitArea.areaStyle.type,
K
kener 已提交
572 573
                            }
                        };
K
kener 已提交
574
                        this.shapeList.push(new RectangleShape(axShape));
K
kener 已提交
575 576 577 578 579
                        lastX = curX;
                    }
                }
                else {
                    // 纵向
K
kener 已提交
580 581 582
                    var x = this.grid.getX();
                    var width = this.grid.getWidth();
                    var lastYend = this.grid.getYend();
K
kener 已提交
583 584
                    var curY;
    
K
kener 已提交
585
                    for (var i = 0; i <= dataLength; i += this._interval) {
K
kener 已提交
586
                        curY = i < dataLength
K
kener 已提交
587 588
                               ? (this.getCoordByIndex(i) - optGap)
                               : this.grid.getY();
K
kener 已提交
589 590
                        axShape = {
                            shape : 'rectangle',
K
kener 已提交
591
                            zlevel : this._zlevelBase,
K
kener 已提交
592 593 594 595 596 597
                            hoverable : false,
                            style : {
                                x : x,
                                y : curY,
                                width : width,
                                height : lastYend - curY,
K
kener 已提交
598 599
                                color : color[(i / this._interval) % colorLength]
                                // type : this.option.splitArea.areaStyle.type
K
kener 已提交
600 601
                            }
                        };
K
kener 已提交
602
                        this.shapeList.push(new RectangleShape(axShape));
K
kener 已提交
603 604
                        lastYend = curY;
                    }
K
kener 已提交
605 606
                }
            }
K
kener 已提交
607
        },
K
kener 已提交
608 609 610 611 612 613 614

        /**
         * 构造函数默认执行的初始化方法,也用于创建实例后动态修改
         * @param {Object} newZr
         * @param {Object} newOption
         * @param {Object} newGrid
         */
K
kener 已提交
615
        init :function (newOption, newComponent) {
K
kener 已提交
616 617 618
            if (newOption.data.length < 1) {
                return;
            }
K
kener 已提交
619 620
            this.grid = (newComponent && newComponent.grid) || this.grid;
            
K
kener 已提交
621 622
            this.refresh(newOption);
        },
K
kener 已提交
623 624 625 626

        /**
         * 刷新
         */
K
kener 已提交
627
        refresh : function (newOption) {
K
kener 已提交
628
            if (newOption) {
K
kener 已提交
629
                this.option = this.reformOption(newOption);
K
kener 已提交
630
                // 通用字体设置
K
kener 已提交
631 632 633
                this.option.axisLabel.textStyle = zrUtil.merge(
                    this.option.axisLabel.textStyle || {},
                    this.ecTheme.textStyle
K
kener 已提交
634
                );
K
kener 已提交
635 636 637
                this.option.axisLabel.textStyle = zrUtil.merge(
                    this.option.axisLabel.textStyle || {},
                    this.ecTheme.textStyle
K
kener 已提交
638 639
                );
            }
K
kener 已提交
640 641 642
            this.clear();
            this._buildShape();
        },
K
kener 已提交
643 644 645 646

        /**
         * 返回间隔
         */
K
kener 已提交
647 648 649 650 651 652
        getGap : function () {
            var dataLength = this.option.data.length;
            var total = (this.option.position == 'bottom'
                        || this.option.position == 'top')
                        ? this.grid.getWidth()
                        : this.grid.getHeight();
K
kener 已提交
653
            if (this.option.boundaryGap) {              // 留空
K
kener 已提交
654
                return total / dataLength;
K
kener 已提交
655
            }
K
kener 已提交
656
            else {                                      // 顶头
K
kener 已提交
657 658
                return total / (dataLength > 1 ? (dataLength - 1) : 1);
            }
K
kener 已提交
659
        },
K
kener 已提交
660 661

        // 根据值换算位置
K
kener 已提交
662 663
        getCoord : function (value) {
            var data = this.option.data;
K
kener 已提交
664
            var dataLength = data.length;
K
kener 已提交
665 666
            var gap = this.getGap();
            var position = this.option.boundaryGap ? (gap / 2) : 0;
K
kener 已提交
667 668 669

            for (var i = 0; i < dataLength; i++) {
                if (data[i] == value
K
kener 已提交
670 671
                    || (typeof data[i].value != 'undefined' 
                        && data[i].value == value)
K
kener 已提交
672
                ) {
K
kener 已提交
673 674
                    if (this.option.position == 'bottom'
                        || this.option.position == 'top'
K
kener 已提交
675 676
                    ) {
                        // 横向
K
kener 已提交
677
                        position = this.grid.getX() + position;
K
kener 已提交
678 679 680
                    }
                    else {
                        // 纵向
K
kener 已提交
681
                        position = this.grid.getYend() - position;
K
kener 已提交
682
                    }
K
kener 已提交
683 684 685 686
                    
                    return position;
                    // Math.floor可能引起一些偏差,但性能会更好
                    /* 准确更重要
687 688 689
                    return (i === 0 || i == dataLength - 1)
                           ? position
                           : Math.floor(position);
K
kener 已提交
690
                    */
K
kener 已提交
691 692 693
                }
                position += gap;
            }
K
kener 已提交
694
        },
K
kener 已提交
695 696

        // 根据类目轴数据索引换算位置
K
kener 已提交
697
        getCoordByIndex : function (dataIndex) {
K
kener 已提交
698
            if (dataIndex < 0) {
K
kener 已提交
699 700
                if (this.option.position == 'bottom' || this.option.position == 'top') {
                    return this.grid.getX();
K
kener 已提交
701 702
                }
                else {
K
kener 已提交
703
                    return this.grid.getYend();
K
kener 已提交
704 705
                }
            }
K
kener 已提交
706 707 708
            else if (dataIndex > this.option.data.length - 1) {
                if (this.option.position == 'bottom' || this.option.position == 'top') {
                    return this.grid.getXend();
K
kener 已提交
709 710
                }
                else {
K
kener 已提交
711
                    return this.grid.getY();
K
kener 已提交
712 713 714
                }
            }
            else {
K
kener 已提交
715 716
                var gap = this.getGap();
                var position = this.option.boundaryGap ? (gap / 2) : 0;
K
kener 已提交
717 718
                position += dataIndex * gap;
                
K
kener 已提交
719 720
                if (this.option.position == 'bottom'
                    || this.option.position == 'top'
K
kener 已提交
721 722
                ) {
                    // 横向
K
kener 已提交
723
                    position = this.grid.getX() + position;
K
kener 已提交
724 725 726
                }
                else {
                    // 纵向
K
kener 已提交
727
                    position = this.grid.getYend() - position;
K
kener 已提交
728
                }
K
kener 已提交
729 730 731
                
                return position;
                /* 准确更重要
K
kener 已提交
732
                return (dataIndex === 0 || dataIndex == this.option.data.length - 1)
K
kener 已提交
733 734
                       ? position
                       : Math.floor(position);
K
kener 已提交
735
                */
K
kener 已提交
736
            }
K
kener 已提交
737
        },
K
kener 已提交
738 739

        // 根据类目轴数据索引换算类目轴名称
K
kener 已提交
740 741
        getNameByIndex : function (dataIndex) {
            var data = this.option.data[dataIndex];
K
kener 已提交
742 743 744
            if (typeof data != 'undefined' && typeof data.value != 'undefined')
            {
                return data.value;
K
kener 已提交
745 746
            }
            else {
K
kener 已提交
747
                return data;
K
kener 已提交
748
            }
K
kener 已提交
749
        },
K
kener 已提交
750
        
K
kener 已提交
751
        // 根据类目轴名称换算类目轴数据索引
K
kener 已提交
752 753
        getIndexByName : function (name) {
            var data = this.option.data;
K
kener 已提交
754 755 756 757 758 759 760 761 762 763
            var dataLength = data.length;

            for (var i = 0; i < dataLength; i++) {
                if (data[i] == name
                    || (typeof data[i].value != 'undefined' 
                        && data[i].value == name)
                ) {
                    return i;
                }
            }
K
kener 已提交
764
        },
K
kener 已提交
765 766 767 768 769 770

        /**
         * 根据类目轴数据索引返回是否为主轴线
         * @param {number} dataIndex 类目轴数据索引
         * @return {boolean} 是否为主轴
         */
K
kener 已提交
771 772 773
        isMainAxis : function (dataIndex) {
            return dataIndex % this._interval === 0;
        },
K
kener 已提交
774

K
kener 已提交
775 776
        getPosition : function () {
            return this.option.position;
K
kener 已提交
777
        }
K
kener 已提交
778 779 780 781
    };
    
    zrUtil.inherits(CategoryAxis, Base);
    
782 783
    require('../component').define('categoryAxis', CategoryAxis);
    
K
kener 已提交
784 785
    return CategoryAxis;
});