VUE3,多Y轴折线图,柱状图,动态传参

2023-12-25 14:05:38

注意这是封装的组件,引用时需要给一个有宽高的容器盒子,导入引用即可

<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 +
                  '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;' +
                  params[i].value +
                  '&nbsp;' +
                  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>

文章来源:https://blog.csdn.net/xu20166424/article/details/135193925
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。