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

303 lines
11 KiB

/**
* echarts图表类:事件河流图
*
* @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。
* @author clmtulip (车丽美, clmtulip@gmail.com)
*
*/
define(function (require) {
var ChartBase = require('./base');
var eventRiverLayout = require('../layout/eventRiver');
// 图形依赖
var PolygonShape = require('zrender/shape/Polygon');
// 组件依赖
require('../component/axis');
require('../component/grid');
require('../component/dataZoom');
var ecConfig = require('../config');
// 事件河流图默认参数
ecConfig.eventRiver = {
zlevel: 0, // 一级层叠
z: 2, // 二级层叠
clickable: true,
legendHoverLink: true,
itemStyle: {
normal: {
// color: 各异,
borderColor: 'rgba(0,0,0,0)',
borderWidth: 1,
label: {
show: true,
position: 'inside', // 可选为'left'|'right'|'top'|'bottom'
formatter: '{b}'
// textStyle: null // 默认使用全局文本样式,详见TEXTSTYLE
}
},
emphasis: {
// color: 各异,
borderColor: 'rgba(0,0,0,0)',
borderWidth: 1,
label: {
show: true
}
}
}
};
var ecData = require('../util/ecData');
var ecDate = require('../util/date');
var zrUtil = require('zrender/tool/util');
var zrColor = require('zrender/tool/color');
/**
* 构造函数
* @param {Object} messageCenter echart消息中心
* @param {ZRender} zr zrender实例
* @param {Object} option 数据
* @param {Object} component 组件
*/
function EventRiver(ecTheme, messageCenter, zr, option, myChart) {
// 图表基类
ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart);
var self = this;
self._ondragend = function () {
self.isDragend = true;
};
this.refresh(option);
}
EventRiver.prototype = {
type: ecConfig.CHART_TYPE_EVENTRIVER,
_buildShape: function() {
var series = this.series;
this.selectedMap = {};
// 数据预处理
this._dataPreprocessing();
var legend = this.component.legend;
// 调用布局算法计算事件在Y轴上的位置
var eventRiverSeries = [];
for (var i = 0; i < series.length; i++) {
if (series[i].type === this.type) {
series[i] = this.reformOption(series[i]);
this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink;
var serieName = series[i].name || '';
// 系列图例开关
this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true;
if (!this.selectedMap[serieName]) {
continue;
}
this.buildMark(i);
eventRiverSeries.push(this.series[i]);
}
}
eventRiverLayout(
eventRiverSeries,
this._intervalX,
this.component.grid.getArea()
);
// 绘制事件河
this._drawEventRiver();
this.addShapeList();
},
/**
* 处理数据
*/
_dataPreprocessing: function() {
// 将年月日的时间转化为平面坐标
var series = this.series;
var xAxis;
var evolutionList;
for (var i = 0, iLen = series.length; i < iLen; i++) {
if (series[i].type === this.type) {
xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex || 0);
for (var j = 0, jLen = series[i].data.length; j < jLen; j++) {
evolutionList = series[i].data[j].evolution;
for (var k = 0, kLen = evolutionList.length; k < kLen; k++) {
evolutionList[k].timeScale = xAxis.getCoord(
ecDate.getNewDate(evolutionList[k].time) - 0
);
// evolutionList[k].valueScale = evolutionList[k].value;
// modified by limei.che, to normalize the value range
evolutionList[k].valueScale = Math.pow(evolutionList[k].value, 0.8);
}
}
}
}
// 尾迹长度
this._intervalX = Math.round(this.component.grid.getWidth() / 40);
},
/**
* 绘制事件河流
*/
_drawEventRiver: function(){
var series = this.series;
for (var i = 0; i < series.length; i++) {
var serieName = series[i].name || '';
if (series[i].type === this.type && this.selectedMap[serieName]) {
for (var j = 0; j < series[i].data.length; j++) {
this._drawEventBubble(series[i].data[j], i, j);
}
}
}
},
/**
* 绘制气泡图
*/
_drawEventBubble: function(oneEvent, seriesIndex, dataIndex) {
var series = this.series;
var serie = series[seriesIndex];
var serieName = serie.name || '';
var data = serie.data[dataIndex];
var queryTarget = [data, serie];
var legend = this.component.legend;
var defaultColor = legend ? legend.getColor(serieName) : this.zr.getColor(seriesIndex);
// 多级控制
var normal = this.deepMerge(queryTarget, 'itemStyle.normal') || {};
var emphasis = this.deepMerge(queryTarget, 'itemStyle.emphasis') || {};
var normalColor = this.getItemStyleColor(normal.color, seriesIndex, dataIndex, data)
|| defaultColor;
var emphasisColor = this.getItemStyleColor(
emphasis.color, seriesIndex, dataIndex, data
)
|| (typeof normalColor === 'string'
? zrColor.lift(normalColor, -0.2)
: normalColor
);
var pts = this._calculateControlPoints(oneEvent);
var eventBubbleShape = {
zlevel: this.getZlevelBase(),
z: this.getZBase(),
clickable: this.deepQuery(queryTarget, 'clickable'),
style: {
pointList: pts,
smooth: 'spline',
brushType: 'both',
lineJoin : 'round',
color: normalColor,
lineWidth: normal.borderWidth,
strokeColor: normal.borderColor
},
highlightStyle:{
color: emphasisColor,
lineWidth: emphasis.borderWidth,
strokeColor: emphasis.borderColor
},
draggable: 'vertical',
ondragend : this._ondragend
};
eventBubbleShape = new PolygonShape(eventBubbleShape);
this.addLabel(eventBubbleShape, serie, data, oneEvent.name);
ecData.pack(
eventBubbleShape,
series[seriesIndex], seriesIndex,
series[seriesIndex].data[dataIndex], dataIndex,
series[seriesIndex].data[dataIndex].name
);
this.shapeList.push(eventBubbleShape);
},
/**
* 根据时间-热度,计算气泡形状的控制点
*/
_calculateControlPoints: function(oneEvent) {
var intervalX = this._intervalX;
var posY = oneEvent.y;
var evolution = oneEvent.evolution;
var n = evolution.length;
if (n < 1) {
return;
}
var time = [];
var value = [];
for (var i = 0; i < n; i++) {
time.push(evolution[i].timeScale);
value.push(evolution[i].valueScale);
}
var pts = [];
// 从左向右绘制气泡的上半部分控制点
// 第一个矩形的左端点
pts.push([time[0], posY]);
// 从一个矩形 到 倒数第二个矩形 上半部分的中点
var i = 0;
for (i = 0; i < n - 1; i++) {
pts.push([(time[i] + time[i + 1]) / 2.0, value[i] / -2.0 + posY]);
}
// 最后一个矩形上半部分的中点
pts.push([(time[i] + (time[i] + intervalX)) / 2.0, value[i] / -2.0 + posY]);
// 最后一个矩形的右端点
pts.push([time[i] + intervalX, posY]);
// 从右向左绘制气泡的下半部分控制点
// 最后一个矩形下半部分的中点
pts.push([(time[i] + (time[i] + intervalX)) / 2.0, value[i] / 2.0 + posY]);
// 从倒数第二个矩形 到 一个矩形 下半部分的中点,由于polygon是闭合的,故不需要再加入左端点
for (i = n - 1; i > 0; i--) {
pts.push([(time[i] + time[i - 1]) / 2.0, value[i - 1] / 2.0 + posY]);
}
return pts;
},
/**
* 数据项被拖拽出去
*/
ondragend : function (param, status) {
if (!this.isDragend || !param.target) {
// 没有在当前实例上发生拖拽行为则直接返回
return;
}
// 别status = {}赋值啊!!
status.dragOut = true;
status.dragIn = true;
status.needRefresh = false; // 会有消息触发fresh,不用再刷一遍
// 处理完拖拽事件后复位
this.isDragend = false;
},
/**
* 刷新
*/
refresh: function(newOption) {
if (newOption) {
this.option = newOption;
this.series = newOption.series;
}
this.backupShapeList();
this._buildShape();
}
};
zrUtil.inherits(EventRiver, ChartBase);
// 图表注册
require('../chart').define('eventRiver', EventRiver);
return EventRiver;
});