注意这是封装的组件,引用时需要给一个有宽高的容器盒子,导入引用即可
<template>
<!-- 多Y轴折线图 -->
<div ref="line" class="line"></div>
</template>
<script>
import * as echarts from 'echarts'
import { onMounted, reactive, toRefs, ref, watch } from 'vue'
export default {
props: {
airlist: {
type: Array,
default: () => {
return [{ name: '11', val: [0, 0, 0] }]
}
},
xdata: {
type: Array,
default: () => {
return [0, 0, 0, 0]
}
},
type: {
type: String,
default: () => ''
},
grid: { top: '22% ', left: '5%', right: '5%', height: '70%', bottom: '0' }
},
setup(props) {
let line = ref('')
let n = ref(2)
let setorder = v => {
let value
if (v <= 1) {
value = 3
}
if (v > 1 && v % 2 == 0) {
value = 3 + 45 * (v - v / 2)
}
if (v > 1 && v % 2 != 0) {
value = 3 + 45 * (v - n.value)
n.value += 1
}
return -value
}
const state = reactive({
yAxis: [],
series: []
})
const methods = {
drawLine() {
props.airlist.forEach((item, index) => {
// 数据
state.series.push({
name: item ? item.name : 'ug/m3',
type: 'line',
smooth: true,
yAxisIndex: index,
symbol: 'none',
symbolSize: 6,
data: item ? item.val : null,
unit: item && item.unit ? item.unit : ''
// markArea:(item.name=='TSP'||item.name=='颗粒物浓度')&&{
// data:[
// [
// { xAxis: '2023-10-28 01:00:00' },
// { xAxis: '2023-10-28 05:00:00' }
// ]
// ],
// itemStyle:{
// color:'rgba(233,205,203,.4)'
// }
// },
// markLine:(item.name=='TSP'||item.name=='颗粒物浓度')&& {//图表标线
// symbol: ['none', 'none'],
// data: [{
// label: {
// position: 'middle', // 表现内容展示的位置
// formatter: 'TSP高值检测线', // 标线展示的内容
// color: '#fff',
// textStyle:{
// fontSize:18
// },
// zIndex: 10, // 展示内容颜色
// },
// yAxis: 1700,
// lineStyle: {
// color: '#f00',
// width: '2'
// },
// textStyle:{
// color: '#f00',
// }
// }],//type: 'average', 平均值, min最小值, max 最大值, median中位数
// }
})
state.yAxis.push({
name: item.name == 'TSP' ? 'ug/m3' : props.airlist[index].unit?`${props.airlist[index].unit}`:"" ,
type: 'value',
scale: true,
// name: item.name,
show: false,
position: index % 2 === 0 ? 'left' : 'right',
offset: setorder(index),
axisLine: {
show: item.name == 'TSP' || props.type == '除尘',
lineStyle: { color: '#fff' }
},
axisTick: {
show: false
},
splitLine: {
show: false
}
})
})
// console.log(state.yAxis);
if (state.yAxis.length > 1 && props.type != 2) {
state.yAxis[0].show = props.type == 2 ? true : false
state.yAxis[0].offset = props.type == 2 ? 30 : 0
state.yAxis[state.yAxis.length - 2].show = true
state.yAxis[state.yAxis.length - 2].position = 'left'
state.yAxis[state.yAxis.length - 2].offset = 0
state.yAxis[state.yAxis.length - 1].show = true
state.yAxis[state.yAxis.length - 1].position = 'right'
state.yAxis[state.yAxis.length - 1].offset = 0
} else {
if (state.yAxis[0]) {
state.yAxis[0].show = true
}
}
// 初始化
var myChart = echarts.init(line.value)
let option = {
tooltip: {
trigger: 'axis',
axisPointer: { type: 'line' },
confine: true,
formatter: params => {
let unit=''
var relVal = params[0].name
for (var i = 0, l = params.length; i < l; i++) {
for(let j=0;j<state.series.length;j++){
params[i].seriesName==state.series[j].name?unit=state.series[j].unit:''
}
relVal =
relVal +
'<br/>' +
params[i].marker +
params[i].seriesName +
' ' +
params[i].value +
' ' +
unit
}
return relVal
}
},
grid: {
right: '5%',
left: '8%'
},
legend: {
type: 'scroll',
left: 'center',
top: '3%',
width: '50%',
selected:
props.type == '2'
? {
TSP: true,
PM10: false,
PM25: false,
温度: false,
湿度: false,
空气质量指数: false
}
: {},
textStyle: {
color: '#fff',
fontSize: 18
},
icon: 'circle'
},
xAxis: [
{
type: 'category',
splitLine: {
show: false
},
axisTick: {
show: false,
lineStyle: { color: '#fff' }
},
axisLine: {
show: true,
lineStyle: { color: '#fff' }
},
data: props.xdata
}
],
yAxis: state.yAxis,
series: state.series
}
// console.log(option, 'option')
myChart.clear()
if (state.yAxis.length >= 1) {
myChart.setOption(option)
}
// 使用刚指定的配置项和数据显示图表。
window.onresize = function () {
myChart.resize()
}
myChart.on('legendselectchanged', function (params) {
//解决图例切换时y轴坐标不隐藏问题
console.log('点击了', params) //可以自己去看下打印
myChart.setOption(
props.type == '除尘' || props.airlist[0].name == 'TSP'
? {
yAxis: Object.keys(params.selected).map(item => {
return {
show: params.selected[item]
}
})
}
: {}
)
// do something
})
}
}
onMounted(() => {
setTimeout(() => {
methods.drawLine()
}, 500)
})
watch(
props.airlist,
newVal => {
if (newVal) {
state.series = []
state.yAxis = []
methods.drawLine() //调用ECharts的方法重新绘制
}
},
{
// 被侦听的内容需要是函数的写法 () => stuInfo.friend
deep: true
}
)
return {
...toRefs(state),
...methods,
line
}
}
}
</script>
<style lang="scss" scoped>
.line {
width: 100%;
height: 100%;
}
</style>