最近由于项目需要做一个类似于甘特图的统计业务随着时间在时间轴和“空间”轴上双向变动的统计图表,搜寻了许多图片和开源组件,最后在Echart官网发现一个相似示例,下面就简要记录实现过程和介绍一下对于部分API的使用,方便需要使用的博友互相学习和自己的后续复习。
首先附上自己在官网上直接改动的示例代码,可直接复制到官网使用。
option = {
title: {
text: 'Step Line'//设置图表标题
},
tooltip: {
trigger: 'axis' //提示框的触发类型 axis坐标轴触发
},
legend: {
data:['G038'] //图例组件,用于标记不同的系列
},
grid: {
left: '3%', //图表相对于左侧的空白 等同于echarts2 中的x
right: '4%', //图表相对于右侧的空白距离,等同于echart2中的x2
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
position:'top',
type: 'value',
data:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
splitNumber:24,
max:24,
name:'时间',
nameLocation:'middle',
nameGap:30,
nameTextStyle:{
fontWeight:'bold'
}
},
yAxis: {
type: 'category',
inverse:true,
data:['L-1A','L-1B','L-2A','L-2B','L-3A','L-3B','L-4A','L-4B','L-5A',
'L-5B','L-6A','L-6B','L-7A','L-7B','L-8A','L-8B','L-9A','L-9B','L-10A',
'L-10B','L-11A','L-11B','L-12A','L-12B','L-13A','L-13B','L-14A','L-14B',
'L-15A','L-15B','L-16A','L-16B','L-17A',
'L-17B','L-18A','L-18B','-L19A','L-19B','L-20A','L-20B','L-21A','L-21B',
'L-22A','L-22B'],
name:'线路',
nameLocation:'middle',
nameGap:50,
nameTextStyle:{
fontWeight:'bold'
},
splitLine: {
show: true
}
},
visualMap: {
show: false,
dimension: 0,
pieces: [{
gt: 0,
lte: 14.2,
color: 'black'
},{
gt: 14.2,
lte: 24,
color: 'green'
}], //pieces的值由动态数据决定
outOfRange: {
color: 'green'
}
},
series: [
{
name:'G038',
type:'line',
step: 'start',
data:[[0.7,'L-1A'],[2,'L-1A'],[8,'L-2B'],[8,'L-2B'],[17,'L-6B']],
// data:[{xAxis:0.7,yAxis:'L-1A'}],
},{
name:'时间轴',
type:'line',
markLine: {
data: [{xAxis:14.2}]
}
}
]
};
先上一张运行的效果图:
好了简单效果是有了,可是还有那么多功能还没有实现,怎么办一步步来。
在Echart的API中提供了xAxis的一个可配置属性叫做xAxis.splitNumber(坐标轴的分割段数),字面意思像是可以根据此属性的具体值将坐标轴划分为改数值的端数,可是仔细阅读文档发现该值在类目轴中无效,本人测试在时间轴上同样无效,只好另辟蹊径。
注意到xAxis描述的同时,往下阅读就可以发现同时利用interval和max和min可以实现功能;xAxis.interval:强制设置坐标轴分割间隔,同时需要配合max和min才可生效(在时间轴中)。
初始化option时的X轴设置
xAxis: {
position: 'top',
type: 'time', //坐标轴类型
data: [], //数据需要以时间戳格式传入,也就是new Date().getTime()
interval: 10 * 60 * 1000, //每隔 10分钟划分一个区段
name: '时间',
nameLocation: 'middle',
nameGap: 30,
nameTextStyle: {
fontWeight: 'bold'
}
},
动态的获取X轴的数据
/**
* 返回指定日期的每小时的时间戳
* @param date 格式为yyyy-MM-dd 或者为yyyy.MM.dd
* @returns {Array} 时间戳数组 共25位(包含下一天的零点)
*/
function getHoursTimespampOfDate(date) {
var timestampArray = [];
var timestamp = new Date(Date.parse(date.replace(/-/g, "/"))).getTime();
timestampArray.push(timestamp);
//获得单个间隔的值
for (let i = 0; i < interval; i++) {
timestamp += intervalTimeValue;
timestampArray.push(timestamp);
}
return timestampArray;
}
/**
* 刷新表格X轴数据
* @param date
* @param interval 将一天分为的间隔
*/
function refreshChartxAxis(date) {
var xAxis = getHoursTimespampOfDate(date);
if (!option) {
option = getChartOption();
}
option.xAxis.data = [];
option.xAxis.data = xAxis;
option.xAxis.min = xAxis[0];
option.xAxis.max = xAxis[interval];
//刷新颜色轴的最大值和最小值
option.visualMap.pieces[0].gt = xAxis[0];
option.visualMap.pieces[1].lte = xAxis[interval];
echart.setOption(option);
}
利用series[i]的markPoint对象实现折线点标记。
//res.data.series是我后端返回的数据,需要适应修改
$.each(res.data.series, function (index, item) {
option.legend.data.push(item.vehicleNum);
option.series.push({
symbolSize: 10,//坐标点大小
name: item.vehicleNum,//名称
type: 'line',//类型 为折线形式
step: 'start', //拐点
data: item.data,//数据
markPoint: {
symbolSize: [120, 40],
data: [{
type: 'min', label: {
normal: {
show: true,
formatter: function (params) {
return "车号:" + params.seriesName;
}
}
}
}]
}
});
});
echart.setOption(option);
重点在于formatter:function(param),param是一个可配置对象,该回调函数的返回值会直接在图表的标记点位置进行显示。
在option配置对象中添加以下配置:
tooltip: {
trigger: 'item',//设置提示框的触发地点, ‘item’表示在具体的点进行触发
formatter: function (params) {
var vehicleNum = params.seriesName;
var dateTime = new Date(params.data[0]).format("yyyy-MM-dd hh:mm:ss");
var trackNum = params.data[1];
if (dateTime && trackNum) {
return "车号:" + vehicleNum + "
" + "时间:" + dateTime + "
" + "股道编码:" + trackNum;
} else {
return "车号:" + vehicleNum;
}
}
},
function refreshTimeLine(interval) {//interval 就是需要多长时间刷新的频率
if (!option || !echart)
return;
//获得最开始的时间戳
var currentTimeStamp = option.series[0].markLine.data[0].xAxis;
setInterval(function () {
currentTimeStamp += interval;
//动态更改时间轴
option.series[0] = {
name: '时间轴',
type: 'line',
markLine: {
data: [{xAxis: currentTimeStamp}],
itemStyle: {
normal: {
label: {
formatter: new Date().format("hh:mm")//自定义标线的显示形式
}
}
}
}
};
//同步更新颜色分段的值,让折线的颜色也随着时间更改
option.visualMap.pieces[0].lte = currentTimeStamp;
option.visualMap.pieces[1].gt = currentTimeStamp + 1;
echart.setOption(option);
}, interval);
}
最后上一版效果图: