天津投入产出系统后端
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.
 
 
 
 
 
 

1244 lines
47 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 PolygonShape = require('zrender/shape/Polygon');
var IconShape = require('../util/shape/Icon');
var ecConfig = require('../config');
// 区域缩放控制器
ecConfig.dataZoom = {
zlevel: 0, // 一级层叠
z: 4, // 二级层叠
show: false,
orient: 'horizontal', // 布局方式,默认为水平布局,可选为:
// 'horizontal' ¦ 'vertical'
// x: {number}, // 水平安放位置,默认为根据grid参数适配,可选为:
// {number}(x坐标,单位px)
// y: {number}, // 垂直安放位置,默认为根据grid参数适配,可选为:
// {number}(y坐标,单位px)
// width: {number}, // 指定宽度,横向布局时默认为根据grid参数适配
// height: {number}, // 指定高度,纵向布局时默认为根据grid参数适配
backgroundColor: 'rgba(0,0,0,0)', // 背景颜色
dataBackgroundColor: '#eee', // 数据背景颜色
fillerColor: 'rgba(144,197,237,0.2)', // 填充颜色
handleColor: 'rgba(70,130,180,0.8)', // 手柄颜色
handleSize: 8,
showDetail: true,
// xAxisIndex: [], // 默认控制所有横向类目
// yAxisIndex: [], // 默认控制所有横向类目
// start: 0, // 默认为0
// end: 100, // 默认为全部 100%
realtime: true
// zoomLock: false // 是否锁定选择区域大小
};
var ecDate = require('../util/date');
var zrUtil = require('zrender/tool/util');
/**
* 构造函数
* @param {Object} messageCenter echart消息中心
* @param {ZRender} zr zrender实例
* @param {Object} option 图表参数
* @param {Object} component 组件
*/
function DataZoom(ecTheme, messageCenter, zr, option, myChart) {
Base.call(this, ecTheme, messageCenter, zr, option, myChart);
var self = this;
self._ondrift = function (dx, dy) {
return self.__ondrift(this, dx, dy);
};
self._ondragend = function () {
return self.__ondragend();
};
this._fillerSize = 30; // 控件大小,水平布局为高,纵向布局为宽
// this._fillerShae; // 填充
// this._startShape; // 起始手柄
// this._endShape; // 结束手柄
// this._startFrameShape; // 起始特效边框
// this._endFrameShape; // 结束特效边框
// this._syncTicket;
this._isSilence = false;
this._zoom = {};
// this._originalData;
this.option.dataZoom = this.reformOption(this.option.dataZoom);
this.zoomOption = this.option.dataZoom;
this._handleSize = this.zoomOption.handleSize;
if (!this.myChart.canvasSupported) {
// 不支持Canvas的强制关闭实时动画
this.zoomOption.realtime = false;
}
// 位置参数,通过计算所得x, y, width, height
this._location = this._getLocation();
// 缩放参数
this._zoom = this._getZoom();
this._backupData();
if (this.option.dataZoom.show) {
this._buildShape();
}
this._syncData();
}
DataZoom.prototype = {
type : ecConfig.COMPONENT_TYPE_DATAZOOM,
_buildShape : function () {
this._buildBackground();
this._buildFiller();
this._buildHandle();
this._buildFrame();
for (var i = 0, l = this.shapeList.length; i < l; i++) {
this.zr.addShape(this.shapeList[i]);
}
this._syncFrameShape();
},
/**
* 根据选项计算实体的位置坐标
*/
_getLocation : function () {
var x;
var y;
var width;
var height;
var grid = this.component.grid;
// 不指定则根据grid适配
if (this.zoomOption.orient == 'horizontal') {
// 水平布局
width = this.zoomOption.width || grid.getWidth();
height = this.zoomOption.height || this._fillerSize;
x = this.zoomOption.x != null ? this.zoomOption.x : grid.getX();
y = this.zoomOption.y != null ? this.zoomOption.y : (this.zr.getHeight() - height - 2);
}
else {
// 垂直布局
width = this.zoomOption.width || this._fillerSize;
height = this.zoomOption.height || grid.getHeight();
x = this.zoomOption.x != null ? this.zoomOption.x : 2;
y = this.zoomOption.y != null ? this.zoomOption.y : grid.getY();
}
return {
x : x,
y : y,
width : width,
height : height
};
},
/**
* 计算缩放参数
* 修正单坐标轴只传对象为数组。
*/
_getZoom : function () {
var series = this.option.series;
var xAxis = this.option.xAxis;
if (xAxis && !(xAxis instanceof Array)) {
xAxis = [xAxis];
this.option.xAxis = xAxis;
}
var yAxis = this.option.yAxis;
if (yAxis && !(yAxis instanceof Array)) {
yAxis = [yAxis];
this.option.yAxis = yAxis;
}
var zoomSeriesIndex = [];
var xAxisIndex;
var yAxisIndex;
var zOptIdx = this.zoomOption.xAxisIndex;
if (xAxis && zOptIdx == null) {
xAxisIndex = [];
for (var i = 0, l = xAxis.length; i < l; i++) {
// 横纵默认为类目轴
if (xAxis[i].type == 'category' || xAxis[i].type == null) {
xAxisIndex.push(i);
}
}
}
else {
if (zOptIdx instanceof Array) {
xAxisIndex = zOptIdx;
}
else if (zOptIdx != null) {
xAxisIndex = [zOptIdx];
}
else {
xAxisIndex = [];
}
}
zOptIdx = this.zoomOption.yAxisIndex;
if (yAxis && zOptIdx == null) {
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 (zOptIdx != null) {
yAxisIndex = [zOptIdx];
}
else {
yAxisIndex = [];
}
}
// 找到缩放控制的所有series
var serie;
for (var i = 0, l = series.length; i < l; i++) {
serie = series[i];
if (serie.type != ecConfig.CHART_TYPE_LINE
&& serie.type != ecConfig.CHART_TYPE_BAR
&& serie.type != ecConfig.CHART_TYPE_SCATTER
&& serie.type != ecConfig.CHART_TYPE_K
) {
continue;
}
for (var j = 0, k = xAxisIndex.length; j < k; j++) {
if (xAxisIndex[j] == (serie.xAxisIndex || 0)) {
zoomSeriesIndex.push(i);
break;
}
}
for (var j = 0, k = yAxisIndex.length; j < k; j++) {
if (yAxisIndex[j] == (serie.yAxisIndex || 0)) {
zoomSeriesIndex.push(i);
break;
}
}
// 不指定接管坐标轴,则散点图、双数值轴折线图柱形图都被纳入接管范围
if (this.zoomOption.xAxisIndex == null
&& this.zoomOption.yAxisIndex == null
&& serie.data
&& this.getDataFromOption(serie.data[0]) instanceof Array
&& (serie.type == ecConfig.CHART_TYPE_SCATTER
|| serie.type == ecConfig.CHART_TYPE_LINE
|| serie.type == ecConfig.CHART_TYPE_BAR)
) {
zoomSeriesIndex.push(i);
}
}
var start = this._zoom.start != null
? this._zoom.start
: (this.zoomOption.start != null ? this.zoomOption.start : 0);
var end = this._zoom.end != null
? this._zoom.end
: (this.zoomOption.end != null ? this.zoomOption.end : 100);
if (start > end) {
// 大小颠倒自动翻转
start = start + end;
end = start - end;
start = start - end;
}
var size = Math.round(
(end - start) / 100
* (
this.zoomOption.orient == 'horizontal'
? this._location.width : this._location.height
)
);
return {
start : start,
end : end,
start2 : 0,
end2 : 100,
size : size,
xAxisIndex : xAxisIndex,
yAxisIndex : yAxisIndex,
seriesIndex : zoomSeriesIndex,
scatterMap : this._zoom.scatterMap || {}
};
},
_backupData : function () {
this._originalData = {
xAxis : {},
yAxis : {},
series : {}
};
var xAxis = this.option.xAxis;
var xAxisIndex = this._zoom.xAxisIndex;
for (var i = 0, l = xAxisIndex.length; i < l; i++) {
this._originalData.xAxis[xAxisIndex[i]] = xAxis[xAxisIndex[i]].data;
}
var yAxis = this.option.yAxis;
var yAxisIndex = this._zoom.yAxisIndex;
for (var i = 0, l = yAxisIndex.length; i < l; i++) {
this._originalData.yAxis[yAxisIndex[i]] = yAxis[yAxisIndex[i]].data;
}
var series = this.option.series;
var seriesIndex = this._zoom.seriesIndex;
var serie;
for (var i = 0, l = seriesIndex.length; i < l; i++) {
serie = series[seriesIndex[i]];
this._originalData.series[seriesIndex[i]] = serie.data;
if (serie.data
&& this.getDataFromOption(serie.data[0]) instanceof Array
&& (serie.type == ecConfig.CHART_TYPE_SCATTER
|| serie.type == ecConfig.CHART_TYPE_LINE
|| serie.type == ecConfig.CHART_TYPE_BAR)
) {
this._backupScale();
this._calculScatterMap(seriesIndex[i]);
}
}
},
// 不止是scatter,双数值轴也使用此方法
_calculScatterMap : function (seriesIndex) {
this._zoom.scatterMap = this._zoom.scatterMap || {};
this._zoom.scatterMap[seriesIndex] = this._zoom.scatterMap[seriesIndex] || {};
var componentLibrary = require('../component');
// x轴极值
var Axis = componentLibrary.get('axis');
var axisOption = zrUtil.clone(this.option.xAxis);
if (axisOption[0].type == 'category') {
axisOption[0].type = 'value';
}
// axisOption[0].scale = true;
// axisOption[0].boundary = [0, 0];
if (axisOption[1] && axisOption[1].type == 'category') {
axisOption[1].type = 'value';
}
var vAxis = new Axis(
this.ecTheme,
null, // messageCenter
false, // this.zr
{
xAxis: axisOption,
series : this.option.series
},
this,
'xAxis'
);
var axisIndex = this.option.series[seriesIndex].xAxisIndex || 0;
this._zoom.scatterMap[seriesIndex].x = vAxis.getAxis(axisIndex).getExtremum();
vAxis.dispose();
// y轴极值
axisOption = zrUtil.clone(this.option.yAxis);
if (axisOption[0].type == 'category') {
axisOption[0].type = 'value';
}
// axisOption[0].scale = true;
// axisOption[1].boundary = [0, 0];
if (axisOption[1] && axisOption[1].type == 'category') {
axisOption[1].type = 'value';
}
vAxis = new Axis(
this.ecTheme,
null, // messageCenter
false, // this.zr
{
yAxis: axisOption,
series : this.option.series
},
this,
'yAxis'
);
axisIndex = this.option.series[seriesIndex].yAxisIndex || 0;
this._zoom.scatterMap[seriesIndex].y = vAxis.getAxis(axisIndex).getExtremum();
vAxis.dispose();
// console.log(this._zoom.scatterMap);
},
_buildBackground : function () {
var width = this._location.width;
var height = this._location.height;
// 背景
this.shapeList.push(new RectangleShape({
zlevel: this.getZlevelBase(),
z: this.getZBase(),
hoverable :false,
style : {
x : this._location.x,
y : this._location.y,
width : width,
height : height,
color : this.zoomOption.backgroundColor
}
}));
// 数据阴影
var maxLength = 0;
var xAxis = this._originalData.xAxis;
var xAxisIndex = this._zoom.xAxisIndex;
for (var i = 0, l = xAxisIndex.length; i < l; i++) {
maxLength = Math.max(
maxLength, xAxis[xAxisIndex[i]].length
);
}
var yAxis = this._originalData.yAxis;
var yAxisIndex = this._zoom.yAxisIndex;
for (var i = 0, l = yAxisIndex.length; i < l; i++) {
maxLength = Math.max(
maxLength, yAxis[yAxisIndex[i]].length
);
}
var seriesIndex = this._zoom.seriesIndex[0];
var data = this._originalData.series[seriesIndex];
var maxValue = Number.MIN_VALUE;
var minValue = Number.MAX_VALUE;
var value;
for (var i = 0, l = data.length; i < l; i++) {
value = this.getDataFromOption(data[i], 0);
if (this.option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) {
value = value[1]; // 收盘价
}
if (isNaN(value)) {
value = 0;
}
maxValue = Math.max(maxValue, value);
minValue = Math.min(minValue, value);
}
var valueRange = maxValue - minValue;
var pointList = [];
var x = width / (maxLength - (maxLength > 1 ? 1 : 0));
var y = height / (maxLength - (maxLength > 1 ? 1 : 0));
var step = 1;
if (this.zoomOption.orient == 'horizontal' && x < 1) {
step = Math.floor(maxLength * 3 / width);
}
else if (this.zoomOption.orient == 'vertical' && y < 1){
step = Math.floor(maxLength * 3 / height);
}
for (var i = 0, l = maxLength; i < l; i += step) {
value = this.getDataFromOption(data[i], 0);
if (this.option.series[seriesIndex].type == ecConfig.CHART_TYPE_K) {
value = value[1]; // 收盘价
}
if (isNaN(value)) {
value = 0;
}
if (this.zoomOption.orient == 'horizontal') {
pointList.push([
this._location.x + x * i,
this._location.y + height - 1 - Math.round(
(value - minValue) / valueRange * (height - 10)
)
]);
}
else {
pointList.push([
this._location.x + 1 + Math.round(
(value - minValue) / valueRange * (width - 10)
),
this._location.y + y * (l - i - 1)
]);
}
}
if (this.zoomOption.orient == 'horizontal') {
pointList.push([
this._location.x + width,
this._location.y + height
]);
pointList.push([
this._location.x, this._location.y + height
]);
}
else {
pointList.push([
this._location.x, this._location.y
]);
pointList.push([
this._location.x, this._location.y + height
]);
}
this.shapeList.push(new PolygonShape({
zlevel: this.getZlevelBase(),
z: this.getZBase(),
style : {
pointList : pointList,
color : this.zoomOption.dataBackgroundColor
},
hoverable : false
}));
},
/**
* 构建填充物
*/
_buildFiller : function () {
this._fillerShae = {
zlevel: this.getZlevelBase(),
z: this.getZBase(),
draggable : true,
ondrift : this._ondrift,
ondragend : this._ondragend,
_type : 'filler'
};
if (this.zoomOption.orient == 'horizontal') {
// 横向
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,
// lineWidth: 2,
text : ':::',
textPosition : 'inside'
};
}
else {
// 纵向
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,
// lineWidth: 2,
text : '::',
textPosition : 'inside'
};
}
this._fillerShae.highlightStyle = {
brushType: 'fill',
color : 'rgba(0,0,0,0)'
/*
color : require('zrender/tool/color').alpha(
this._fillerShae.style.color, 0
)
*/
};
this._fillerShae = new RectangleShape(this._fillerShae);
this.shapeList.push(this._fillerShae);
},
/**
* 构建拖拽手柄
*/
_buildHandle : function () {
var detail = this.zoomOption.showDetail ? this._getDetail() : {start: '',end: ''};
this._startShape = {
zlevel: this.getZlevelBase(),
z: this.getZBase(),
draggable : true,
style : {
iconType: 'rectangle',
x: this._location.x,
y: this._location.y,
width: this._handleSize,
height: this._handleSize,
color: this.zoomOption.handleColor,
text: '=',
textPosition: 'inside'
},
highlightStyle: {
text: detail.start,
brushType: 'fill',
textPosition: 'left'
},
ondrift: this._ondrift,
ondragend: this._ondragend
};
if (this.zoomOption.orient == 'horizontal') {
this._startShape.style.height = this._location.height;
this._endShape = zrUtil.clone(this._startShape);
this._startShape.style.x = this._fillerShae.style.x - this._handleSize,
this._endShape.style.x = this._fillerShae.style.x + this._fillerShae.style.width;
this._endShape.highlightStyle.text = detail.end;
this._endShape.highlightStyle.textPosition = 'right';
}
else {
this._startShape.style.width = this._location.width;
this._endShape = zrUtil.clone(this._startShape);
this._startShape.style.y = this._fillerShae.style.y + this._fillerShae.style.height;
this._startShape.highlightStyle.textPosition = 'bottom';
this._endShape.style.y = this._fillerShae.style.y - this._handleSize;
this._endShape.highlightStyle.text = detail.end;
this._endShape.highlightStyle.textPosition = 'top';
}
this._startShape = new IconShape(this._startShape);
this._endShape = new IconShape(this._endShape);
this.shapeList.push(this._startShape);
this.shapeList.push(this._endShape);
},
/**
* 构建特效边框
*/
_buildFrame : function () {
// 特效框线,亚像素优化
var x = this.subPixelOptimize(this._location.x, 1);
var y = this.subPixelOptimize(this._location.y, 1);
this._startFrameShape = {
zlevel: this.getZlevelBase(),
z: this.getZBase(),
hoverable :false,
style : {
x : x,
y : y,
width : this._location.width - (x > this._location.x ? 1 : 0),
height : this._location.height - (y > this._location.y ? 1 : 0),
lineWidth: 1,
brushType: 'stroke',
strokeColor : this.zoomOption.handleColor
}
};
this._endFrameShape = zrUtil.clone(this._startFrameShape);
this._startFrameShape = new RectangleShape(this._startFrameShape);
this._endFrameShape = new RectangleShape(this._endFrameShape);
this.shapeList.push(this._startFrameShape);
this.shapeList.push(this._endFrameShape);
return;
},
_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;
this._zoom.start = (
this._startShape.style.x - this._location.x
) / this._location.width * 100;
this._zoom.end = (
this._endShape.style.x + this._handleSize - this._location.x
) / this._location.width * 100;
}
else {
this._startShape.style.y = this._fillerShae.style.y + this._fillerShae.style.height;
this._endShape.style.y = this._fillerShae.style.y - this._handleSize;
this._zoom.start = (
this._location.y + this._location.height
- this._startShape.style.y
) / this._location.height * 100;
this._zoom.end = (
this._location.y + this._location.height
- this._endShape.style.y - this._handleSize
) / this._location.height * 100;
}
this.zr.modShape(this._startShape.id);
this.zr.modShape(this._endShape.id);
// 同步边框
this._syncFrameShape();
this.zr.refreshNextFrame();
},
_syncFillerShape : function () {
var a;
var b;
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.min(a, b) - this._location.x
) / this._location.width * 100;
this._zoom.end = (
Math.max(a, b) + this._handleSize - this._location.x
) / this._location.width * 100;
}
else {
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 = (
this._location.y + this._location.height - Math.max(a, b)
) / this._location.height * 100;
this._zoom.end = (
this._location.y + this._location.height - Math.min(a, b) - this._handleSize
) / this._location.height * 100;
}
this.zr.modShape(this._fillerShae.id);
// 同步边框
this._syncFrameShape();
this.zr.refreshNextFrame();
},
_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;
}
else {
this._startFrameShape.style.y =
this._fillerShae.style.y + this._fillerShae.style.height;
this._startFrameShape.style.height =
this._location.y + this._location.height - this._startFrameShape.style.y;
this._endFrameShape.style.height =
this._fillerShae.style.y - this._location.y;
}
this.zr.modShape(this._startFrameShape.id);
this.zr.modShape(this._endFrameShape.id);
},
_syncShape : function () {
if (!this.zoomOption.show) {
// 没有伸缩控件
return;
}
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;
this._fillerShae.style.x = this._startShape.style.x + this._handleSize;
this._fillerShae.style.width = this._endShape.style.x
- this._startShape.style.x
- this._handleSize;
}
else {
this._startShape.style.y = this._location.y + this._location.height
- this._zoom.start / 100 * this._location.height;
this._endShape.style.y = this._location.y + this._location.height
- this._zoom.end / 100 * this._location.height
- this._handleSize;
this._fillerShae.style.y = this._endShape.style.y + this._handleSize;
this._fillerShae.style.height = this._startShape.style.y
- this._endShape.style.y
- this._handleSize;
}
this.zr.modShape(this._startShape.id);
this.zr.modShape(this._endShape.id);
this.zr.modShape(this._fillerShae.id);
// 同步边框
this._syncFrameShape();
this.zr.refresh();
},
_syncData : function (dispatchNow) {
var target;
var start;
var end;
var length;
var data;
for (var key in this._originalData) {
target = this._originalData[key];
for (var idx in target) {
data = target[idx];
if (data == null) {
continue;
}
length = data.length;
start = Math.floor(this._zoom.start / 100 * length);
end = Math.ceil(this._zoom.end / 100 * length);
if (!(this.getDataFromOption(data[0]) instanceof Array)
|| this.option[key][idx].type == ecConfig.CHART_TYPE_K
) {
this.option[key][idx].data = data.slice(start, end);
}
else {
// 散点图,双数值轴折线图柱形图特殊处理
// axis.data[0]不会是Array,所以axis的情况不会走进这个分支
this._setScale();
this.option[key][idx].data = this._synScatterData(idx, data);
}
}
}
if (!this._isSilence && (this.zoomOption.realtime || dispatchNow)) {
this.messageCenter.dispatch(
ecConfig.EVENT.DATA_ZOOM,
null,
{zoom: this._zoom},
this.myChart
);
}
//this.zoomOption.start = this._zoom.start;
//this.zoomOption.end = this._zoom.end;
},
_synScatterData : function (seriesIndex, data) {
if (this._zoom.start === 0
&& this._zoom.end == 100
&& this._zoom.start2 === 0
&& this._zoom.end2 == 100
) {
return data;
}
var newData = [];
var scale = this._zoom.scatterMap[seriesIndex];
var total;
var xStart;
var xEnd;
var yStart;
var yEnd;
if (this.zoomOption.orient == 'horizontal') {
total = scale.x.max - scale.x.min;
xStart = this._zoom.start / 100 * total + scale.x.min;
xEnd = this._zoom.end / 100 * total + scale.x.min;
total = scale.y.max - scale.y.min;
yStart = this._zoom.start2 / 100 * total + scale.y.min;
yEnd = this._zoom.end2 / 100 * total + scale.y.min;
}
else {
total = scale.x.max - scale.x.min;
xStart = this._zoom.start2 / 100 * total + scale.x.min;
xEnd = this._zoom.end2 / 100 * total + scale.x.min;
total = scale.y.max - scale.y.min;
yStart = this._zoom.start / 100 * total + scale.y.min;
yEnd = this._zoom.end / 100 * total + scale.y.min;
}
var dataMappingMethods;
if (dataMappingMethods = scale.x.dataMappingMethods) {
xStart = dataMappingMethods.coord2Value(xStart);
xEnd = dataMappingMethods.coord2Value(xEnd);
}
if (dataMappingMethods = scale.y.dataMappingMethods) {
yStart = dataMappingMethods.coord2Value(yStart);
yEnd = dataMappingMethods.coord2Value(yEnd);
}
// console.log(xStart,xEnd,yStart,yEnd);
var value;
for (var i = 0, l = data.length; i < l; i++) {
value = data[i].value || data[i];
if (value[0] >= xStart
&& value[0] <= xEnd
&& value[1] >= yStart
&& value[1] <= yEnd
) {
newData.push(data[i]);
}
}
return newData;
},
/**
* 发生缩放后修改axis的scale
*/
_setScale: function() {
var needScale = this._zoom.start !== 0
|| this._zoom.end !== 100
|| this._zoom.start2 !== 0
|| this._zoom.end2 !== 100;
var axis = {
xAxis : this.option.xAxis,
yAxis : this.option.yAxis
};
for (var key in axis) {
for (var i = 0, l = axis[key].length; i < l; i++) {
axis[key][i].scale = needScale || axis[key][i]._scale;
}
}
},
/**
* 备份可能存在的scale设置
*/
_backupScale: function() {
var axis = {
xAxis : this.option.xAxis,
yAxis : this.option.yAxis
};
for (var key in axis) {
for (var i = 0, l = axis[key].length; i < l; i++) {
axis[key][i]._scale = axis[key][i].scale;
}
}
},
/**
* 获取当前定位
*/
_getDetail : function () {
var key = ['xAxis', 'yAxis'];
for (var i = 0, l = key.length; i < l; i++) {
var target = this._originalData[key[i]];
for (var idx in target) {
var data = target[idx];
if (data == null) {
continue;
}
var length = data.length;
var start = Math.floor(this._zoom.start / 100 * length);
var end = Math.ceil(this._zoom.end / 100 * length);
end -= end > 0 ? 1 : 0;
return {
start : this.getDataFromOption(data[start]),
end : this.getDataFromOption(data[end])
};
}
}
key = this.zoomOption.orient == 'horizontal' ? 'xAxis' : 'yAxis';
var seriesIndex = this._zoom.seriesIndex[0];
var axisIndex = this.option.series[seriesIndex][key + 'Index'] || 0;
var axisType = this.option[key][axisIndex].type;
var min = this._zoom.scatterMap[seriesIndex][key.charAt(0)].min;
var max = this._zoom.scatterMap[seriesIndex][key.charAt(0)].max;
var gap = max - min;
if (axisType == 'value') {
return {
start : min + gap * this._zoom.start / 100,
end : min + gap * this._zoom.end / 100
};
}
else if (axisType == 'time') {
// 最优解
max = min + gap * this._zoom.end / 100;
min = min + gap * this._zoom.start / 100;
var formatter = ecDate.getAutoFormatter(min, max).formatter;
return {
start : ecDate.format(formatter, min),
end : ecDate.format(formatter, max)
};
}
return {
start : '',
end : ''
};
},
/**
* 拖拽范围控制
*/
__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;
}
}
if (shape._type == 'filler') {
this._syncHandleShape();
}
else {
this._syncFillerShape();
}
if (this.zoomOption.realtime) {
this._syncData();
}
if (this.zoomOption.showDetail) {
var detail = this._getDetail();
this._startShape.style.text = this._startShape.highlightStyle.text = detail.start;
this._endShape.style.text = this._endShape.highlightStyle.text = detail.end;
this._startShape.style.textPosition = this._startShape.highlightStyle.textPosition;
this._endShape.style.textPosition = this._endShape.highlightStyle.textPosition;
}
return true;
},
__ondragend : function () {
if (this.zoomOption.showDetail) {
this._startShape.style.text = this._endShape.style.text = '=';
this._startShape.style.textPosition = this._endShape.style.textPosition = 'inside';
this.zr.modShape(this._startShape.id);
this.zr.modShape(this._endShape.id);
this.zr.refreshNextFrame();
}
this.isDragend = true;
},
/**
* 数据项被拖拽出去
*/
ondragend : function (param, status) {
if (!this.isDragend || !param.target) {
// 没有在当前实例上发生拖拽行为则直接返回
return;
}
!this.zoomOption.realtime && this._syncData();
// 别status = {}赋值啊!!
status.dragOut = true;
status.dragIn = true;
if (!this._isSilence && !this.zoomOption.realtime) {
this.messageCenter.dispatch(
ecConfig.EVENT.DATA_ZOOM,
null,
{zoom: this._zoom},
this.myChart
);
}
status.needRefresh = false; // 会有消息触发fresh,不用再刷一遍
// 处理完拖拽事件后复位
this.isDragend = false;
return;
},
ondataZoom : function (param, status) {
status.needRefresh = true;
return;
},
absoluteZoom : function (param) {
this._zoom.start = param.start;
this._zoom.end = param.end;
this._zoom.start2 = param.start2;
this._zoom.end2 = param.end2;
this._syncShape();
this._syncData(true);
return;
},
rectZoom : function (param) {
if (!param) {
// 重置拖拽
//this.zoomOption.start =
//this.zoomOption.start2 =
this._zoom.start = this._zoom.start2 = 0;
//this.zoomOption.end =
//this.zoomOption.end2 =
this._zoom.end = this._zoom.end2 = 100;
this._syncShape();
this._syncData(true);
return this._zoom;
}
var gridArea = this.component.grid.getArea();
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;
}
// console.log(rect,this._zoom);
// 剔除无效缩放
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;
}
var total;
var sdx = (rect.x - gridArea.x) / gridArea.width;
var edx = 1 - (rect.x + rect.width - gridArea.x) / gridArea.width;
var sdy = 1 - (rect.y + rect.height - gridArea.y) / gridArea.height;
var edy = (rect.y - gridArea.y) / gridArea.height;
// 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;
total = this._zoom.end2 - this._zoom.start2;
this._zoom.start2 += total * sdy;
this._zoom.end2 -= total * edy;
}
else {
total = this._zoom.end - this._zoom.start;
this._zoom.start += total * sdy;
this._zoom.end -= total * edy;
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;
},
syncBackupData : function (curOption) {
var start;
var target = this._originalData['series'];
var curSeries = curOption.series;
var curData;
for (var i = 0, l = curSeries.length; i < l; i++) {
curData = curSeries[i].data || curSeries[i].eventList;
if (target[i]) {
// dataZoom接管的
start = Math.floor(this._zoom.start / 100 * target[i].length);
}
else {
// 非dataZoom接管
start = 0;
}
for (var j = 0, k = curData.length; j < k; j++) {
//optionBackup.series[i].data[j + start] = curData[j];
if (target[i]) {
// 同步内部备份
target[i][j + start] = curData[j];
}
}
}
},
syncOption : function(magicOption) {
this.silence(true);
this.option = magicOption;
this.option.dataZoom = this.reformOption(this.option.dataZoom);
this.zoomOption = this.option.dataZoom;
if (!this.myChart.canvasSupported) {
// 不支持Canvas的强制关闭实时动画
this.zoomOption.realtime = false;
}
this.clear();
// 位置参数,通过计算所得x, y, width, height
this._location = this._getLocation();
// 缩放参数
this._zoom = this._getZoom();
this._backupData();
if (this.option.dataZoom && this.option.dataZoom.show) {
this._buildShape();
}
this._syncData();
this.silence(false);
},
silence : function (s) {
this._isSilence = s;
},
getRealDataIndex : function (sIdx, dIdx) {
if (!this._originalData || (this._zoom.start === 0 && this._zoom.end == 100)) {
return dIdx;
}
var sreies = this._originalData.series;
if (sreies[sIdx]) {
return Math.floor(this._zoom.start / 100 * sreies[sIdx].length) + dIdx;
}
return -1;
},
/**
* 避免dataZoom带来两次refresh,不设refresh接口,resize重复一下buildshape逻辑
*/
resize : function () {
this.clear();
// 位置参数,通过计算所得x, y, width, height
this._location = this._getLocation();
// 缩放参数
this._zoom = this._getZoom();
if (this.option.dataZoom.show) {
this._buildShape();
}
}
};
zrUtil.inherits(DataZoom, Base);
require('../component').define('dataZoom', DataZoom);
return DataZoom;
});