/** * echarts组件:漫游控制器 * * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 * @author Kener (@Kener-林峰, kener.linfeng@gmail.com) * */ define(function (require) { var Base = require('./base'); // 图形依赖 var RectangleShape = require('zrender/shape/Rectangle'); var SectorShape = require('zrender/shape/Sector'); var CircleShape = require('zrender/shape/Circle'); var ecConfig = require('../config'); ecConfig.roamController = { zlevel: 0, // 一级层叠 z: 4, // 二级层叠 show: true, x: 'left', // 水平安放位置,默认为全图左对齐,可选为: // 'center' ¦ 'left' ¦ 'right' // ¦ {number}(x坐标,单位px) y: 'top', // 垂直安放位置,默认为全图顶端,可选为: // 'top' ¦ 'bottom' ¦ 'center' // ¦ {number}(y坐标,单位px) width: 80, height: 120, backgroundColor: 'rgba(0,0,0,0)', borderColor: '#ccc', // 图例边框颜色 borderWidth: 0, // 图例边框线宽,单位px,默认为0(无边框) padding: 5, // 图例内边距,单位px,默认各方向内边距为5, // 接受数组分别设定上右下左边距,同css handleColor: '#6495ed', fillerColor: '#fff', step: 15, // 移动幅度 mapTypeControl: null }; var zrUtil = require('zrender/tool/util'); var zrColor = require('zrender/tool/color'); var zrEvent = require('zrender/tool/event'); /** * 构造函数 * @param {Object} messageCenter echart消息中心 * @param {ZRender} zr zrender实例 * @param {Object} option 图表参数 */ function RoamController(ecTheme, messageCenter, zr, option, myChart) { if (!option.roamController || !option.roamController.show) { return; } if (!option.roamController.mapTypeControl) { console.error('option.roamController.mapTypeControl has not been defined.'); return; } Base.call(this, ecTheme, messageCenter, zr, option, myChart); this.rcOption = option.roamController; var self = this; this._drictionMouseDown = function(params) { return self.__drictionMouseDown(params); }; this._drictionMouseUp = function(params) { return self.__drictionMouseUp(params); }; this._drictionMouseMove = function(params) { return self.__drictionMouseMove(params); }; this._drictionMouseOut = function(params) { return self.__drictionMouseOut(params); }; this._scaleHandler = function(params) { return self.__scaleHandler(params); }; this.refresh(option); } RoamController.prototype = { type: ecConfig.COMPONENT_TYPE_ROAMCONTROLLER, _buildShape: function () { if (!this.rcOption.show) { return; } // 元素组的位置参数,通过计算所得x, y, width, height this._itemGroupLocation = this._getItemGroupLocation(); this._buildBackground(); this._buildItem(); for (var i = 0, l = this.shapeList.length; i < l; i++) { this.zr.addShape(this.shapeList[i]); } }, /** * 构建所有漫游控制器元素 */ _buildItem: function () { this.shapeList.push(this._getDirectionShape('up')); this.shapeList.push(this._getDirectionShape('down')); this.shapeList.push(this._getDirectionShape('left')); this.shapeList.push(this._getDirectionShape('right')); this.shapeList.push(this._getScaleShape('scaleUp')); this.shapeList.push(this._getScaleShape('scaleDown')); }, _getDirectionShape: function(direction) { var r = this._itemGroupLocation.r; var x = this._itemGroupLocation.x + r; var y = this._itemGroupLocation.y + r; var sectorShape = { zlevel: this.getZlevelBase(), z: this.getZBase(), style: { x: x, // 圆心横坐标 y: y, // 圆心纵坐标 r: r, // 圆环外半径 startAngle: -45, endAngle: 45, color: this.rcOption.handleColor, text: '>', textX: x + r / 2 + 4, textY: y - 0.5, textAlign: 'center', textBaseline: 'middle', textPosition: 'specific', textColor: this.rcOption.fillerColor, textFont: Math.floor(r / 2) + 'px arial' }, highlightStyle: { color: zrColor.lift(this.rcOption.handleColor, -0.2), brushType: 'fill' }, clickable: true }; switch (direction) { case 'up': sectorShape.rotation = [Math.PI / 2, x, y]; break; case 'left': sectorShape.rotation = [Math.PI, x, y]; break; case 'down': sectorShape.rotation = [-Math.PI / 2, x, y]; break; } sectorShape = new SectorShape(sectorShape); sectorShape._roamType = direction; sectorShape.onmousedown = this._drictionMouseDown; sectorShape.onmouseup = this._drictionMouseUp; sectorShape.onmousemove = this._drictionMouseMove; sectorShape.onmouseout = this._drictionMouseOut; return sectorShape; }, _getScaleShape: function(text) { var width = this._itemGroupLocation.width; var height = this._itemGroupLocation.height - width; height = height < 0 ? 20 : height; // 确保height不为负 var r = Math.min(width / 2 - 5, height) / 2; var x = this._itemGroupLocation.x + (text === 'scaleDown' ? (width - r) : r); var y = this._itemGroupLocation.y + this._itemGroupLocation.height - r; var scaleShape = { zlevel: this.getZlevelBase(), z: this.getZBase(), style: { x: x, y: y, r: r, color: this.rcOption.handleColor, text: text === 'scaleDown' ? '-' : '+', textX: x, textY: y - 2, textAlign: 'center', textBaseline: 'middle', textPosition: 'specific', textColor: this.rcOption.fillerColor, textFont: Math.floor(r) + 'px verdana' }, highlightStyle: { color: zrColor.lift(this.rcOption.handleColor, -0.2), brushType: 'fill' }, clickable: true }; scaleShape = new CircleShape(scaleShape); scaleShape._roamType = text; scaleShape.onmousedown = this._scaleHandler; return scaleShape; }, _buildBackground: function () { var padding = this.reformCssArray(this.rcOption.padding); this.shapeList.push(new RectangleShape({ zlevel: this.getZlevelBase(), z: this.getZBase(), hoverable :false, style: { x: this._itemGroupLocation.x - padding[3], y: this._itemGroupLocation.y - padding[0], width: this._itemGroupLocation.width + padding[3] + padding[1], height: this._itemGroupLocation.height + padding[0] + padding[2], brushType: this.rcOption.borderWidth === 0 ? 'fill' : 'both', color: this.rcOption.backgroundColor, strokeColor: this.rcOption.borderColor, lineWidth: this.rcOption.borderWidth } })); }, /** * 根据选项计算漫游控制器实体的位置坐标 */ _getItemGroupLocation: function () { var padding = this.reformCssArray(this.rcOption.padding); var width = this.rcOption.width; var height = this.rcOption.height; var zrWidth = this.zr.getWidth(); var zrHeight = this.zr.getHeight(); var x; switch (this.rcOption.x) { case 'center' : x = Math.floor((zrWidth - width) / 2); break; case 'left' : x = padding[3] + this.rcOption.borderWidth; break; case 'right' : x = zrWidth - width - padding[1] - padding[3] - this.rcOption.borderWidth * 2; break; default : x = this.parsePercent(this.rcOption.x, zrWidth); break; } var y; switch (this.rcOption.y) { case 'top' : y = padding[0] + this.rcOption.borderWidth; break; case 'bottom' : y = zrHeight - height - padding[0] - padding[2] - this.rcOption.borderWidth * 2; break; case 'center' : y = Math.floor((zrHeight - height) / 2); break; default : y = this.parsePercent(this.rcOption.y, zrHeight); break; } return { x: x, y: y, r: width / 2, width: width, height: height }; }, __drictionMouseDown: function(params) { this.mousedown = true; this._drictionHandlerOn(params); }, __drictionMouseUp: function(params) { this.mousedown = false; this._drictionHandlerOff(params); }, __drictionMouseMove: function(params) { if (this.mousedown) { this._drictionHandlerOn(params); } }, __drictionMouseOut: function(params) { this._drictionHandlerOff(params); }, _drictionHandlerOn: function(params) { this._dispatchEvent(params.event, params.target._roamType); clearInterval(this.dircetionTimer); var self = this; this.dircetionTimer = setInterval(function() { self._dispatchEvent(params.event, params.target._roamType); }, 100); zrEvent.stop(params.event); }, _drictionHandlerOff: function(params) { clearInterval(this.dircetionTimer); }, __scaleHandler: function(params) { this._dispatchEvent(params.event, params.target._roamType); zrEvent.stop(params.event); }, _dispatchEvent: function(event, roamType){ this.messageCenter.dispatch( ecConfig.EVENT.ROAMCONTROLLER, event, { roamType: roamType, mapTypeControl: this.rcOption.mapTypeControl, step: this.rcOption.step }, this.myChart ); }, /** * 刷新 */ refresh: function (newOption) { if (newOption) { this.option = newOption || this.option; this.option.roamController = this.reformOption(this.option.roamController); this.rcOption = this.option.roamController; } this.clear(); this._buildShape(); } }; zrUtil.inherits(RoamController, Base); require('../component').define('roamController', RoamController); return RoamController; });