admin管理员组

文章数量:821322

基于Echart实现的梯形折线图

 

最近由于项目需要做一个类似于甘特图的统计业务随着时间在时间轴和“空间”轴上双向变动的统计图表,搜寻了许多图片和开源组件,最后在Echart官网发现一个相似示例,下面就简要记录实现过程和介绍一下对于部分API的使用,方便需要使用的博友互相学习和自己的后续复习。

首先附上自己在官网上直接改动的示例代码,可直接复制到官网使用。

option = {title: {text: 'Step Line'//设置图表标题},tooltip: {trigger: 'axis' //提示框的触发类型 axis坐标轴触发},legend: {data:['G038']  //图例组件,用于标记不同的系列},grid: {left: '3%',   //图表相对于左侧的空白  等同于echarts2 中的xright: '4%',  //图表相对于右侧的空白距离,等同于echart2中的x2bottom: '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}]}}]
};

先上一张运行的效果图:

好了简单效果是有了,可是还有那么多功能还没有实现,怎么办一步步来。

X轴划分为指定的区间长度和区间个数

在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是一个可配置对象,该回调函数的返回值会直接在图表的标记点位置进行显示。

利用Echart提示框(tooltip)自定义提示内容

在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 + "<br>" + "时间:" + dateTime + "<br>" + "股道编码:" + trackNum;} else {return "车号:" + vehicleNum;}}},

利用markline+setInterval函数实现基于时间移动的时间标线

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);}

最后上一版效果图:

 

本文标签: 基于Echart实现的梯形折线图