Echarts横坐标时间轴,并缩放数据

avatar
作者
筋斗云
阅读量:0

本文中Echarts的版本为5.5.0

        首先说一下我们的项目背景,就是需要一个横坐标为时间轴折线型数据。折线分为数值类型和枚举类型,也就是说Y坐标为数值型或者枚举型的数据;然后数据的缩放是这样的,把请求到的数据,一次性的全部显示在折线中,并且需要支持鼠标滚轮和鼠标拖拽式,缩放查看局部的数据。效果如图所示:

        项目中的难点主要是三部分。1、查询的到的数据,比如查询的是今天的数据,但是今天的话,只有在10点和11点有数据,其他的时间没有数据;2、横坐标下面的显示的当前缩放完成之后的时间范围;3、需要线断开连接,具体的规则是,当数据中有flage:start的时候,就认为这是一个新的曲线了,需要和前面的数据断开显示;

1、正确显示数据

配置dataZoom

        针对于第一个问题,采用的是dataZoom中配置,startValue和endValue,而不是配置start和end;

    dataZoom: [       {         type: "inside",         // start: 50, // 不能使用百分比,因为搜索的时间和数据的时间不一定能对应上         // end: 100,         startValue: zoomStartValue,         endValue: zoomEndValue,         filterMode: "filter",       },     ],

        其中zoomStartValue和zoomEndValue就是第一条数据和最后一条数据的时间;例如刚刚说的上面的例子。搜索今天的全部数据,但是只有10点和11点之间是有数据。那么zoomStartvalue="2024-04-10 10:00:00",则zoomEndValue可能就是"2024-04-10 11:30:00"。这里不需要使用时间戳,直接使用字符串类型的时间就可以;但是因为搜索的是今天,所以在用户拖动的时候,应该是能拖动到今天的0点的。结束时间应该是查询的时候的时间。所以这个时候的x轴需要单独的配置;

配置xAxis

        在xAxis中,需要配置min和max两个参数,用于让x轴能滑动到今天的0点的时刻,虽然那个时间点并没有数据;

    xAxis: {       type: "time", // 这里需要明确为“time”       min: searchBeginTime,       max: searchEndTime,       axisLine: {         show: true,         lineStyle: {           color: "#C0C0C0",         }       },       axisTick: {         show: true       },       axisLabel: {         color: "#676767"       },       data: xdata, //  这里比较关键,需要传个数据,要不然直接靠server得到的数据,缩放有问题     },

        其中的min和max对应的数据,就是搜索传给后台的数据。比如我搜索的今天的数据,那么searchBeginTime应该是"2024-04-10 00:00:00",searchEndTime应该是当前的搜索的结束时间:"2024-4-10 11:49:02";

        其中还有一个问题是我在实际开发中发现的。就是xAxis中的data数据也是需要传递的。要不然直接靠server中的横坐标的数据,下面缩放以后获取到的时间就有问题了。xdata的数据,就是后台给的数据中,所有数据的时间的数组:['2024-04-10 10:00:00','2024-04-10 10:15:00',2024-04-10 10:30:00,'2024-04-10 10:45:00',……'2024-04-10 11:30:00']

2、缩放显示当前的时间区间

监听dataZoom事件

        使用on("dataZoom")的方法,来监听Echats进行了缩放,而且这里面会有对应的,当前缩放的横坐标开始的百分比,和结束的百分比;

        具体的方法如下:

  myChart.off("dataZoom");   myChart.on("dataZoom", (params) => {     var optionData = myChart.getOption();     var min = optionData.xAxis[0].min;     var max = optionData.xAxis[0].max;     var minT = new Date(min).getTime();     var maxT = new Date(max).getTime();     var len = maxT - minT;// 计算出时间的差额。使用的是时间戳计算~     var start = params.batch[0].start; // 横坐标左侧的百分比     var end = params.batch[0].end; // 横坐标右侧的百分比     var startIndex = Math.round((len * start) / 100);     var endIndex = Math.round((len * end) / 100);     var xTextContent = `${moment(minT + startIndex).format("YYYY-MM-DD HH:mm:ss")} -- ${moment(minT + endIndex).format("YYYY-MM-DD HH:mm:ss")}`; // 使用moment插件,格式化成具体的时间     xText.value = xTextContent;   });

其中,start和end就是Echats缩放之后,获取的开始百分比和结束百分比;start的最小值为0,end的最大值为100。然后根据横坐标的min和max获取到整体的时间戳。然后计算出来差额,再根据百分比就能获取到当前的横坐标显示的时间了。

3、断开曲线

        项目中需要把数据中,含有flags:true的,就认为是一个新的曲线。当时我们想到的断开方法是给一个数据,只传时间,然后对应的值传空,这样就能断开了。但是由于我们的数据横坐标对应都是有值的。上面的方法就不可用了。所以我们采用的了第二种方法,就是在Echats中绘制了两条曲线,这两条曲线互不干扰。

        首先说一下,我们的数据:

var chartRowData = [{   timestamp: "2024-4-10 11:20:00",   value: 12,   status: "null",   flags: true, },{   timestamp: "2024-4-10 11:21:00",   value: 19,   status: "ok", },{   timestamp: "2024-4-10 11:22:00",   value: 20,   status: "alarm", },{   timestamp: "2024-4-10 11:23:00",   value: 22,   status: "ok", },{   timestamp: "2024-4-10 11:24:00",   value: 8,   status: "ok",   flags: true, },{   timestamp: "2024-4-10 11:25:00",   value: 15,   status: "ok", },{   timestamp: "2024-4-10 11:26:00",   value: 12,   status: "ok", },{   timestamp: "2024-4-10 11:27:00",   value: 14,   status: "ok", }]

        所以我采用下面的方法整理数据

var xdata = [], seriesData = [], seriesArr=[]; // 横坐标;一段横线的小数组;全部数据的数组   var chartRowDataLength = chartRowData.length;   chartRowData.forEach((item, i) => {     xdata.push(item.timestamp);     // 如果是flags的值为start的话,就重新添加一条线     if(item.hasOwnProperty("flags") && item.flags == "start" && seriesData.length) {       seriesArr.push({         name: historyName,         data: seriesData.slice(0),         type: "line",         smooth: true,         showSymbol: false,         emphasis: { // 关闭鼠标高亮           disabled: true         }       })       seriesData.splice(0);     }     seriesData.push([item.timestamp, item.value, item.status]);     if (i == 0) {       zoomStartValue = item.timestamp;     }     if (i == chartRowDataLength - 1) {       zoomEndValue = item.timestamp;       // 数据最后一条,也要添加到大数组中。       seriesArr.push({         name: historyName,         data: seriesData.slice(0),         type: "line",         smooth: true,         showSymbol: false,         emphasis: { // 关闭鼠标高亮           disabled: true         }       })     }   })

4、其他的小问题

设置语言

        做完了发现时间显示的有问题。就是不是按照咱们写的年月日时分秒显示的。所以需要在初始化Echats的时候,指定一下语言;

var chartDom = document.getElementById("chartDom"); myChart = echarts.init(chartDom, null, { locale: "ZH" });

一天中仅有一条数据

        测试提出,如果查询今天只有一条数据的话,就会发现,缩放有问题;经过查询代码发现,是因为zoomStartValue和zoomEndValue相等,导致了出现了横坐标显示的不是今天的数据。所以有了以下的一个判断:

    // 如果之有一个数据的话,zoomStartValue和zoomEndValue的值是一样的。这样Echarts的zoom就有问题了~     // 所以需要单独处理一下     if(chartRowData.length == 1) {        zoomStartValue = searchBeginTime;       zoomEndValue = searchEndTime;     }

        如有需要,可以查看资源。里面的代码可以直接运行,因为没有请求,所以里面很多内容都是直接写死的。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!