vue+element項目中對echarts圖表隨着瀏覽器窗口resize的處理

知識點:

mixins、ref、$refs、element響應式佈局

準備工作:

1、項目中安裝echarts:

cnpm i echarts -S

2、在main.js中引入echarts:

import echarts from 'echarts'
// 在原型鏈中註冊,然後在需要的頁面調用:this.$echarts
Vue.prototype.$echarts = echarts

實現方式:

1、普通方式:

實現該功能的單文件組件爲:chart.vue

<template>
  <el-row>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart1" style="height: 300px;"></div>
    </el-col>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart2" style="height: 300px;"></div>
    </el-col>
  </el-row>
</template>

<script>
export default {
  data() {
    return {
      AreaPiecesChart: null,
      electricityChart: null
    };
  },
  methods: {
    drawAreaPieces() {
      this.AreaPiecesChart = this.$echarts.init(
        this.$refs.myChart1
      );

      let option = {
        xAxis: {
          type: "category",
          boundaryGap: false
        },
        yAxis: {
          type: "value",
          boundaryGap: [0, "30%"]
        },
        visualMap: {
          type: "piecewise",
          show: false,
          dimension: 0,
          seriesIndex: 0,
          pieces: [
            {
              gt: 1,
              lt: 3,
              color: "rgba(0, 180, 0, 0.5)"
            },
            {
              gt: 5,
              lt: 7,
              color: "rgba(0, 180, 0, 0.5)"
            }
          ]
        },
        series: [
          {
            type: "line",
            smooth: 0.6,
            symbol: "none",
            lineStyle: {
              color: "green",
              width: 5
            },
            markLine: {
              symbol: ["none", "none"],
              label: { show: false },
              data: [{ xAxis: 1 }, { xAxis: 3 }, { xAxis: 5 }, { xAxis: 7 }]
            },
            areaStyle: {},
            data: [
              ["2019-10-10", 200],
              ["2019-10-11", 400],
              ["2019-10-12", 650],
              ["2019-10-13", 500],
              ["2019-10-14", 250],
              ["2019-10-15", 300],
              ["2019-10-16", 450],
              ["2019-10-17", 300],
              ["2019-10-18", 100]
            ]
          }
        ]
      };

      this.AreaPiecesChart.setOption(option);
    },
    drawElectricity() {
      this.electricityChart = this.$echarts.init(
                this.$refs.myChart2
      );

      let option = {
        title: {
          text: "一天用電量分佈",
          subtext: "純屬虛構"
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross"
          }
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: [
            "00:00",
            "01:15",
            "02:30",
            "03:45",
            "05:00",
            "06:15",
            "07:30",
            "08:45",
            "10:00",
            "11:15",
            "12:30",
            "13:45",
            "15:00",
            "16:15",
            "17:30",
            "18:45",
            "20:00",
            "21:15",
            "22:30",
            "23:45"
          ]
        },
        yAxis: {
          type: "value",
          axisLabel: {
            formatter: "{value} W"
          },
          axisPointer: {
            snap: true
          }
        },
        visualMap: {
          show: false,
          dimension: 0,
          pieces: [
            {
              lte: 6,
              color: "green"
            },
            {
              gt: 6,
              lte: 8,
              color: "red"
            },
            {
              gt: 8,
              lte: 14,
              color: "green"
            },
            {
              gt: 14,
              lte: 17,
              color: "red"
            },
            {
              gt: 17,
              color: "green"
            }
          ]
        },
        series: [
          {
            name: "用電量",
            type: "line",
            smooth: true,
            data: [
              300,
              280,
              250,
              260,
              270,
              300,
              550,
              500,
              400,
              390,
              380,
              390,
              400,
              500,
              600,
              750,
              800,
              700,
              600,
              400
            ],
            markArea: {
              data: [
                [
                  {
                    name: "早高峯",
                    xAxis: "07:30"
                  },
                  {
                    xAxis: "10:00"
                  }
                ],
                [
                  {
                    name: "晚高峯",
                    xAxis: "17:30"
                  },
                  {
                    xAxis: "21:15"
                  }
                ]
              ]
            }
          }
        ]
      };
      this.electricityChart.setOption(option);
    },
    chartResize(){
        let eleArr = [this.AreaPiecesChart, this.electricityChart];
        for(let i = 0; i<eleArr.length; i++){
          //此處定時器是爲了在頁面存在多個圖時,resize方法的調用時間微微錯開,避免明顯的卡頓
          setTimeout(function(){
              eleArr[i].resize();
          }, 200);
        }
    }
  },
  mounted() {
    this.drawAreaPieces();
    this.drawElectricity();
    //注:此處要用addEventListener,如果用 window.onresize = function(){},如果別的組件也用了onresize事件,就容易覆蓋掉此處的函數
    window.addEventListener("resize", this.chartResize);
  },
  destroyed(){
    window.removeEventListener("resize", this.chartResize);
  }
};
</script>

<style scoped>
#myChart1,
#myChart2 {
  height: 300px;
}
</style>

2、使用mixins的方式引入:

定義一個頁面Resize.vue,用來處理每一個有圖表的頁面添加resize , 離開時移除resize函數:

<script>
/**
 * 用來處理每一個有圖表的頁面添加resize , 離開時移除resize函數
 */
import echarts from "echarts";
export default {
  data() {
    return {
      doms: []
    };
  },
  methods: {
    chartResize(eleArr) {
      for (let i = 0; i < eleArr.length; i++) {
        setTimeout(function() {
          eleArr[i].resize();
        }, 200);
      }
    }
  },
  mounted() {
    let _this = this;
    window.addEventListener("resize", function() {
      _this.chartResize(_this.doms);
    });
  },
  destroyed() {
    let _this = this;
    window.removeEventListener("resize", function() {
      _this.chartResize(_this.doms);
    });
  }
};
</script>

圖表頁面Chart.vue中引入Resize.vue:

<template>
  <el-row>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart1" style="height: 300px;"></div>
    </el-col>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart2" style="height: 300px;"></div>
    </el-col>
  </el-row>
</template>

<script>
import Resize from './Resize'
export default {
  mixins: [Resize],
  data() {
    return {
      AreaPiecesChart: null,
      electricityChart: null
    };
  },
  methods: {
    drawAreaPieces() {
      this.AreaPiecesChart = this.$echarts.init(
        this.$refs.myChart1
      );

      this.doms.push(this.AreaPiecesChart);

      let option = {
        xAxis: {
          type: "category",
          boundaryGap: false
        },
        yAxis: {
          type: "value",
          boundaryGap: [0, "30%"]
        },
        visualMap: {
          type: "piecewise",
          show: false,
          dimension: 0,
          seriesIndex: 0,
          pieces: [
            {
              gt: 1,
              lt: 3,
              color: "rgba(0, 180, 0, 0.5)"
            },
            {
              gt: 5,
              lt: 7,
              color: "rgba(0, 180, 0, 0.5)"
            }
          ]
        },
        series: [
          {
            type: "line",
            smooth: 0.6,
            symbol: "none",
            lineStyle: {
              color: "green",
              width: 5
            },
            markLine: {
              symbol: ["none", "none"],
              label: { show: false },
              data: [{ xAxis: 1 }, { xAxis: 3 }, { xAxis: 5 }, { xAxis: 7 }]
            },
            areaStyle: {},
            data: [
              ["2019-10-10", 200],
              ["2019-10-11", 400],
              ["2019-10-12", 650],
              ["2019-10-13", 500],
              ["2019-10-14", 250],
              ["2019-10-15", 300],
              ["2019-10-16", 450],
              ["2019-10-17", 300],
              ["2019-10-18", 100]
            ]
          }
        ]
      };

      this.AreaPiecesChart.setOption(option);
    },
    drawElectricity() {
      this.electricityChart = this.$echarts.init(
                this.$refs.myChart2
      );

      this.doms.push(this.electricityChart);

      let option = {
        title: {
          text: "一天用電量分佈",
          subtext: "純屬虛構"
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross"
          }
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: [
            "00:00",
            "01:15",
            "02:30",
            "03:45",
            "05:00",
            "06:15",
            "07:30",
            "08:45",
            "10:00",
            "11:15",
            "12:30",
            "13:45",
            "15:00",
            "16:15",
            "17:30",
            "18:45",
            "20:00",
            "21:15",
            "22:30",
            "23:45"
          ]
        },
        yAxis: {
          type: "value",
          axisLabel: {
            formatter: "{value} W"
          },
          axisPointer: {
            snap: true
          }
        },
        visualMap: {
          show: false,
          dimension: 0,
          pieces: [
            {
              lte: 6,
              color: "green"
            },
            {
              gt: 6,
              lte: 8,
              color: "red"
            },
            {
              gt: 8,
              lte: 14,
              color: "green"
            },
            {
              gt: 14,
              lte: 17,
              color: "red"
            },
            {
              gt: 17,
              color: "green"
            }
          ]
        },
        series: [
          {
            name: "用電量",
            type: "line",
            smooth: true,
            data: [
              300,
              280,
              250,
              260,
              270,
              300,
              550,
              500,
              400,
              390,
              380,
              390,
              400,
              500,
              600,
              750,
              800,
              700,
              600,
              400
            ],
            markArea: {
              data: [
                [
                  {
                    name: "早高峯",
                    xAxis: "07:30"
                  },
                  {
                    xAxis: "10:00"
                  }
                ],
                [
                  {
                    name: "晚高峯",
                    xAxis: "17:30"
                  },
                  {
                    xAxis: "21:15"
                  }
                ]
              ]
            }
          }
        ]
      };
      this.electricityChart.setOption(option);
    }
  },
  mounted() {
    this.drawAreaPieces();
    this.drawElectricity();
  }
};
</script>

<style scoped>

</style>

3、使用Vue.prototype方式引入:

將echarts中resize圖表的方法抽象成一個函數chartResize.js:

function chartResize(eleArr){
    for(let i = 0; i<eleArr.length; i++){
        // 定時器是爲了在頁面存在多個圖時,resize方法的調用時間微微錯開,避免明顯的卡頓
        setTimeout(function(){
            eleArr[i].resize();
        }, 200);
    }
}

export {chartResize}

main.js中在原型中註冊chartResize函數:

import {chartResize} from './assets/chartResize.js'

// 在原型鏈中註冊,然後在需要的頁面調用:this.$chartResize()
Vue.prototype.$chartResize = chartResize

在Chart.vue組件中使用:

<template>
  <el-row>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart1" style="height: 300px;"></div>
    </el-col>
    <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="12">
      <div ref="myChart2" style="height: 300px;"></div>
    </el-col>
  </el-row>
</template>

<script>
export default {
  data() {
    return {
      AreaPiecesChart: null,
      electricityChart: null
    };
  },
  methods: {
    drawAreaPieces() {
      this.AreaPiecesChart = this.$echarts.init(
        this.$refs.myChart1
      );

      let option = {
        xAxis: {
          type: "category",
          boundaryGap: false
        },
        yAxis: {
          type: "value",
          boundaryGap: [0, "30%"]
        },
        visualMap: {
          type: "piecewise",
          show: false,
          dimension: 0,
          seriesIndex: 0,
          pieces: [
            {
              gt: 1,
              lt: 3,
              color: "rgba(0, 180, 0, 0.5)"
            },
            {
              gt: 5,
              lt: 7,
              color: "rgba(0, 180, 0, 0.5)"
            }
          ]
        },
        series: [
          {
            type: "line",
            smooth: 0.6,
            symbol: "none",
            lineStyle: {
              color: "green",
              width: 5
            },
            markLine: {
              symbol: ["none", "none"],
              label: { show: false },
              data: [{ xAxis: 1 }, { xAxis: 3 }, { xAxis: 5 }, { xAxis: 7 }]
            },
            areaStyle: {},
            data: [
              ["2019-10-10", 200],
              ["2019-10-11", 400],
              ["2019-10-12", 650],
              ["2019-10-13", 500],
              ["2019-10-14", 250],
              ["2019-10-15", 300],
              ["2019-10-16", 450],
              ["2019-10-17", 300],
              ["2019-10-18", 100]
            ]
          }
        ]
      };

      this.AreaPiecesChart.setOption(option);
    },
    drawElectricity() {
      this.electricityChart = this.$echarts.init(
                this.$refs.myChart2
      );

      let option = {
        title: {
          text: "一天用電量分佈",
          subtext: "純屬虛構"
        },
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "cross"
          }
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: [
            "00:00",
            "01:15",
            "02:30",
            "03:45",
            "05:00",
            "06:15",
            "07:30",
            "08:45",
            "10:00",
            "11:15",
            "12:30",
            "13:45",
            "15:00",
            "16:15",
            "17:30",
            "18:45",
            "20:00",
            "21:15",
            "22:30",
            "23:45"
          ]
        },
        yAxis: {
          type: "value",
          axisLabel: {
            formatter: "{value} W"
          },
          axisPointer: {
            snap: true
          }
        },
        visualMap: {
          show: false,
          dimension: 0,
          pieces: [
            {
              lte: 6,
              color: "green"
            },
            {
              gt: 6,
              lte: 8,
              color: "red"
            },
            {
              gt: 8,
              lte: 14,
              color: "green"
            },
            {
              gt: 14,
              lte: 17,
              color: "red"
            },
            {
              gt: 17,
              color: "green"
            }
          ]
        },
        series: [
          {
            name: "用電量",
            type: "line",
            smooth: true,
            data: [
              300,
              280,
              250,
              260,
              270,
              300,
              550,
              500,
              400,
              390,
              380,
              390,
              400,
              500,
              600,
              750,
              800,
              700,
              600,
              400
            ],
            markArea: {
              data: [
                [
                  {
                    name: "早高峯",
                    xAxis: "07:30"
                  },
                  {
                    xAxis: "10:00"
                  }
                ],
                [
                  {
                    name: "晚高峯",
                    xAxis: "17:30"
                  },
                  {
                    xAxis: "21:15"
                  }
                ]
              ]
            }
          }
        ]
      };
      this.electricityChart.setOption(option);
    }
  },
  computed: {
    chartArr(){
      return [this.AreaPiecesChart, this.electricityChart];
    }
  },
  mounted() {
    this.drawAreaPieces();
    this.drawElectricity();

    let _this = this;
    //注:此處要用addEventListener,如果用 window.onresize = function(){},如果別的組件也用了onresize事件,就容易覆蓋掉此處的函數
    window.addEventListener("resize", function(){
      _this.$chartResize(_this.chartArr);
    });
  },
  destroyed(){
    let _this = this;
    window.removeEventListener("resize", function(){
      _this.$chartResize(_this.chartArr);
    });
  }
};
</script>

<style scoped>

</style>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章