You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
13 KiB
356 lines
13 KiB
/**
|
|
* 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;
|
|
});
|
|
|
|
|
|
|