lineChart.vue 5.64 KB
<template>
  <div class="chart" :id="id"></div>
</template>

<script>
import 'echarts/lib/component/dataZoom'
export default {
  name: "lineChart",
  props: {
    id: String,
    params: Array,
    xAxis: Array,
    colors: Array,
    formatterYAxis: true,
    tooltipFormatter: false
  },
  watch: {
    params: {
      handler: function (val) {
        if (val.length) {
          this.initData();
        }
        console.log(val)
      },
      deep: true,
    },
  },
  data() {
    return {
      chart: null,
    };
  },
  created() { },
  mounted() {
    this.initData();
  },
  methods: {
    extension(chart) {
      // 注意这里,是以X轴显示内容过长为例,如果是y轴的话,需要把params.componentType == 'xAxis'改为yAxis
      // 判断是否创建过div框,如果创建过就不再创建了
      // 该div用来盛放文本显示内容的,方便对其悬浮位置进行处理
      var elementDiv = document.getElementById('extension')
      if (!elementDiv) {
        var div = document.createElement('div')
        div.setAttribute('id', 'extension')
        div.style.display = 'block'
        document.querySelector('html').appendChild(div)
      }
      chart.on('mouseover', function (params) {
        if (params.componentType == 'xAxis') {
          var elementDiv = document.querySelector('#extension')
          //设置悬浮文本的位置以及样式
          var elementStyle =
            'position: absolute;z-index: 99999;color: #fff;padding: 5px;display: inline;border-radius: 4px;background-color: #303133;box-shadow: rgba(0, 0, 0, 0.3) 2px 2px 8px'
          elementDiv.style.cssText = elementStyle
          elementDiv.innerHTML = params.value
          document.querySelector('html').onmousemove = function (event) {
            var elementDiv = document.querySelector('#extension')
            var xx = event.pageX - 10
            var yy = event.pageY + 15
            elementDiv.style.top = yy + 'px'
            elementDiv.style.left = xx + 'px'
          }
        }
      })
      chart.on('mouseout', function (params) {
        //注意这里,我是以X轴显示内容过长为例,如果是y轴的话,需要改为yAxis
        if (params.componentType == 'xAxis') {
          var elementDiv = document.querySelector('#extension')

          elementDiv.style.cssText = 'display:none'
        }
      })
    },
    setOption() {
      const that = this;
      const options = {
        color: this.colors || ["#9772ff", "#79cd91", "#72b8ff"],
        backgroundColor: "#fff",
        tooltip: {
          trigger: "item",
          confine: true,
          formatter(v) {
            let html = `<p>${v.seriesName}</p>`
            html += `${v.marker} ${v.name}:${Number(v.value)}${that.tooltipFormatter ? '%' : ''}`
            return html
          },
        },
        dataZoom: [{
          type: 'slider',//给x轴设置滚动条
          show: true, //flase直接隐藏图形
          xAxisIndex: [0],
          bottom: 0,
          height: 20,
          showDetail: false,
          startValue: 0,//滚动条的起始位置
          endValue: 9 //滚动条的截止位置(按比例分割你的柱状图x轴长度)
        },
        {
          type: 'inside',//设置鼠标滚轮缩放
          show: true,
          xAxisIndex: [0],
          startValue: 0,
          endValue: 9
        }],
        legend: {
          show: true,
          top: 0,
          right: 20,
          itemHeight: 15,
          icon: "circle"
        },
        grid: {
          top: '3%',
          right: '3%',
          bottom: '3%',
          left: '0%',
          // 包含文本
          containLabel: true,
          // 是否显示网格线
          show: true,
          // 边框颜色
          borderColor: 'rgba(0, 240, 255, 0.3)',
        },
        xAxis: {
          type: "category",
          data: this.xAxis,
          axisLine: { show: true, lineStyle: { color: "#e2e2e2" } },
          axisTick: {
            alignWithLabel: false,
            show: false,
          },
          triggerEvent: true,
          axisLabel: {
            color: "#333",
            interval: 0,
            width: Math.ceil(600 / this.xAxis.length),
            formatter: function (value) {
              if (value.length > 3) {
                return `${value.slice(0, 3)}...`
              }
              return value
            }
          },
        },
        yAxis: {
          type: "value",
          axisLine: { show: false },
          splitLine: {
            show: true,
          },
          axisLabel: {
            color: "#666",
            formatter: function (name) {
              return that.formatterYAxis ? `${name} %` : name
            },
          },
        },
        grid: {
          top: 36,
          left: 20,
          right: 20,
          bottom: 10,
          containLabel: true,
        },
        series: that.params.map((item) => {
          return {
            name: item.name,
            type: "line",
            symbol: "circle",
            symbolSize: "6",
            lineStyle: {
              width: 1,
            },
            data: item.value,
          };
        }),
      };  
      return options;
    },
    initData() {
      if (!this.chart) {
        const div = document.getElementById(this.id);
        this.chart = this.$echarts.init(div);
      }
      const options = this.setOption();
      this.chart?.clear();
      this.chart.setOption(options, true);
      this.chart.off("click");
      this.extension(this.chart)
      this.chart.on("click", "series", (params) => {
        // this.$emit("clickPieChart", params);
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.chart {
  height: 100%;
}
</style>