dataZoom.js 41.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 11
    var Base = require('./base');
    
    // 图形依赖
K
kener 已提交
12 13 14 15
    var RectangleShape = require('zrender/shape/Rectangle');
    var PolygonShape = require('zrender/shape/Polygon');
    var IconShape = require('../util/shape/Icon');
    
K
kener 已提交
16 17 18
    var ecConfig = require('../config');
    var zrUtil = require('zrender/tool/util');

K
kener 已提交
19 20 21 22 23 24 25
    /**
     * 构造函数
     * @param {Object} messageCenter echart消息中心
     * @param {ZRender} zr zrender实例
     * @param {Object} option 图表参数
     * @param {Object} component 组件
     */
K
kener 已提交
26 27
    function DataZoom(ecTheme, messageCenter, zr, option, component) {
        Base.call(this, ecTheme, zr, option);
K
kener 已提交
28

K
kener 已提交
29
        this.messageCenter = messageCenter;
K
kener 已提交
30

K
kener 已提交
31 32
        var self = this;
        self._ondrift = function (dx, dy) {
K
kener 已提交
33
            return self.__ondrift(this, dx, dy);
K
kener 已提交
34 35
        };
        self._ondragend = function () {
K
kener 已提交
36
            return self.__ondragend();
K
kener 已提交
37
        };
K
kener 已提交
38

K
kener 已提交
39
        self.init(option, component);
K
kener 已提交
40 41 42 43 44 45 46 47 48
    }
    
    DataZoom.prototype = {
        type : ecConfig.COMPONENT_TYPE_DATAZOOM,
        _buildShape : function () {
            this._buildBackground();
            this._buildFiller();
            this._buildHandle();
            this._buildFrame();
K
kener 已提交
49

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

        /**
         * 根据选项计算实体的位置坐标
         */
K
kener 已提交
59
        _getLocation : function () {
K
kener 已提交
60 61 62 63
            var x;
            var y;
            var width;
            var height;
K
kener 已提交
64
            var grid = this.component.grid;
K
kener 已提交
65 66

            // 不指定则根据grid适配
K
kener 已提交
67
            if (this.zoomOption.orient == 'horizontal') {
K
kener 已提交
68
                // 水平布局
K
kener 已提交
69 70 71 72 73 74
                width = this.zoomOption.width || grid.getWidth();
                height = this.zoomOption.height || this._fillerSize;
                x = typeof this.zoomOption.x != 'undefined'
                    ? this.zoomOption.x : grid.getX();
                y = typeof this.zoomOption.y != 'undefined'
                    ? this.zoomOption.y : (this.zr.getHeight() - height - 2);
K
kener 已提交
75 76 77
            }
            else {
                // 垂直布局
K
kener 已提交
78 79 80 81 82 83
                width = this.zoomOption.width || this._fillerSize;
                height = this.zoomOption.height || grid.getHeight();
                x = typeof this.zoomOption.x != 'undefined'
                    ? this.zoomOption.x : 2;
                y = typeof this.zoomOption.y != 'undefined'
                    ? this.zoomOption.y : grid.getY();
K
kener 已提交
84 85 86 87 88 89 90 91
            }

            return {
                x : x,
                y : y,
                width : width,
                height : height
            };
K
kener 已提交
92
        },
K
kener 已提交
93 94 95 96 97

        /**
         * 计算缩放参数
         * 修正单坐标轴只传对象为数组。
         */
K
kener 已提交
98 99 100
        _getZoom : function () {
            var series = this.option.series;
            var xAxis = this.option.xAxis;
K
kener 已提交
101 102
            if (xAxis && !(xAxis instanceof Array)) {
                xAxis = [xAxis];
K
kener 已提交
103
                this.option.xAxis = xAxis;
K
kener 已提交
104
            }
K
kener 已提交
105
            var yAxis = this.option.yAxis;
K
kener 已提交
106 107
            if (yAxis && !(yAxis instanceof Array)) {
                yAxis = [yAxis];
K
kener 已提交
108
                this.option.yAxis = yAxis;
K
kener 已提交
109 110 111 112 113 114
            }

            var zoomSeriesIndex = [];
            var xAxisIndex;
            var yAxisIndex;

K
kener 已提交
115
            var zOptIdx = this.zoomOption.xAxisIndex;
K
kener 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
            if (xAxis && typeof zOptIdx == 'undefined') {
                xAxisIndex = [];
                for (var i = 0, l = xAxis.length; i < l; i++) {
                    // 横纵默认为类目轴
                    if (xAxis[i].type == 'category'
                        || typeof xAxis[i].type == 'undefined'
                    ) {
                        xAxisIndex.push(i);
                    }
                }
            }
            else {
                if (zOptIdx instanceof Array) {
                    xAxisIndex = zOptIdx;
                }
                else if (typeof zOptIdx != 'undefined') {
                    xAxisIndex = [zOptIdx];
                }
                else {
                    xAxisIndex = [];
                }
            }

K
kener 已提交
139
            zOptIdx = this.zoomOption.yAxisIndex;
K
kener 已提交
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
            if (yAxis && typeof zOptIdx == 'undefined') {
                yAxisIndex = [];
                for (var i = 0, l = yAxis.length; i < l; i++) {
                    if (yAxis[i].type == 'category') {
                        yAxisIndex.push(i);
                    }
                }
            }
            else {
                if (zOptIdx instanceof Array) {
                    yAxisIndex = zOptIdx;
                }
                else if (typeof zOptIdx != 'undefined') {
                    yAxisIndex = [zOptIdx];
                }
                else {
                    yAxisIndex = [];
                }
            }

            // 找到缩放控制的所有series
            for (var i = 0, l = series.length; i < l; i++) {
K
kener 已提交
162 163 164 165 166 167 168
                if (series[i].type != ecConfig.CHART_TYPE_LINE
                    && series[i].type != ecConfig.CHART_TYPE_BAR
                    && series[i].type != ecConfig.CHART_TYPE_SCATTER
                    && series[i].type != ecConfig.CHART_TYPE_K
                ) {
                    continue;
                }
K
kener 已提交
169 170 171 172 173 174 175 176 177 178 179 180
                for (var j = 0, k = xAxisIndex.length; j < k; j++) {
                    if (xAxisIndex[j] == (series[i].xAxisIndex || 0)) {
                        zoomSeriesIndex.push(i);
                        break;
                    }
                }
                for (var j = 0, k = yAxisIndex.length; j < k; j++) {
                    if (yAxisIndex[j] == (series[i].yAxisIndex || 0)) {
                        zoomSeriesIndex.push(i);
                        break;
                    }
                }
K
kener 已提交
181 182
                // 不指定接管坐标轴,则散点图被纳入接管范围
                if (series[i].type == ecConfig.CHART_TYPE_SCATTER
K
kener 已提交
183 184
                    && typeof this.zoomOption.xAxisIndex == 'undefined'
                    && typeof this.zoomOption.yAxisIndex == 'undefined'
K
kener 已提交
185 186 187
                ) {
                    zoomSeriesIndex.push(i);
                }
K
kener 已提交
188 189
            }

K
kener 已提交
190 191 192 193 194 195 196 197
            var start = typeof this.zoomOption.start != 'undefined'
                        && this.zoomOption.start >= 0
                        && this.zoomOption.start <= 100
                        ? this.zoomOption.start : 0;
            var end = typeof this.zoomOption.end != 'undefined'
                      && this.zoomOption.end >= 0
                      && this.zoomOption.end <= 100
                      ? this.zoomOption.end : 100;
K
kener 已提交
198 199 200 201 202 203 204 205
            if (start > end) {
                // 大小颠倒自动翻转
                start = start + end;
                end = start - end;
                start = start - end;
            }
            var size = Math.round(
                           (end - start) / 100
K
kener 已提交
206 207
                           * (this.zoomOption.orient == 'horizontal'
                             ? this._location.width : this._location.height)
K
kener 已提交
208 209 210 211
                       );
            return {
                start : start,
                end : end,
K
kener 已提交
212 213
                start2 : 0,
                end2 : 100,
K
kener 已提交
214 215 216 217 218
                size : size,
                xAxisIndex : xAxisIndex,
                yAxisIndex : yAxisIndex,
                seriesIndex : zoomSeriesIndex
            };
K
kener 已提交
219
        },
K
kener 已提交
220

K
kener 已提交
221 222
        _backupData : function () {
            this._originalData = {
K
kener 已提交
223 224 225 226
                xAxis : {},
                yAxis : {},
                series : {}
            };
K
kener 已提交
227 228
            var xAxis = this.option.xAxis;
            var xAxisIndex = this._zoom.xAxisIndex;
K
kener 已提交
229
            for (var i = 0, l = xAxisIndex.length; i < l; i++) {
K
kener 已提交
230
                this._originalData.xAxis[xAxisIndex[i]] = xAxis[xAxisIndex[i]].data;
K
kener 已提交
231 232
            }

K
kener 已提交
233 234
            var yAxis = this.option.yAxis;
            var yAxisIndex = this._zoom.yAxisIndex;
K
kener 已提交
235
            for (var i = 0, l = yAxisIndex.length; i < l; i++) {
K
kener 已提交
236
                this._originalData.yAxis[yAxisIndex[i]] = yAxis[yAxisIndex[i]].data;
K
kener 已提交
237 238
            }

K
kener 已提交
239 240
            var series = this.option.series;
            var seriesIndex = this._zoom.seriesIndex;
K
kener 已提交
241
            var serie;
K
kener 已提交
242
            for (var i = 0, l = seriesIndex.length; i < l; i++) {
K
kener 已提交
243
                serie = series[seriesIndex[i]];
K
kener 已提交
244
                this._originalData.series[seriesIndex[i]] = serie.data;
K
kener 已提交
245
                if (serie.type == ecConfig.CHART_TYPE_SCATTER) {
K
kener 已提交
246
                    this._calculScatterMap(seriesIndex[i]);
K
kener 已提交
247
                }
K
kener 已提交
248
            }
K
kener 已提交
249
        },
K
kener 已提交
250
        
K
kener 已提交
251 252 253
        _calculScatterMap : function (seriesIndex) {
            this._zoom.scatterMap = this._zoom.scatterMap || {};
            this._zoom.scatterMap[seriesIndex] = this._zoom.scatterMap[seriesIndex] || {};
K
kener 已提交
254
            var componentLibrary = require('../component');
K
kener 已提交
255
            var zrUtil = require('zrender/tool/util');
K
kener 已提交
256 257
            // x轴极值
            var Axis = componentLibrary.get('axis');
K
kener 已提交
258
            var axisOption = zrUtil.clone(this.option.xAxis);
K
kener 已提交
259 260 261 262 263 264 265
            if (axisOption instanceof Array) {
                axisOption[0].type = 'value';
                axisOption[1] && (axisOption[1].type = 'value');
            }
            else {
                axisOption.type = 'value';
            }
K
kener 已提交
266
            var vAxis = new Axis(
K
kener 已提交
267
                this.ecTheme,
K
kener 已提交
268
                null,   // messageCenter
K
kener 已提交
269
                false,  // this.zr
K
kener 已提交
270
                {
K
kener 已提交
271
                    xAxis: axisOption,
K
kener 已提交
272
                    series : this.option.series
K
kener 已提交
273
                }, 
K
kener 已提交
274
                this.component,
K
kener 已提交
275 276
                'xAxis'
            );
K
kener 已提交
277 278
            var axisIndex = this.option.series[seriesIndex].xAxisIndex || 0;
            this._zoom.scatterMap[seriesIndex].x = 
K
kener 已提交
279
                vAxis.getAxis(axisIndex).getExtremum();
K
kener 已提交
280
            vAxis.dispose();
K
kener 已提交
281 282
            
            // y轴极值
K
kener 已提交
283
            axisOption = zrUtil.clone(this.option.yAxis);
K
kener 已提交
284 285 286 287 288 289 290
            if (axisOption instanceof Array) {
                axisOption[0].type = 'value';
                axisOption[1] && (axisOption[1].type = 'value');
            }
            else {
                axisOption.type = 'value';
            }
K
kener 已提交
291
            vAxis = new Axis(
K
kener 已提交
292
                this.ecTheme,
K
kener 已提交
293
                null,   // messageCenter
K
kener 已提交
294
                false,  // this.zr
K
kener 已提交
295
                {
K
kener 已提交
296
                    yAxis: axisOption,
K
kener 已提交
297
                    series : this.option.series
K
kener 已提交
298
                }, 
K
kener 已提交
299
                this.component,
K
kener 已提交
300 301
                'yAxis'
            );
K
kener 已提交
302 303
            axisIndex = this.option.series[seriesIndex].yAxisIndex || 0;
            this._zoom.scatterMap[seriesIndex].y = 
K
kener 已提交
304
                vAxis.getAxis(axisIndex).getExtremum();
K
kener 已提交
305
            vAxis.dispose();
K
kener 已提交
306 307
            // console.log(this._zoom.scatterMap);
        },
K
kener 已提交
308

K
kener 已提交
309
        _buildBackground : function () {
K
kener 已提交
310
            // 背景
K
kener 已提交
311 312
            this.shapeList.push(new RectangleShape({
                zlevel : this._zlevelBase,
K
kener 已提交
313 314
                hoverable :false,
                style : {
K
kener 已提交
315 316 317 318 319
                    x : this._location.x,
                    y : this._location.y,
                    width : this._location.width,
                    height : this._location.height,
                    color : this.zoomOption.backgroundColor
K
kener 已提交
320
                }
K
kener 已提交
321
            }));
K
kener 已提交
322 323
            
            // 数据阴影
K
kener 已提交
324
            var maxLength = 0;
K
kener 已提交
325 326
            var xAxis = this._originalData.xAxis;
            var xAxisIndex = this._zoom.xAxisIndex;
K
kener 已提交
327 328
            for (var i = 0, l = xAxisIndex.length; i < l; i++) {
                maxLength = Math.max(
K
kener 已提交
329
                    maxLength, xAxis[xAxisIndex[i]].length
K
kener 已提交
330 331
                );
            }
K
kener 已提交
332 333
            var yAxis = this._originalData.yAxis;
            var yAxisIndex = this._zoom.yAxisIndex;
K
kener 已提交
334 335
            for (var i = 0, l = yAxisIndex.length; i < l; i++) {
                maxLength = Math.max(
K
kener 已提交
336
                    maxLength, yAxis[yAxisIndex[i]].length
K
kener 已提交
337 338 339
                );
            }

K
kener 已提交
340 341
            var seriesIndex = this._zoom.seriesIndex[0];
            var data = this._originalData.series[seriesIndex];
K
kener 已提交
342 343 344 345 346 347 348 349
            var maxValue = Number.MIN_VALUE;
            var minValue = Number.MAX_VALUE;
            var value;
            for (var i = 0, l = data.length; i < l; i++) {
                value = typeof data[i] != 'undefined'
                        ? (typeof data[i].value != 'undefined'
                          ? data[i].value : data[i])
                        : 0;
K
kener 已提交
350
                if (this.option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) {
K
kener 已提交
351 352
                    value = value[1];   // 收盘价
                }
K
kener 已提交
353 354 355 356 357 358 359 360
                if (isNaN(value)) {
                    value = 0;
                }
                maxValue = Math.max(maxValue, value);
                minValue = Math.min(minValue, value);
            }

            var pointList = [];
K
kener 已提交
361 362
            var x = this._location.width / (maxLength - (maxLength > 1 ? 1 : 0));
            var y = this._location.height / (maxLength - (maxLength > 1 ? 1 : 0));
K
kener 已提交
363 364 365 366 367
            for (var i = 0, l = maxLength; i < l; i++) {
                value = typeof data[i] != 'undefined'
                        ? (typeof data[i].value != 'undefined'
                          ? data[i].value : data[i])
                        : 0;
K
kener 已提交
368
                if (this.option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) {
K
kener 已提交
369 370
                    value = value[1];   // 收盘价
                }
K
kener 已提交
371 372 373
                if (isNaN(value)) {
                    value = 0;
                }
K
kener 已提交
374
                if (this.zoomOption.orient == 'horizontal') {
K
kener 已提交
375
                    pointList.push([
K
kener 已提交
376 377
                        this._location.x + x * i,
                        this._location.y + this._location.height - 5 - Math.round(
K
kener 已提交
378 379
                            (value - minValue)
                            / (maxValue - minValue)
K
kener 已提交
380
                            * (this._location.height - 10)
K
kener 已提交
381 382 383 384 385
                        )
                    ]);
                }
                else {
                    pointList.push([
K
kener 已提交
386
                        this._location.x + 5 + Math.round(
K
kener 已提交
387 388
                            (value - minValue)
                            / (maxValue - minValue)
K
kener 已提交
389
                            * (this._location.width - 10)
K
kener 已提交
390
                        ),
K
kener 已提交
391
                        this._location.y + y * i
K
kener 已提交
392 393 394
                    ]);
                }
            }
K
kener 已提交
395
            if (this.zoomOption.orient == 'horizontal') {
K
kener 已提交
396
                 pointList.push([
K
kener 已提交
397 398
                    this._location.x + this._location.width,
                    this._location.y + this._location.height
K
kener 已提交
399 400
                ]);
                pointList.push([
K
kener 已提交
401
                    this._location.x, this._location.y + this._location.height
K
kener 已提交
402 403 404 405
                ]);
            }
            else {
                pointList.push([
K
kener 已提交
406
                    this._location.x, this._location.y + this._location.height
K
kener 已提交
407 408
                ]);
                pointList.push([
K
kener 已提交
409
                    this._location.x, this._location.y
K
kener 已提交
410 411 412
                ]);
            }

K
kener 已提交
413 414
            this.shapeList.push(new PolygonShape({
                zlevel : this._zlevelBase,
K
kener 已提交
415 416
                style : {
                    pointList : pointList,
K
kener 已提交
417
                    color : this.zoomOption.dataBackgroundColor
K
kener 已提交
418 419
                },
                hoverable : false
K
kener 已提交
420
            }));
K
kener 已提交
421
        },
K
kener 已提交
422 423 424 425

        /**
         * 构建填充物
         */
K
kener 已提交
426 427 428
        _buildFiller : function () {
            this._fillerShae = {
                zlevel : this._zlevelBase,
K
kener 已提交
429
                draggable : true,
K
kener 已提交
430 431
                ondrift : this._ondrift,
                ondragend : this._ondragend,
K
kener 已提交
432 433 434
                _type : 'filler'
            };

K
kener 已提交
435
            if (this.zoomOption.orient == 'horizontal') {
K
kener 已提交
436
                // 横向
K
kener 已提交
437 438 439 440 441 442 443 444 445
                this._fillerShae.style = {
                    x : this._location.x
                        + Math.round(this._zoom.start / 100 * this._location.width)
                        + this._handleSize,
                    y : this._location.y,
                    width : this._zoom.size - this._handleSize * 2,
                    height : this._location.height,
                    color : this.zoomOption.fillerColor,
                    // strokeColor : '#fff', // this.zoomOption.handleColor,
K
kener 已提交
446
                    // lineWidth: 2,
K
kener 已提交
447 448 449 450 451
                    text : ':::',
                    textPosition : 'inside'
                };
            }
            else {
K
kener 已提交
452
                // 纵向
K
kener 已提交
453 454 455 456 457 458 459 460 461
                this._fillerShae.style ={
                    x : this._location.x,
                    y : this._location.y
                        + Math.round(this._zoom.start / 100 * this._location.height)
                        + this._handleSize,
                    width :  this._location.width,
                    height : this._zoom.size - this._handleSize * 2,
                    color : this.zoomOption.fillerColor,
                    // strokeColor : '#fff', // this.zoomOption.handleColor,
K
kener 已提交
462 463
                    // lineWidth: 2,
                    text : '::',
K
kener 已提交
464 465 466
                    textPosition : 'inside'
                };
            }
K
kener 已提交
467
            
K
kener 已提交
468
            this._fillerShae.highlightStyle = {
K
kener 已提交
469 470 471 472
                brushType: 'fill',
                color : 'rgba(0,0,0,0)'
                /*
                color : require('zrender/tool/color').alpha(
K
kener 已提交
473
                            this._fillerShae.style.color, 0
K
kener 已提交
474 475 476
                        )
                */
            };
K
kener 已提交
477 478 479
            this._fillerShae = new RectangleShape(this._fillerShae);
            this.shapeList.push(this._fillerShae);
        },
K
kener 已提交
480 481 482 483

        /**
         * 构建拖拽手柄
         */
K
kener 已提交
484
        _buildHandle : function () {
K
kener 已提交
485
            var zrUtil = require('zrender/tool/util');
K
kener 已提交
486 487
            this._startShape = {
                zlevel : this._zlevelBase,
K
kener 已提交
488 489 490
                draggable : true,
                style : {
                    iconType: 'rectangle',
K
kener 已提交
491 492 493 494 495
                    x : this._location.x,
                    y : this._location.y,
                    width : this._handleSize,
                    height : this._handleSize,
                    color : this.zoomOption.handleColor,
K
kener 已提交
496
                    text : '=',
K
kener 已提交
497
                    textPosition : 'inside'
K
kener 已提交
498 499 500 501
                },
                highlightStyle : {
                    brushType: 'fill'
                },
K
kener 已提交
502 503
                ondrift : this._ondrift,
                ondragend : this._ondragend
K
kener 已提交
504 505
            };
            
K
kener 已提交
506 507 508
            if (this.zoomOption.orient == 'horizontal') {
                this._startShape.style.height = this._location.height;
                this._endShape = zrUtil.clone(this._startShape);
K
kener 已提交
509
                
K
kener 已提交
510 511 512
                this._startShape.style.x = this._fillerShae.style.x - this._handleSize,
                this._endShape.style.x = this._fillerShae.style.x  
                                    + this._fillerShae.style.width;
K
kener 已提交
513 514
            }
            else {
K
kener 已提交
515 516
                this._startShape.style.width = this._location.width;
                this._endShape = zrUtil.clone(this._startShape);
K
kener 已提交
517
                
K
kener 已提交
518 519 520 521 522 523 524 525 526
                this._startShape.style.y = this._fillerShae.style.y - this._handleSize;
                this._endShape.style.y = this._fillerShae.style.y 
                                    + this._fillerShae.style.height;
            }
            this._startShape = new IconShape(this._startShape);
            this._endShape = new IconShape(this._endShape);
            this.shapeList.push(this._startShape);
            this.shapeList.push(this._endShape);
        },
K
kener 已提交
527

K
kener 已提交
528 529 530
        /**
         * 构建特效边框
         */
K
kener 已提交
531
        _buildFrame : function () {
K
kener 已提交
532 533
            var zrUtil = require('zrender/tool/util');
            // 特效框线,亚像素优化
K
kener 已提交
534 535 536 537
            var x = this.subPixelOptimize(this._location.x, 1);
            var y = this.subPixelOptimize(this._location.y, 1);
            this._startFrameShape = {
                zlevel : this._zlevelBase,
K
kener 已提交
538 539 540 541
                hoverable :false,
                style : {
                    x : x,
                    y : y,
K
kener 已提交
542 543
                    width : this._location.width - (x > this._location.x ? 1 : 0),
                    height : this._location.height - (y > this._location.y ? 1 : 0),
K
kener 已提交
544 545
                    lineWidth: 1,
                    brushType: 'stroke',
K
kener 已提交
546
                    strokeColor : this.zoomOption.handleColor
K
kener 已提交
547 548
                }
            };
K
kener 已提交
549
            this._endFrameShape = zrUtil.clone(this._startFrameShape);
K
kener 已提交
550
            
K
kener 已提交
551 552 553 554
            this._startFrameShape = new RectangleShape(this._startFrameShape);
            this._endFrameShape = new RectangleShape(this._endFrameShape);
            this.shapeList.push(this._startFrameShape);
            this.shapeList.push();
K
kener 已提交
555
            return;
K
kener 已提交
556
        },
K
kener 已提交
557
        
K
kener 已提交
558 559 560 561 562
        _syncHandleShape : function () {
            if (this.zoomOption.orient == 'horizontal') {
                this._startShape.style.x = this._fillerShae.style.x - this._handleSize;
                this._endShape.style.x = this._fillerShae.style.x
                                    + this._fillerShae.style.width;
K
kener 已提交
563
                
K
kener 已提交
564 565 566
                this._zoom.start = Math.floor(
                    (this._startShape.style.x - this._location.x)
                    / this._location.width * 100
K
kener 已提交
567
                );
K
kener 已提交
568 569 570
                this._zoom.end = Math.ceil(
                    (this._endShape.style.x + this._handleSize - this._location.x)
                    / this._location.width * 100
K
kener 已提交
571 572 573
                );
            }
            else {
K
kener 已提交
574 575 576 577 578 579
                this._startShape.style.y = this._fillerShae.style.y - this._handleSize;
                this._endShape.style.y = this._fillerShae.style.y
                                    + this._fillerShae.style.height;
                this._zoom.start = Math.floor(
                    (this._startShape.style.y - this._location.y)
                    / this._location.height * 100
K
kener 已提交
580
                );
K
kener 已提交
581 582 583
                this._zoom.end = Math.ceil(
                    (this._endShape.style.y + this._handleSize - this._location.y)
                    / this._location.height * 100
K
kener 已提交
584 585 586
                );
            }

K
kener 已提交
587 588
            this.zr.modShape(this._startShape.id);
            this.zr.modShape(this._endShape.id);
K
kener 已提交
589 590
            
            // 同步边框
K
kener 已提交
591
            this._syncFrameShape();
K
kener 已提交
592
            
K
kener 已提交
593 594
            this.zr.refresh();
        },
K
kener 已提交
595

K
kener 已提交
596
        _syncFillerShape : function () {
K
kener 已提交
597 598
            var a;
            var b;
K
kener 已提交
599 600 601 602 603 604 605 606
            if (this.zoomOption.orient == 'horizontal') {
                a = this._startShape.style.x;
                b = this._endShape.style.x;
                this._fillerShae.style.x = Math.min(a, b) + this._handleSize;
                this._fillerShae.style.width = Math.abs(a - b) - this._handleSize;
                this._zoom.start = Math.floor(
                    (Math.min(a, b) - this._location.x)
                    / this._location.width * 100
K
kener 已提交
607
                );
K
kener 已提交
608 609 610
                this._zoom.end = Math.ceil(
                    (Math.max(a, b) + this._handleSize - this._location.x)
                    / this._location.width * 100
K
kener 已提交
611 612 613
                );
            }
            else {
K
kener 已提交
614 615 616 617 618 619 620
                a = this._startShape.style.y;
                b = this._endShape.style.y;
                this._fillerShae.style.y = Math.min(a, b) + this._handleSize;
                this._fillerShae.style.height = Math.abs(a - b) - this._handleSize;
                this._zoom.start = Math.floor(
                    (Math.min(a, b) - this._location.y)
                    / this._location.height * 100
K
kener 已提交
621
                );
K
kener 已提交
622 623 624
                this._zoom.end = Math.ceil(
                    (Math.max(a, b) + this._handleSize - this._location.y)
                    / this._location.height * 100
K
kener 已提交
625 626 627
                );
            }

K
kener 已提交
628
            this.zr.modShape(this._fillerShae.id);
K
kener 已提交
629 630
            
            // 同步边框
K
kener 已提交
631
            this._syncFrameShape();
K
kener 已提交
632
            
K
kener 已提交
633 634
            this.zr.refresh();
        },
635
        
K
kener 已提交
636 637 638 639 640 641 642 643
        _syncFrameShape : function () {
            if (this.zoomOption.orient == 'horizontal') {
                this._startFrameShape.style.width = 
                    this._fillerShae.style.x - this._location.x;
                this._endFrameShape.style.x = 
                    this._fillerShae.style.x + this._fillerShae.style.width;
                this._endFrameShape.style.width = 
                    this._location.x + this._location.width - this._endFrameShape.style.x;
K
kener 已提交
644 645
            }
            else {
K
kener 已提交
646 647 648 649 650 651
                this._startFrameShape.style.height = 
                    this._fillerShae.style.y - this._location.y;
                this._endFrameShape.style.y = 
                    this._fillerShae.style.y + this._fillerShae.style.height;
                this._endFrameShape.style.height = 
                    this._location.y + this._location.height - this._endFrameShape.style.y;
K
kener 已提交
652 653
            }
                    
K
kener 已提交
654 655
            this.zr.modShape(this._startFrameShape.id);
            this.zr.modShape(this._endFrameShape.id);
K
kener 已提交
656
        },
K
kener 已提交
657
        
K
kener 已提交
658 659
        _syncShape : function () {
            if (!this.zoomOption.show) {
K
kener 已提交
660 661 662
                // 没有伸缩控件
                return;
            }
K
kener 已提交
663 664 665 666 667 668
            if (this.zoomOption.orient == 'horizontal') {
                this._startShape.style.x = this._location.x 
                                      + this._zoom.start / 100 * this._location.width;
                this._endShape.style.x = this._location.x 
                                    + this._zoom.end / 100 * this._location.width
                                    - this._handleSize;
669
                    
K
kener 已提交
670 671 672 673
                this._fillerShae.style.x = this._startShape.style.x + this._handleSize;
                this._fillerShae.style.width = this._endShape.style.x 
                                          - this._startShape.style.x
                                          - this._handleSize;
674 675
            }
            else {
K
kener 已提交
676 677 678 679 680
                this._startShape.style.y = this._location.y 
                                      + this._zoom.start / 100 * this._location.height;
                this._endShape.style.y = this._location.y 
                                    + this._zoom.end / 100 * this._location.height
                                    - this._handleSize;
681
                    
K
kener 已提交
682 683 684 685
                this._fillerShae.style.y = this._startShape.style.y + this._handleSize;
                this._fillerShae.style.height = this._endShape.style.y 
                                          - this._startShape.style.y
                                          - this._handleSize;
686 687
            }
            
K
kener 已提交
688 689 690
            this.zr.modShape(this._startShape.id);
            this.zr.modShape(this._endShape.id);
            this.zr.modShape(this._fillerShae.id);
K
kener 已提交
691
            // 同步边框
K
kener 已提交
692 693 694 695 696
            this._syncFrameShape();
            this.zr.refresh();
        },
        
         _syncData : function (dispatchNow) {
K
kener 已提交
697 698 699 700 701
            var target;
            var start;
            var end;
            var length;
            var data;
K
kener 已提交
702 703
            for (var key in this._originalData) {
                target = this._originalData[key];
K
kener 已提交
704 705 706
                for (var idx in target) {
                    data = target[idx];
                    length = data.length;
K
kener 已提交
707 708 709 710
                    start = Math.floor(this._zoom.start / 100 * length);
                    end = Math.ceil(this._zoom.end / 100 * length);
                    if (this.option[key][idx].type != ecConfig.CHART_TYPE_SCATTER) {
                        this.option[key][idx].data = data.slice(start, end);
K
kener 已提交
711 712 713
                    }
                    else {
                        // 散点图特殊处理
K
kener 已提交
714
                        this.option[key][idx].data = this._synScatterData(idx, data);
K
kener 已提交
715
                    }
K
kener 已提交
716 717 718
                }
            }

K
kener 已提交
719 720
            if (!this._isSilence && (this.zoomOption.realtime || dispatchNow)) {
                this.messageCenter.dispatch(
K
kener 已提交
721 722
                    ecConfig.EVENT.DATA_ZOOM,
                    null,
K
kener 已提交
723
                    {zoom: this._zoom}
K
kener 已提交
724
                );
K
kener 已提交
725 726
            }

K
kener 已提交
727 728 729
            this.zoomOption.start = this._zoom.start;
            this.zoomOption.end = this._zoom.end;
        },
K
kener 已提交
730
        
K
kener 已提交
731
        _synScatterData : function (seriesIndex, data) {
K
kener 已提交
732
            var newData = [];
K
kener 已提交
733
            var scale = this._zoom.scatterMap[seriesIndex];
K
kener 已提交
734 735 736 737 738 739
            var total;
            var xStart;
            var xEnd;
            var yStart;
            var yEnd;
            
K
kener 已提交
740
            if (this.zoomOption.orient == 'horizontal') {
K
kener 已提交
741
                total = scale.x.max - scale.x.min;
K
kener 已提交
742 743
                xStart = this._zoom.start / 100 * total + scale.x.min;
                xEnd = this._zoom.end / 100 * total + scale.x.min;
K
kener 已提交
744 745
                
                total = scale.y.max - scale.y.min;
K
kener 已提交
746 747
                yStart = this._zoom.start2 / 100 * total + scale.y.min;
                yEnd = this._zoom.end2 / 100 * total + scale.y.min;
K
kener 已提交
748 749 750
            }
            else {
                total = scale.x.max - scale.x.min;
K
kener 已提交
751 752
                xStart = this._zoom.start2 / 100 * total + scale.x.min;
                xEnd = this._zoom.end2 / 100 * total + scale.x.min;
K
kener 已提交
753 754
                
                total = scale.y.max - scale.y.min;
K
kener 已提交
755 756
                yStart = this._zoom.start / 100 * total + scale.y.min;
                yEnd = this._zoom.end / 100 * total + scale.y.min;
K
kener 已提交
757 758 759
            }
            
            // console.log(xStart,xEnd,yStart,yEnd);
K
kener 已提交
760
            var value;
K
kener 已提交
761
            for (var i = 0, l = data.length; i < l; i++) {
K
kener 已提交
762 763 764 765 766
                value = data[i].value || data[i];
                if (value[0] >= xStart 
                    && value[0] <= xEnd
                    && value[1] >= yStart
                    && value[1] <= yEnd
K
kener 已提交
767 768 769 770 771 772
                ) {
                    newData.push(data[i]);
                }
            }
            
            return newData;
K
kener 已提交
773
        },
K
kener 已提交
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811
        /**
         * 拖拽范围控制
         */
        __ondrift : function (shape, dx, dy) {
            if (this.zoomOption.zoomLock) {
                // zoomLock时把handle转成filler的拖拽
                shape = this._fillerShae;
            }
            
            var detailSize = shape._type == 'filler' ? this._handleSize : 0;
            if (this.zoomOption.orient == 'horizontal') {
                if (shape.style.x + dx - detailSize <= this._location.x) {
                    shape.style.x = this._location.x + detailSize;
                }
                else if (shape.style.x + dx + shape.style.width + detailSize
                         >= this._location.x + this._location.width
                ) {
                    shape.style.x = this._location.x + this._location.width
                                - shape.style.width - detailSize;
                }
                else {
                    shape.style.x += dx;
                }
            }
            else {
                if (shape.style.y + dy - detailSize <= this._location.y) {
                    shape.style.y = this._location.y + detailSize;
                }
                else if (shape.style.y + dy + shape.style.height + detailSize
                         >= this._location.y + this._location.height
                ) {
                    shape.style.y = this._location.y + this._location.height
                                - shape.style.height - detailSize;
                }
                else {
                    shape.style.y += dy;
                }
            }
K
kener 已提交
812

K
kener 已提交
813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
            if (shape._type == 'filler') {
                this._syncHandleShape();
            }
            else {
                this._syncFillerShape();
            }

            if (this.zoomOption.realtime) {
                this._syncData();
            }
            else {
                clearTimeout(this._syncTicket);
                var self = this;
                this._syncTicket = setTimeout(function (){
                    self._syncData();
                }, 200);
            }

            return true;
        },
        
        __ondragend : function () {
            this.isDragend = true;
        },
        
K
kener 已提交
838 839 840
        /**
         * 数据项被拖拽出去
         */
K
kener 已提交
841 842
        ondragend : function (param, status) {
            if (!this.isDragend || !param.target) {
K
kener 已提交
843 844 845 846
                // 没有在当前实例上发生拖拽行为则直接返回
                return;
            }

K
kener 已提交
847
             this._syncData();
K
kener 已提交
848 849 850 851

            // 别status = {}赋值啊!!
            status.dragOut = true;
            status.dragIn = true;
K
kener 已提交
852 853
            if (!this._isSilence && !this.zoomOption.realtime) {
                this.messageCenter.dispatch(
K
kener 已提交
854 855
                    ecConfig.EVENT.DATA_ZOOM,
                    null,
K
kener 已提交
856
                    {zoom: this._zoom}
K
kener 已提交
857
                );
K
kener 已提交
858 859 860
            }
            status.needRefresh = false; // 会有消息触发fresh,不用再刷一遍
            // 处理完拖拽事件后复位
K
kener 已提交
861
            this.isDragend = false;
K
kener 已提交
862 863

            return;
K
kener 已提交
864
        },
K
kener 已提交
865

K
kener 已提交
866
        ondataZoom : function (param, status) {
K
kener 已提交
867 868
            status.needRefresh = true;
            return;
K
kener 已提交
869
        },
870
        
K
kener 已提交
871 872 873 874 875 876 877 878
        absoluteZoom : function (param) {
            this.zoomOption.start = this._zoom.start = param.start;
            this.zoomOption.end = this._zoom.end = param.end;
            this.zoomOption.start2 = this._zoom.start2 = param.start2;
            this.zoomOption.end2 = this._zoom.end2 = param.end2;
            //console.log(rect,gridArea,this._zoom,total)
            this._syncShape();
            this._syncData(true);
K
kener 已提交
879
            return;
K
kener 已提交
880
        },
K
kener 已提交
881
        
K
kener 已提交
882
        rectZoom : function (param) {
883 884
            if (!param) {
                // 重置拖拽
K
kener 已提交
885 886 887 888
                this.zoomOption.start = 
                this.zoomOption.start2 = 
                this._zoom.start = 
                this._zoom.start2 = 0;
K
kener 已提交
889
                    
K
kener 已提交
890 891 892 893
                this.zoomOption.end =
                this.zoomOption.end2 = 
                this._zoom.end = 
                this._zoom.end2 = 100;
K
kener 已提交
894
                
K
kener 已提交
895 896 897
                this._syncShape();
                this._syncData(true);
                return this._zoom;
898
            }
K
kener 已提交
899
            var gridArea = this.component.grid.getArea();
900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
            var rect = {
                x : param.x,
                y : param.y,
                width : param.width,
                height : param.height
            };
            // 修正方向框选
            if (rect.width < 0) {
                rect.x += rect.width;
                rect.width = -rect.width;
            }
            if (rect.height < 0) {
                rect.y += rect.height;
                rect.height = -rect.height;
            }
K
kener 已提交
915
            // console.log(rect,this._zoom);
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
            
            // 剔除无效缩放
            if (rect.x > gridArea.x + gridArea.width
                || rect.y > gridArea.y + gridArea.height
            ) {
                return false; // 无效缩放
            }
            
            // 修正框选超出
            if (rect.x < gridArea.x) {
                rect.x = gridArea.x;
            }
            if (rect.x + rect.width > gridArea.x + gridArea.width) {
                rect.width = gridArea.x + gridArea.width - rect.x;
            }
            if (rect.y + rect.height > gridArea.y + gridArea.height) {
                rect.height = gridArea.y + gridArea.height - rect.y;
            }
            
K
kener 已提交
935 936
            var total;
            var sdx = (rect.x - gridArea.x) / gridArea.width;
K
kener 已提交
937 938
            var edx = 1 - (rect.x + rect.width - gridArea.x) / gridArea.width;
            var sdy = 1 - (rect.y + rect.height - gridArea.y) / gridArea.height;
K
kener 已提交
939
            var edy = (rect.y - gridArea.y) / gridArea.height;
K
kener 已提交
940 941 942 943 944
            //console.log('this',sdy,edy,this._zoom.start,this._zoom.end)
            if (this.zoomOption.orient == 'horizontal') {
                total = this._zoom.end - this._zoom.start;
                this._zoom.start += total * sdx;
                this._zoom.end -= total * edx;
K
kener 已提交
945
                
K
kener 已提交
946 947 948
                total = this._zoom.end2 - this._zoom.start2;
                this._zoom.start2 += total * sdy;
                this._zoom.end2 -= total * edy;
K
kener 已提交
949 950
            }
            else {
K
kener 已提交
951 952 953
                total = this._zoom.end - this._zoom.start;
                this._zoom.start += total * sdy;
                this._zoom.end -= total * edy;
K
kener 已提交
954
                
K
kener 已提交
955 956 957 958 959 960 961 962 963 964 965 966 967 968
                total = this._zoom.end2 - this._zoom.start2;
                this._zoom.start2 += total * sdx;
                this._zoom.end2 -= total * edx;
            }
            //console.log(this._zoom.start,this._zoom.end,this._zoom.start2,this._zoom.end2)
            this.zoomOption.start = this._zoom.start;
            this.zoomOption.end = this._zoom.end;
            this.zoomOption.start2 = this._zoom.start2;
            this.zoomOption.end2 = this._zoom.end2;
            //console.log(rect,gridArea,this._zoom,total)
            this._syncShape();
            this._syncData(true);
            return this._zoom;
        },
K
kener 已提交
969
        
K
kener 已提交
970
        syncBackupData : function (curOption, optionBackup) {
K
kener 已提交
971
            var start;
K
kener 已提交
972
            var target = this._originalData['series'];
K
kener 已提交
973 974 975 976 977 978
            var curSeries = curOption.series;
            var curData;
            for (var i = 0, l = curSeries.length; i < l; i++) {
                curData = curSeries[i].data;
                if (target[i]) {
                    // dataZoom接管的
K
kener 已提交
979
                    start = Math.floor(this._zoom.start / 100 * target[i].length);
K
kener 已提交
980 981 982 983 984 985
                }
                else {
                    // 非dataZoom接管
                    start = 0;
                }
                for (var j = 0, k = curData.length; j < k; j++) {
K
kener 已提交
986 987 988 989 990
                    optionBackup.series[i].data[j + start] = curData[j];
                    if (target[i]) {
                        // 同步内部备份
                        target[i][j + start] 
                            = curData[j];
K
kener 已提交
991 992 993
                    }
                }
            }
K
kener 已提交
994
        },
995
        
K
kener 已提交
996 997 998
        silence : function (s) {
            this._isSilence = s;
        },
999
        
K
kener 已提交
1000 1001
        getRealDataIndex : function (sIdx, dIdx) {
            if (!this._originalData) {
K
kener 已提交
1002 1003
                return dIdx;
            }
K
kener 已提交
1004
            var sreies = this._originalData.series;
1005
            if (sreies[sIdx]) {
K
kener 已提交
1006
                return Math.floor(this._zoom.start / 100 * sreies[sIdx].length) 
1007 1008 1009
                       + dIdx;
            }
            return -1;
K
kener 已提交
1010
        },
K
kener 已提交
1011

K
kener 已提交
1012
        init : function (newOption, newComponent) {
K
kener 已提交
1013 1014
            this.option = newOption || this.option;
            this.component = newComponent || this.component;
K
kener 已提交
1015
            
K
kener 已提交
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
            this._fillerSize = 28;       // 控件大小,水平布局为高,纵向布局为宽
            this._handleSize = 8;        // 手柄大小
            // this._fillerShae;            // 填充
            // this._startShape;            // 起始手柄
            // this._endShape;              // 结束手柄
            // this._startFrameShape;       // 起始特效边框
            // this._endFrameShape;         // 结束特效边框
            // this._syncTicket;
            this._isSilence = false;
            // this._originalData;
K
kener 已提交
1026
            
K
kener 已提交
1027 1028
            this.option.dataZoom = this.reformOption(this.option.dataZoom);
            this.zoomOption = this.option.dataZoom;
K
kener 已提交
1029

K
kener 已提交
1030
            this.clear();
1031 1032
            
            // 自己show 或者 toolbox启用且dataZoom有效
K
kener 已提交
1033
            if (this.option.dataZoom.show
1034
                || (
K
kener 已提交
1035 1036
                    this.query(this.option, 'toolbox.show')
                    && this.query(this.option, 'toolbox.feature.dataZoom.show')
1037 1038
                )
            ) {
K
kener 已提交
1039 1040 1041 1042 1043
                // 位置参数,通过计算所得x, y, width, height
                this._location = this._getLocation();
                // 缩放参数
                this._zoom =  this._getZoom();
                this._backupData();
1044 1045
            }
            
K
kener 已提交
1046 1047 1048
            if (this.option.dataZoom.show) {
                this._buildShape();
                this._syncData();
K
kener 已提交
1049
            }
K
kener 已提交
1050
        },
K
kener 已提交
1051 1052 1053 1054

        /**
         * 避免dataZoom带来两次refresh,不设refresh接口,resize重复一下buildshape逻辑 
         */
K
kener 已提交
1055 1056
        resize : function () {
            this.clear();
K
kener 已提交
1057 1058
            
            // 自己show 或者 toolbox启用且dataZoom有效
K
kener 已提交
1059
            if (this.option.dataZoom.show
K
kener 已提交
1060
                || (
K
kener 已提交
1061 1062
                    this.query(this.option, 'toolbox.show')
                    && this.query(this.option, 'toolbox.feature.dataZoom.show')
K
kener 已提交
1063 1064
                )
            ) {
K
kener 已提交
1065 1066
                this._location = this._getLocation();
                this._zoom =  this._getZoom();
K
kener 已提交
1067 1068
            }
            
K
kener 已提交
1069 1070
            if (this.option.dataZoom.show) {
                this._buildShape();
K
kener 已提交
1071 1072
            }
        }
K
kener 已提交
1073 1074 1075 1076
    };
    
    zrUtil.inherits(DataZoom, Base);
    
1077 1078
    require('../component').define('dataZoom', DataZoom);
    
K
kener 已提交
1079 1080
    return DataZoom;
});