最近做电力项目中,遇到这样一个需求:
用户选择设备的属性后(多选情况,可以选择不同设备的属性),然后请求各自的数据,使用折线图的形式实现趋势展示,同时要支持暂停和开始功能;
这个需求,重点在图表数据项的不确性,可能是一组数据,也可能是多组数据,所以要对echarts进行拆分;对于开始暂停功能,就是定时器的建立与清除;
第一步:使用设计模式思想,将变化的部分和不变的部分分开,echarts中的配置项option是固定的,series中的data数据项是变化;所以先实现曲线UI样式设计;
let option = ref({
backgroundColor: '#374369',
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#ddd'
}
},
backgroundColor: 'rgba(255,255,255,1)',
padding: [5, 10],
textStyle: {
color: '#7588E4',
},
extraCssText: 'box-shadow: 0 0 5px rgba(0,0,0,0.3)'
},
legend: {
show: true,
shadowColor: "#fff",
shadowBlur: 5,
shadowOffsetX: 5,
data: [],
top: '5%',
textStyle: {
color: '#fff',
fontSize: 14
},
itemHeight: 10
},
grid: {
top: '30%',
left: '7%',
right: '8%',
bottom: '10%',
containLabel: true
},
xAxis: [{
type: 'category',
show: false,
data: (function () {
var now = new Date();
var res = [];
var len = 40; //显示个数
while (len--) {
res.unshift(now.toLocaleTimeString().replace(/^\D*/, ''));
now = new Date(now - 2000);
}
return res;
})(),
boundaryGap: false,
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#2d67a7'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
}
}],
yAxis: {
type: 'value',
splitLine: {
show: false
},
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#2d67a7'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
}
},
// 需要动态生成的部分
series: []
})
第二步:获取设备数据,进行渲染;
// 开始
function handleStart() {
option.value.series = [] // 清空series数据缓存,防止重叠
loading.value = true;
emptyStatus.value = false;
if (myChart.value) {
myChart.value.dispose();
}
// 点击开始,实现DOM创建,否则回报错,因为不是页面加载时创建
setTimeout(() => {
myChart.value = proxy.$echarts.init(compare.value);
}, 500);
dataStatus.value = true;
// 每次开始获取最新数据数据
//图表默认数组
var zhou1 = [], zhou2 = [], zhou3 = [], legends = ['总进线', '变频', '软起']
for (var i = 0; i <= 40; i++) {
zhou1[i] = 0;
zhou2[i] = 0;
zhou3[i] = 0;
}
const dataArray = []
dataArray.push(zhou1)
dataArray.push(zhou2)
dataArray.push(zhou3)
option.value.legend.data = legends
// 使用for循环创建动态系列数据 ,就是形成多个series数据项
for (var i = 0; i < dataArray.length; i++) {
option.value.series.push({
//对配置项不熟悉的可以去查看官网文档资料
name: legends[i],
type: 'line',
smooth: true,
showSymbol: false,
symbol: 'circle',
symbolSize: 1,
data: dataArray[i],
itemStyle: {
normal: getUniqueRandomColor(),
emphasis: getUniqueRandomColor()
},
lineStyle: {
width: 2,
shadowColor: 'rgba(0,0,0,0.6)',
shadowBlur: 10,
shadowOffsetY: 5
}
});
}
// 使用定时器,进行曲线实时滚动
timer.value = setInterval(function () {
//数据为模拟随机数
let electricityX = Math.random() * 100;
let electricityY = Math.random() * 10;
let electricityZ = Math.random() * 5;
zhou1.shift();
zhou1.push(electricityX);
zhou2.shift();
zhou2.push(electricityY);
zhou3.shift();
zhou3.push(electricityZ);
let axisData = (new Date()).toLocaleTimeString().replace(/^\D*/, '');
option.value.xAxis[0].data.shift();
option.value.xAxis[0].data.push(axisData);
//进行渲染
myChart.value.setOption(option.value);
}, 1000)
//强制出现加载效果(业务目的),为了用户体验,哈哈哈哈
setTimeout(() => {
loading.value = false
}, 500);
}
第三步:实现暂停效果,清除定时器;
// 暂停
function handleQuery() {
dataStatus.value = false;
clearInterval(timer.value);
}