文章目录
- 需求
- 分析
需求
如下图数据格式所示,现要求按照该格式进行绘制折线图
分析
在绘制折线图时,通常我们的 series 中的 data 数据是这样的格式
option = {
title: {
text: 'Stacked Area Chart'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Email',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Video Ads',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: 'Direct',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: 'Search Engine',
type: 'line',
stack: 'Total',
label: {
show: true,
position: 'top'
},
areaStyle: {},
emphasis: {
focus: 'series'
},
data: [820, 932, 901, 934, 1290, 1330, 1320]
}
]
};
但是给定的格式是如下的这种,我们就需要进行一些变换
-
首先是 Y 轴的格式需要改变,之前是value,但value会导致数据变为这种情况
因此需要将Y轴格式改为如下,效果就出来了
-
X 轴需要变换
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
- series 中 data 的数据需要变换
series: [{
data: [
// xAxis yAxis
[ 0, 0, 2 ], // 意思是此点位于 xAxis: '星期一', yAxis: 'a'。
[ '星期四', 2, 1 ], // 意思是此点位于 xAxis: '星期四', yAxis: 'm'。
[ 2, 'p', 2 ], // 意思是此点位于 xAxis: '星期三', yAxis: 'p'。
[ 3, 3, 5 ]
]
}]
格式处理如下:
for (let index = 0; index < res.series.length; index++) {
const item = res.series[index];
const obj = {
name: item.name,
type: 'line',
data: item.data,
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
}
option.value.series.push(obj)
}
option.value.xAxis.data = res.xAxisData
- 源码
<template>
<div ref="echartsRef" class="content"> </div>
</template>
<script lang="ts" setup>
import {
ref,
reactive,
watch,
watchEffect,
toRefs,
defineProps,
onMounted,
} from 'vue';
import * as echarts from 'echarts';
import { getInfoAQJCApi } from '@/api/dashboard'
/**
* @description : 安全监测模块
* @author : 'Hukang'
* @param : ''
* @date : 2024-03-05 14:59:56
*/
const props = defineProps({
//子组件接收父组件传递过来的值
InfoAQJ: Object,
})
//使用父组件传递过来的值
const { InfoAQJ } = toRefs(props)
const echartsData = reactive({
option: {
title: {
text: ''
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: [],
right: "5%",
top: "5%",
textStyle: {
fontSize: 12, //字体大小
color: "#ffffff" //字体颜色
}
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: "category",
boundaryGap: false,
data: [],
axisLine: {
lineStyle: {
color: "rgba(255, 255, 255, 0.20)"
}
},
axisTick: {
show: false
},
nameTextStyle: {
color: "#ffffff",
fontSize: 12
},
axisLabel: {
textStyle: {
color: "#ffffff",
fontSize: 12
},
formatter: (value, index) => {
return value
.replace(/(\d{4})-(\d{1,2})-(\d{1,2}).*/, "$1-$2-$3")
.slice(5);
}
}
},
yAxis: [
{
name: '',
type: "value",
axisTick: {
show: false
},
nameTextStyle: {
color: "#ffffff",
fontSize: 12
},
axisLine: {
show: false,
lineStyle: {
color: "#ffffff"
}
},
axisLabel: {
textStyle: {
color: "#ffffff",
fontSize: 12
}
},
splitLine: {
lineStyle: {
type: "dashed", //虚线
color: "rgba(255,255,255,0.2)"
},
show: true //隐藏
},
min(v) {
return v.min
}
}
],
series: []
}
});
const { option } = toRefs(echartsData);
const echartsRef = ref<string>();
let echartInstance;
let series = [];
function getAreaStyle(index) {
let areaStyle = null;
if (index == 0) {
areaStyle = {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#FDBD35"
},
{
offset: 0.8,
color: "rgba(253, 189, 53, 0.1)"
}
])
};
} else if (index == 1) {
areaStyle = {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#32D7FF"
},
{
offset: 0.8,
color: "rgba(0,254,243,0.1)"
}
])
};
} else {
areaStyle = {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#20D661"
},
{
offset: 0.8,
color: "rgba(32,214,97,0.06)"
}
])
};
}
return areaStyle;
}
watchEffect(() => {
if (InfoAQJ.value) {
const res = InfoAQJ.value
option.value.legend.data = res.legend
option.value.yAxis[0].name = res.yMain[0]
option.value.xAxis.data = res.xAxisData
res.series.forEach((item, index) => {
let obj = {
name: item.name,
type: "line",
data: item.data,
smooth: true,
areaStyle: getAreaStyle(index)
};
series.push(obj);
option.value.series.push(obj)
});
}
})
onMounted(() => {
echartInstance = echarts.init(echartsRef.value, 'macarons');
echartInstance.setOption(option.value);
});
</script>
<style scoped lang="less">
@import '@/assets/style/leftright.less';
.content {
width: 100%;
height: 100%;
}
</style>