Bootstrap

Vue2实现数据大屏可视化

                它主要展示了如何在页面上使用 echarts 绘制多个中国地图图表,并动态更新当前日期和星期。代码中包含了 Vue 生命周期钩子、事件监听、地图数据展示、窗口尺寸适应等功能。接下来,我将详细介绍这段代码的各个部分:

1.        在模板部分,使用了多个 <div> 元素来容纳不同的图表。每个 div 都有一个 id,对应一个地图图表的显示区域。这里使用了 ref 来引用这些 div 元素,但它们的内容实际是通过 echarts 初始化和渲染的。

<template>
  <div>
    <div ref="dataScreen" id="map" style="height: 100%; width: 100%;"></div>
    <div ref="dataScreen" id="map2" style="height: 100%; width: 100%;"></div>
    <div ref="dataScreen" id="map3" style="height: 100%; width: 100%;"></div>
    <div ref="dataScreen" id="map4" style="height: 100%; width: 100%;"></div>
    <div ref="dataScreen" id="map5" style="height: 100%; width: 100%;"></div>
    <div ref="dataScreen" id="map6" style="height: 100%; width: 100%;"></div>
    <!-- 显示当前日期和星期 -->
    <div>{{ currentDate }} ({{ str }})</div>
    <button @click="backIndex">返回首页</button>
  </div>
</template>

2.数据部分 (data())

在 data() 函数中,定义了需要用到的数据属性:
loading: 用来指示是否正在加载。
currentDate: 当前日期和时间。
str: 当前星期的文字表示(例如“今天是星期一”)。
week: 当前星期的数字(0-6,表示星期日到星期六)。
scale: 用于控制地图缩放的比例,值会基于窗口的大小来动态计算。

data() {
  return {
    loading: true,
    currentDate: '',
    str: '',
    week: null,
    scale: 1,
  };
},

3. 生命周期钩子 (created 和 mounted)

  created:在组件创建时调用,这里用于计算页面比例。this.scale = this.getScale(); 会根据窗口的宽高比例设置缩放值。并且每秒更新一次时间。

created() {
  this.scale = this.getScale();
  setInterval(this.updateTime, 1000);
},

  mounted:在组件挂载后调用,调用 initChart 方法来初始化 echarts 图表。window.addEventListener("resize", this.resize); 用于绑定 resize 事件,当窗口大小变化时调整图表的大小。

mounted() {
  this.initChart();
  window.addEventListener("resize", this.resize);
},

4. 计算缩放比例 (getScale)

getScale 方法根据当前浏览器窗口的大小与预设的参考尺寸(1920x1080)进行比较,返回一个缩放比例。这个比例用于调整地图的大小,使其适应不同的屏幕尺寸。

getScale(width = 1920, height = 1080) {
  let ww = window.innerWidth / width;
  let wh = window.innerHeight / height;
  return ww < wh ? ww : wh;
},

5. 初始化图表 (initChart)

initChart 方法中,使用 echarts 初始化了 6 个中国地图的图表,每个图表的 id 对应于 HTML 模板中的 div 元素。echarts.registerMap('china', mapJson) 注册了中国地图的 GeoJSON 数据(mapJson),并为每个图表设置了统一的配置项。

initChart() {
  const myChart = echarts.init(document.getElementById('map'));
  const myChart2 = echarts.init(document.getElementById('map2'));
  const myChart3 = echarts.init(document.getElementById('map3'));
  const myChart4 = echarts.init(document.getElementById('map4'));
  const myChart5 = echarts.init(document.getElementById('map5'));
  const myChart6 = echarts.init(document.getElementById('map6'));

  echarts.registerMap('china', mapJson);
  const option = {
    backgroundColor: "transparent",
    series: [
      {
        type: "map",
        roam: false,
        top: 100,
        label: {
          normal: {
            show: true,
            textStyle: {
              color: "#fff",
            },
          },
          emphasis: {
            textStyle: {
              color: "#fff",
            },
          },
        },
        itemStyle: {
          normal: {
            borderColor: "#2ab8ff",
            borderWidth: 1.5,
            areaColor: "#12235c",
          },
          emphasis: {
            areaColor: "#2AB8FF",
            borderWidth: 0,
            color: "green",
          },
        },
        zoom: 1.5,
        roam: true,
        map: "china", // 使用注册的地图
      },
    ],
  };

  // 将相同的配置应用到所有的图表
  myChart.setOption(option);
  myChart2.setOption(option);
  myChart3.setOption(option);
  myChart4.setOption(option);
  myChart5.setOption(option);
  myChart6.setOption(option);

  setTimeout(() => {
    this.loading = false;
  }, 2000);
},

6. 窗口大小变化时的处理 (resize 和 resizeCharts)

  • resize:当浏览器窗口大小发生变化时,resize 方法会重新计算缩放比例,并更新每个图表的缩放。这里通过 transform: scale() CSS 样式来缩放 div 元素。

    resize() {
      const scale = this.getScale();
      const dataScreen = this.$refs.dataScreen;
      if (dataScreen) {
        dataScreen.style.transform = `scale(${scale}) translate(-50%, -50%)`;
      }
      this.resizeCharts();
    },
    

    resizeCharts:调用 echarts 实例的 resize 方法,确保图表在窗口调整时正确调整大小。

  • resizeCharts() {
      echarts.getInstanceByDom(document.getElementById('map'))?.resize();
      echarts.getInstanceByDom(document.getElementById('map2'))?.resize();
      echarts.getInstanceByDom(document.getElementById('map3'))?.resize();
      echarts.getInstanceByDom(document.getElementById('map4'))?.resize();
      echarts.getInstanceByDom(document.getElementById('map5'))?.resize();
      echarts.getInstanceByDom(document.getElementById('map6'))?.resize();
    },
    

    7.时间更新 (updateTime)

    updateTime 方法用于每秒更新一次当前日期和星期的显示。它获取当前时间并根据星期数字更新对应的中文字符表示。

  • updateTime() {
      const date = new Date();
      this.currentDate = date.toLocaleString();
      this.week = date.getDay();
      const daysOfWeek = ["日", "一", "二", "三", "四", "五", "六"];
      this.str = `今天是星期${daysOfWeek[this.week]}`;
    },
    

     8.返回首页功能 (backIndex)

    当用户点击“返回首页”按钮时,调用 this.$router.push('/') 跳转到首页。

  • backIndex() {
      this.$router.push('/');
    },
    

    9. 销毁时清除事件监听 (destroyed)

    destroyed 生命周期钩子中,移除 resize 事件的监听,以防止内存泄漏。

  • destroyed() {
      window.removeEventListener("resize", this.resize);
    },
    

    总结:

  • 这段代码的功能非常实用,主要完成了以下任务:

  • 使用 echarts 绘制多个中国地图,并通过 mapJson 加载 GeoJSON 数据。
  • 自动适应窗口大小调整,保持地图和其他内容的缩放和显示效果。
  • 每秒更新当前时间和星期,并显示在页面上。
  • 提供一个返回首页的按钮,通过 Vue Router 进行页面跳转。
  • <template>
      <div>
        <div ref="dataScreen" id="map" style="height: 100%; width: 100%;"></div>
        <div ref="dataScreen" id="map2" style="height: 100%; width: 100%;"></div>
        <div ref="dataScreen" id="map3" style="height: 100%; width: 100%;"></div>
        <div ref="dataScreen" id="map4" style="height: 100%; width: 100%;"></div>
        <div ref="dataScreen" id="map5" style="height: 100%; width: 100%;"></div>
        <div ref="dataScreen" id="map6" style="height: 100%; width: 100%;"></div>
        <!-- 显示当前日期和星期 -->
        <div>{{ currentDate }} ({{ str }})</div>
        <button @click="backIndex">返回首页</button>
      </div>
    </template>
    
    <script>
    import * as echarts from 'echarts';
    import mapJson from './modules/china.json';
    import { mapState } from 'vuex'; // 如果使用 Vuex,可以引入
    
    export default {
      data() {
        return {
          loading: true,
          currentDate: '',
          str: '',
          week: null,
          scale: 1,
        };
      },
      created() {
        // 初始化时计算比例
        this.scale = this.getScale();
        setInterval(this.updateTime, 1000); // 每秒更新一次时间
      },
      mounted() {
        // 组件挂载后初始化图表
        this.initChart();
    
        // 绑定窗口的 resize 事件
        window.addEventListener("resize", this.resize);
      },
      methods: {
        // 根据窗口大小计算比例
        getScale(width = 1920, height = 1080) {
          let ww = window.innerWidth / width;
          let wh = window.innerHeight / height;
          return ww < wh ? ww : wh;
        },
        
        // 窗口大小变化时调整地图的缩放比例
        resize() {
          const scale = this.getScale();
          const dataScreen = this.$refs.dataScreen;
          if (dataScreen) {
            dataScreen.style.transform = `scale(${scale}) translate(-50%, -50%)`;
          }
    
          // 调整所有图表的大小
          this.resizeCharts();
        },
    
        // 初始化 echarts 图表
        initChart() {
          const myChart = echarts.init(document.getElementById('map'));
          const myChart2 = echarts.init(document.getElementById('map2'));
          const myChart3 = echarts.init(document.getElementById('map3'));
          const myChart4 = echarts.init(document.getElementById('map4'));
          const myChart5 = echarts.init(document.getElementById('map5'));
          const myChart6 = echarts.init(document.getElementById('map6'));
    
          echarts.registerMap('china', mapJson);
          const option = {
            backgroundColor: "transparent",
            series: [
              {
                type: "map",
                roam: false,
                top: 100,
                label: {
                  normal: {
                    show: true,
                    textStyle: {
                      color: "#fff",
                    },
                  },
                  emphasis: {
                    textStyle: {
                      color: "#fff",
                    },
                  },
                },
                itemStyle: {
                  normal: {
                    borderColor: "#2ab8ff",
                    borderWidth: 1.5,
                    areaColor: "#12235c",
                  },
                  emphasis: {
                    areaColor: "#2AB8FF",
                    borderWidth: 0,
                    color: "green",
                  },
                },
                zoom: 1.5,
                roam: true,
                map: "china", // 使用注册的地图
              },
            ],
          };
    
          // 将相同的配置应用到所有的图表
          myChart.setOption(option);
          myChart2.setOption(option);
          myChart3.setOption(option);
          myChart4.setOption(option);
          myChart5.setOption(option);
          myChart6.setOption(option);
    
          // 绑定 resize 事件,窗口大小变化时调整图表大小
          window.addEventListener("resize", () => {
            this.resizeCharts();
          });
    
          setTimeout(() => {
            this.loading = false;
          }, 2000);
        },
    
        // 调整所有 echarts 实例的大小
        resizeCharts() {
          echarts.getInstanceByDom(document.getElementById('map'))?.resize();
          echarts.getInstanceByDom(document.getElementById('map2'))?.resize();
          echarts.getInstanceByDom(document.getElementById('map3'))?.resize();
          echarts.getInstanceByDom(document.getElementById('map4'))?.resize();
          echarts.getInstanceByDom(document.getElementById('map5'))?.resize();
          echarts.getInstanceByDom(document.getElementById('map6'))?.resize();
        },
    
        // 返回首页
        backIndex() {
          this.$router.push('/');
        },
    
        // 每秒更新一次当前时间
        updateTime() {
          const date = new Date();
          this.currentDate = date.toLocaleString();
          this.week = date.getDay();
          const daysOfWeek = ["日", "一", "二", "三", "四", "五", "六"];
          this.str = `今天是星期${daysOfWeek[this.week]}`;
        },
      },
      destroyed() {
        // 组件销毁时移除事件监听
        window.removeEventListener("resize", this.resize);
      },
    };
    </script>
    
    <style scoped>
    /* 在这里添加样式 */
    </style>
    

;