需求背景:
此次需求是要做个图表交互,y轴表示评分等级是一个非连续性的值,范围用背景颜色做等级区分;x轴是以四个小时为间隔的固定刻度,如00:00 4:00·····,零点时刻用日期代替(如01-09);折线数据点是评分次数,点击数据点会将评分结果、评分时间还有评分项给显示出来。
拆解需求
趋势图+评分结果展示
趋势图可以用散点图也可以用折线图,也可以用canvas去画,我当时可能是觉得折线图比较熟悉就采用了折线图
echarts固定x轴且以天为维度的日期(也可以小时、分钟、秒为维度),对应的日期时间画折线图
vue3使用echarts
<script setup>
import * as echarts from 'echarts'
</script>
趋势图y轴实现
普通echarts折线图:
我们先给y轴自定义范围,做到等级划分: 1-3 5-7 9-14····这样的
其实也是利用了echarts的markArea去制作背景图,y轴的坐标轴刻度通过option.yAxis.axisLabel.formatter方法定义坐标轴刻度标签的展示形式,如果index里有包含指定的刻度值,那就值显示那几个
效果图:
option = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value',
interval: 1,
splitLine:{show: false},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel:{
formatter: function (value, index){
if([0,1,4, 5, 7, 8, 14].includes(index)){
return value
}
return ''
}
}
},
series: [
{
data: [2, 7, 4, 10, 13, 6],
type: 'line',
markArea:{
data: [[{
yAxis: '0',
itemStyle: {
color: '#fff',
},
},{
yAxis: '0'
}],[{ yAxis: '1', itemStyle: { color: 'green' }, },{ yAxis: '4' }],[{ yAxis: '5', itemStyle: { color: 'yellow' }, },{ yAxis: '7' }],[{ yAxis: '8', itemStyle: { color: 'red' }, },{ yAxis: 14 }]],
},
},
]
};
趋势图x轴实现
x轴是后端给我传数据记录的起始时间然后去解析成固定刻度,遇到0点就转为当天开始的日期
主要思路:
先把字符串时间转成时间戳再转成时间
设置type的类别为time
interval属性固定x轴时间间隔,间隔时间自己设定 min属性设置开始时间戳,max属性设置结束时间时间戳
x轴的坐标轴刻度通过option.xAxis.axisLabel.formatter方法定义坐标轴刻度标签的展示形式
效果图:
var option = {
title: {
text: "固定横轴坐标,包含时分秒刻度,根据数据展示对应图",
subtext: "评分点数",
},
tooltip: {
trigger: "axis",
// 鼠标上移x轴、y轴刻度展示
// axisPointer: {
// type: "cross",
// },
},
toolbox: {
show: true,
feature: {
saveAsImage: {},
},
},
formatter: function(params) {
// console.log(params);
var temp = "";
temp = params[0].data[0] + "<br/>" + "评分点数:" + params[0].data[1];
return temp;
},
dataZoom: [
{
type: 'inside', //1平移 缩放
throttle: '50', //设置触发视图刷新的频率。单位为毫秒(ms)。
minValueSpan: 6, //用于限制窗口大小的最小值,在类目轴上可以设置为 5 表示 5 个类目
start: 1, //数据窗口范围的起始百分比 范围是:0 ~ 100。表示 0% ~ 100%。
end: 50, //数据窗口范围的结束百分比。范围是:0 ~ 100。
zoomLock: true, //如果设置为 true 则锁定选择区域的大小,也就是说,只能平移,不能缩放。
},
],
xAxis: {
type: "time",
min: new Date('2022-04-25 00:00:00').getTime(), //默认值
max: new Date('2022-04-30 00:00:00').getTime(), //默认值
interval: 4*60*60*1000,
axisLabel: {
show: true,
showMinLabel: true,
showMaxLabel: true,
formatter: function (value, index) {
if (new Date(value).toString().includes('00:00:00')) {
let month = new Date(value).getMonth() + 1;
let date = new Date(value).getDate();
month = month >= 10 ? month : '0' + month;
date = date >= 10 ? date : "0" + date;
return month + '-' + date
} else {
let hour = new Date(value).getHours();
let minute = new Date(value).getMinutes();
let second = new Date(value).getSeconds();
hour = hour >= 10 ? hour : "0" + hour;
minute = minute >= 10 ? minute : "0" + minute;
return hour + ":" + minute;
}
return ''
}
}
},
yAxis: {
type: "value",
axisLabel: {
formatter: "{value} W",
},
axisPointer: {
snap: true,
},
interval: 1,
splitLine:{show: false},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
axisLabel:{
formatter: function (value, index){
if([0,1,5,7,20].includes(index)){
return value
}
return ''
}
}
},
visualMap: {
show: false,
dimension: 0,
},
series: [
{
name: "Electricity",
type: "line",
// smooth: true,
type: 'scatter',
symbol: "circle",
symbolSize: 10,
lineStyle: {
color: "#fff"
},
// data的格式 [[实际日期:数值],[[实际日期:数值]]]
// 不需要属性名
data:[
["2022-04-28 2:12:58", "3"],
["2022-04-28 6:20:13", "7"],
["2022-04-29 23:12:58", "4"],
["2022-04-29 20:2:13", "10"],
["2022-04-30 12:00:00", "11"],
["2022-05-01", "6"],
["2022-05-02", "8"],
["2022-05-03", "2"],
["2022-05-04", "13"]
],
markArea:{
data: [[{
yAxis: '0',
itemStyle: {
color: '#fff',
},
},{
yAxis: '0'
}],[{
yAxis: '1.7',
itemStyle: {
color: 'green'
},
},{
yAxis: '5'
}],[{
yAxis: '5.7',
itemStyle: {
color: 'yellow'
},
},{
yAxis: '7'
}],[{
yAxis: '7.7',
itemStyle: {
color: 'red'
},
},{
yAxis: 14
}]],
},
},
{
}
]
};