Newer
Older
ganzhou-feidu / src / components / Echart / LineChart.vue
<template>
  <div class="line-chart-container" ref="chartContainer"></div>
</template>

<script>
import echarts from 'echarts';

export default {
  name: 'LineChart',
  props: {
    // 图表数据
    chartData: {
      type: Object,
      required: true
    },
    // 图表配置
    options: {
      type: Object,
      default: () => ({})
    },
    // 图表宽度
    width: {
      type: String,
      default: '100%'
    },
    // 图表高度
    height: {
      type: String,
      default: '400px'
    }
  },
  data() {
    return {
      chart: null
    };
  },
  mounted() {
    this.initChart();
    this.resizeHandler = window.addEventListener('resize', this.resizeChart);
  },
  beforeDestroy() {
    if (this.chart) {
      this.chart.dispose();
      this.chart = null;
    }
    if (this.resizeHandler) {
      window.removeEventListener('resize', this.resizeHandler);
    }
  },
  watch: {
    chartData: {
      deep: true,
      handler() {
        this.updateChart();
      }
    },
    options: {
      deep: true,
      handler() {
        this.updateChart();
      }
    }
  },
  methods: {
    // 初始化图表
    initChart() {
      const container = this.$refs.chartContainer;
      container.style.width = this.width;
      container.style.height = this.height;

      this.chart = echarts.init(container);
      this.updateChart();
    },

    // 更新图表配置和数据
    updateChart() {
      if (!this.chart) return;

      // 合并默认配置和用户自定义配置
      const defaultOptions = {
        tooltip: {
          trigger: 'axis'
        },
        grid: {
          left: '3%',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        xAxis: {
          type: 'category',
          boundaryGap: false
        },
        yAxis: {
          type: 'value'
        },
        series: []
      };

      const mergedOptions = { ...defaultOptions, ...this.options };

      // 应用数据
      if (this.chartData.xAxis) {
        mergedOptions.xAxis.data = this.chartData.xAxis;
      }

      if (this.chartData.series) {
        mergedOptions.series = this.chartData.series;
      }

      this.chart.setOption(mergedOptions);
    },

    // 响应窗口大小变化
    resizeChart() {
      if (this.chart) {
        this.chart.resize();
      }
    }
  }
};
</script>

<style scoped>
.line-chart-container {
  width: 100%;
  height: 100%;
}
</style>