业务需求
如上图所示,通过Smoothing值,重新计算data,生成新的折线图。
代码实现
<template>
<div :class="'chart-box-' + index" class="chart-box" style="width: 100%;height: 320px;" :id="'chart-box-' + index"></div>
</template>
<script>
export default {
data() {
return {
trainChart: {}
};
},
props: {
chartList: {
type: Object,
default: () => {}
},
index: {
type: Number,
default: 0
},
smooth: {
type: Number,
default: 0
}
},
watch: {
// 通过监听父组件传过来的smooth值和chartList值,刷新折线图
smooth() {
this.initChart(this.chartList);
},
chartList() {
this.initChart(this.chartList);
}
},
methods: {
smoothAlgorithm(yData) {
// 平滑算法
let smooth = this.smooth;
let smoothData = [];
for (let i = 0; i < yData.length; i++) {
if (i === 0) {
smoothData.push(yData[i][2]);
} else {
smoothData.push((smoothData[i - 1] * smooth + yData[i][2]) / (smooth + 1));
smooth = (smooth + 1) * this.smooth;
}
}
return smoothData;
},
formatRelativeTime(msTime) {
const time = msTime / 1000;
const hour = Math.floor(time / 3600) % 60;
const minute = Math.floor(time / 60) % 60;
const second = Math.floor(time) % 60;
return hour ? `${hour}h${minute}m${second}s` : minute ? `${minute}m${second}s` : `${second}s`;
},
getLocalTime(nS) {
return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, " ");
},
initChart(chartData) {
let { name, list } = chartData;
let title = name.split("/")[1];
let id = `chart-box-${this.index}`;
this.trainChart = this.$echarts.init(document.getElementById(id));
// 获取平滑数据
let smoothValueList = this.smoothAlgorithm(list);
// 将平滑数据加入到二维数组中的每一项
list.forEach((item, index) => {
if (item.length > 3) item.pop();
item.push(smoothValueList[index]);
});
let smooth = this.smooth;
let option = {
dataset: {
dimensions: ["time", "step", "baseValue", "value"]
},
grid: {
left: 60,
right: 30,
bottom: 40
},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow",
shadowStyle: {
color: "rgba(0, 0, 0, 0.1)"
}
},
backgroundColor: "rgba(0, 0, 0, 0.6)",
borderRadius: 4,
borderWidth: 0,
textStyle: { color: "#fff" },
renderMode: "html",
formatter: a => {
// console.log(a[1]);
let smoothData = a[1].data;
let value = smoothData[3] < 0.01 ? smoothData[3].toExponential(4) : smoothData[3].toFixed(4),
step = smoothData[1],
time = smoothData[0],
startTime = list[0][0],
relative = (time - startTime) * 1000;
relative = this.formatRelativeTime(relative);
time = this.getLocalTime(time);
let tipHTML = `
<div class="tooltip-box">
<div class="tip-item">
<div class="tip-label"></div>
</div>
<div class="tip-item">
<h4 class="tip-title">Smoothed</h4>
<div class="tip-con">${smooth}</div>
</div>
<div class="tip-item">
<h4 class="tip-title">Value</h4>
<p class="tip-con">${value}</p>
</div>
<div class="tip-item">
<h4 class="tip-title">Step</h4>
<p class="tip-con">${step}</p>
</div>
<div class="tip-item">
<h4 class="tip-title">Time</h4>
<p class="tip-con">${time}</p>
</div>
<div class="tip-item">
<h4 class="tip-title">Relative</h4>
<p class="tip-con">${relative}</p>
</div>
</div>`;
return tipHTML;
}
},
title: {
show: true,
text: title + "\n" + "tag: " + name,
textStyle: {
color: "#2A2A32",
fontSize: 12,
lineHeight: 15,
fontWeight: 400
},
textAlign: "left",
padding: [15, 0, 0, 23]
},
xAxis: {
type: "category",
axisLine: { lineStyle: { color: "#DDDDDD" } },
axisLabel: { color: "#666666", interval: 9 },
axisTick: {
show: false
}
},
yAxis: {
type: "value",
axisLine: { lineStyle: { color: "#DDDDDD" } },
axisLabel: {
color: "#9B9BAC",
formatter: a => {
// toExponential转为科学计数法
return a < 0.01 ? a.toExponential() : a.toFixed(3);
}
},
splitLine: {
lineStyle: { color: "#DEE0E5", type: "dashed" }
},
scale: true // Y轴依据数据,自动缩放至视图大小
},
series: [
{
name: "base",
type: "line",
symbol: "circle",
lineStyle: {
color: "#b3baff"
},
itemStyle: {
color: "#fff",
borderColor: "#b3baff",
borderWidth: 1
},
encode: {
x: "step",
y: "baseValue"
}
},
{
name: "smooth",
type: "line",
symbol: "circle",
lineStyle: {
color: "#475AFF"
},
itemStyle: {
color: "#fff",
borderColor: "#475AFF",
borderWidth: 1
},
emphasis: {
scale: true
},
encode: {
x: "step",
y: "value"
}
}
]
};
option.dataset.source = list;
option && this.trainChart.setOption(option);
}
},
mounted() {
this.initChart(this.chartList);
// console.log(this.chartList);
}
};
</script>
<style lang="scss">
.tooltip-box {
display: flex;
justify-content: space-around;
.tip-item {
padding-right: 30px;
.tip-title {
font-size: 14px;
margin-bottom: 10px;
}
.tip-label {
width: 16px;
height: 16px;
border-radius: 50%;
background-color: #4f61ff;
margin-top: 33px;
margin-left: 10px;
}
}
}
</style>