最近项目要求做一个有上下限范围的折线图(基线图)类似这种
翻了翻Echarts官网,只有这种最接近:
但是这种用来达到展示效果是可以的,但是里面的数据渲染,数据结构不好理解(可能我急于求成,没好好理解)所以我换了种写法,最终达到以下可控的效果:
以上为我模拟测试用的数据,无实际应用。
Vue3内全部代码如下(未精简,如有写的不好的地方请自改,仅供参考与提供思路):
异常点请参考ECharts官网的散点图
需要注意的是响应式数据内 dealTop 为上限实际渲染的数据,因为上限的数据会在原本的数据上自动加上下限的数据,例如 11-01 内的下限数据为 43,如果上限渲染的数据如果为 183,那么在图内实际展示的上限范围为 183 + 43 = 226,因此需要将上限的数据减去下限的数据,然后再拿来渲染上限的折线。也就是183-43 = 140,然后拿去渲染达到实际要展示的上限183,但是鼠标悬浮的时候该处数据显示仍为140(可以自定义去改,我没这个需求,后面对接口会将上下限的悬浮提示去掉),如图:
<template>
<div id="box" style="width: 100%; height: 500px"></div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts';
import { onMounted, reactive } from 'vue';
const state = reactive({
//x轴日期数据
dateArray: [],
chartData:{
//上限数据
top: [183, 145, 176, 115, 128, 199, 154, 167, 139, 191, 178, 161, 135, 111, 172, 147,
219, 163, 150, 188],
//上限减下限处理后的数据
dealTop:[],
//下限数据
bottom: [43, 75, 76, 25, 48, 99, 64, 87, 79, 91, 48, 71, 65, 61, 82, 47, 99, 93, 70,
88],
//中间蓝色线实际数据
line: [93, 85, 46, 75, 88, 119, 124, 127, 129, 101, 128, 131, 95, 101, 112, 127, 129,
153, 80, 98]
}
});
onMounted(() => {
//该处为函数赋予日期数据,不需要可自删
var startDate = new Date(2023, 10, 1);
var endDate = new Date(2023, 11, 30);
var dateArray = [];
for (var date = new Date(startDate); date <= endDate; date.setDate(date.getDate() + 1)) {
var formattedDate =
(date.getMonth() + 1).toString().padStart(2, '0') +
'-' +
date.getDate().toString().padStart(2, '0');
dateArray.push(formattedDate);
}
state.dateArray = dateArray;
chart();
});
function chart() {
state.chartData.top.forEach((item,index) => {
state.chartData.bottom.forEach((i,j) => {
if (index === j) {
state.chartData.dealTop.push( item - i);
}
});
})
var chartDom = document.getElementById('box');
var myChart = echarts.init(chartDom);
var options;
myChart.setOption(
(options = {
legend: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
animation: false,
label: {
backgroundColor: '#ccc',
borderColor: '#aaa',
borderWidth: 1,
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 0,
color: '#222',
},
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: state.dateArray,
},
yAxis: [
{
type: 'value',
},
],
series: [
{
name: '流量时序',
type: 'line',
showSymbol: false,
color: '#839ECB',
data: state.chartData.line,
},
{
name: '下限',
type: 'line',
color: '#CBCDCC',
lineStyle: {
opacity: 0,
},
symbol: "none",
stack: 'lb', // 两根线这个字段值设置就会叠加
data: state.chartData.bottom,
},
{
name: '上限',
type: 'line',
color: '#CBCDCC',
lineStyle: {
opacity: 0,
},
symbol: "none",
areaStyle: {
color: '#EBF2FC',
},
emphasis: {
areaStyle: {
color: '#EBF2FC'
}
},
stack: 'lb',
data: state.chartData.dealTop,
},
{
// 系列名称,用于tooltip显示,legend图例筛选
name: '异常点',
symbolSize: 15,
// 图表类型
color: 'red',
type: 'scatter',
// 数据内容
data: [[2, 46]],
},
],
}),
);
}
</script>
再次声明,代码写的随意,并非专业大佬,只为大家提供参考思路,可拿去自改优化~