echarts map地图动态下钻,自定义标注,自定义tooltip弹窗【完整demo版本】

在数据可视化中,地图是很重要的一个环节,很多时候需要展现的不仅是国家地图,还需要能从国家进入到省市。这个逐级进入的过程就是我们今天说的地图下钻。

地图下钻看起来很屌、很高大上,但是仔细琢磨一下,技术实现上真的很简单。

文章目录

  • [1. 本章主要功能介绍](#1. 本章主要功能介绍)
  • [1. 地图下钻实现思路(本章核心)](#1. 地图下钻实现思路(本章核心))
  • [2. 下钻代码实现(本章核心)](#2. 下钻代码实现(本章核心))
  • [3. 完整代码](#3. 完整代码)
    • [3.1 vue部分](#3.1 vue部分)
    • [3.2 mapData.js 部分](#3.2 mapData.js 部分)
  • [4. 接口数据](#4. 接口数据)

1. 本章主要功能介绍

  1. 自定义标注样式&自定义tooltip弹窗样式(上章内容) echarts 自定义标注样式&自定义tooltip弹窗样式
  2. 自定义地图贴图样式(上章内容)echarts 实现中国geo地图自定义贴图实例
  3. 下拉菜单选择切换地图省份(本章核心)
  4. 点击地图切换地图省份(本章核心)
  5. 进入全屏/退出全屏(其他)

1. 地图下钻实现思路(本章核心)

  1. mounted 里面首先初始化一个中国地图的数据,provinceCode默认为100000
  2. 创建echarts实例,获取中国地图的 geoJSON 数据
  3. 拿到geoJSON 数据调用initEcharts函数区创建echarts
  4. geoJSON 数据对echarts进行渲染上图
  5. 上图完成后,通过 this.myChart.on("click",()=>{}) 事件活动点击的对象,params.name 可以拿到点击的省份名称,修改 provinceCode 值为点击的省份
  6. 监听 provinceCode 改变,重新执行第一递归循环即可

2. 下钻代码实现(本章核心)

3. 完整代码

3.1 vue部分

html 复制代码
<template>
  <div class="map">
    <div class="navProvince">
      <select
        v-model="provinceCode"
        @change="changeProvince($event.target.value)"
      >
        <option
          :value="item.code"
          v-for="(item, index) in provinceData()"
          :key="index"
        >
          {{ item.name }}
        </option>
      </select>
      <img src="@/assets/img/dataView/down.webp" alt="" srcset="" />
    </div>
    <div class="navBase" v-if="baseId">
      <select v-model="baseId" @change="changeBaseId($event.target.value)">
        <option
          :value="item.baseId"
          v-for="(item, index) in baseData"
          :key="index"
        >
          {{ item.name }}
        </option>
      </select>
      <img src="@/assets/img/dataView/down.webp" alt="" srcset="" />
    </div>
    <div
      class="screen"
      @click="toggleFullScreen"
      :title="isFullscreen ? '退出全屏' : '进入全屏'"
    >
      <img src="@/assets/img/dataView/screen.webp" alt="" srcset="" />
      <span>{{ isFullscreen ? "退出全屏" : "进入全屏" }}</span>
    </div>
    <div ref="myEchart" id="personnel"></div>
  </div>
</template>

<script>
import "echarts-gl"; //3D地图插件
import screenfull from "screenfull";
import axios from "axios";
import {
  provinceObj,
  provinceData,
  getCodeByName,
  formatHtml,
} from "./js/mapData";
import { API_listBase } from "@/api/dataView";
import { mapGetters } from "vuex";
export default {
  data() {
    return {
      provinceData,
      isFullscreen: false,
      publicUrl: "https://geo.datav.aliyun.com/areas_v3/bound/",
      chinaGeoJson: [],
      myChart: null,
      mapImg: null, //地图底色
      mapActiveImg: null, //地图悬浮移入后的底色
      baseData: [], //基地数据
      provinceCode: 100000,
      baseId: "",
    };
  },
  computed: {
    ...mapGetters({
      getProvinceCode: "dataView/getProvinceCode",
      getBaseId: "dataView/getBaseId",
    }),
  },
  watch: {
    provinceCode(_newData, _oldData) {
      this.provinceCode = _newData;
      this.$store.commit(
        "dataView/SET_PROVINCECODE",
        provinceObj[_newData] == "全国" ? "" : _newData
      );
      this.getList();
    },
  },
  methods: {
    // 请求三方地图数据接口
    async getGeoJson(jsonName, province) {
      let res = await axios.get(`${this.publicUrl}${jsonName}`);
      if (res && res.status === 200) {
        this.initEcharts(res.data, province);
      }
    },
    // 加载地图数据
    initEcharts(geoJson, name) {
      this.$echarts.registerMap(name, geoJson);
      let option = {
        tooltip: {
          trigger: "item",
          formatter: function (params) {
            // 为小图表创建一个容器
            if (params.data) {
              return params.name + " : " + params.data.data.datas;
            }
          },
        },
        geo: {
          map: name == "全国" ? "china" : name,
          zoom: 1,
          roam: false,
          itemStyle: {
            normal: {
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.8,
                colorStops: [
                  {
                    offset: 0,
                    color: "#09132c", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "#274d68", // 100% 处的颜色
                  },
                ],
                globalCoord: true, // 缺省为 false
              },
              shadowColor: "rgb(13, 48, 92,0.8)", //底层颜色
              shadowOffsetX: 10,
              shadowOffsetY: 11,
            },
          },
          regions: [
            {
              show: false,
              name: "南海诸岛",
              itemStyle: {
                areaColor: "rgba(0, 10, 52, 1)",
                borderColor: "rgba(0, 10, 52, 1)",
                normal: {
                  opacity: 0,
                  label: {
                    show: false,
                    color: "#009cc9",
                  },
                },
              },
            },
          ],
        },
        series: [
          {
            type: "map",
            roam: false,
            label: {
              normal: {
                show: true,
                textStyle: {
                  color: "#D5E0EE",
                },
              },
              emphasis: {
                textStyle: {
                  color: "rgb(183,185,14)",
                },
              },
            },
            itemStyle: {
              normal: {
                borderColor: "rgb(81, 184, 220)",
                borderWidth: 1,
                areaColor: {
                  image: this.mapImg,
                  repeat: "repeat",
                },
              },
              emphasis: {
                areaColor: {
                  image: this.mapActiveImg,
                  repeat: "repeat",
                },
                borderColor: "#2ab8ff",
                borderWidth: 1,
                shadowColor: "rgba(0, 255, 255, 0.7)",
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowOffsetY: 1,
                label: {
                  show: false,
                },
              },
            },
            zoom: 1,
            map: name == "全国" ? "china" : name, //使用
          },
          {
            type: "scatter",
            coordinateSystem: "geo",
            itemStyle: {
              color: "#f00",
            },
            tooltip: {
              trigger: "item",
              backgroundColor: "transparent",
              formatter: function (params) {
                return formatHtml(params.data);
              },
            },
            symbol: `image://${require("@/assets/img/dataView/point.png")}`,
            symbolSize: [48, 58],
            symbolOffset: [0, 0],
            z: 9999,
            data: this.baseData,
          },
        ],
      };
      this.myChart = this.$echarts.init(this.$refs.myEchart);
      this.myChart.setOption(option, true);
      this.myChart.off("click");
      this.myChart.on("click", (params) => {
        this.$store.commit("dataView/SET_BASEID", params.data?.baseId);
        if (params.data?.provinceCode) {
          this.baseId = params.data?.baseId;
        }
        if (params.data?.provinceCode || getCodeByName(params.name)) {
          this.provinceCode =
            params.data?.provinceCode || getCodeByName(params.name);
        } else {
          return this.$message.warning("暂无继续进行地图下钻");
        }
      });
    },
    // 切换全屏
    toggleFullScreen() {
      if (!screenfull.isEnabled) return false;
      screenfull.toggle();
    },
    changeProvince(_data) {
      this.baseId = "";
      this.$store.commit("dataView/SET_BASEID", "");
    },
    changeBaseId(_data) {
      let params = this.baseData.find((item) => item.baseId == _data);
      if (params) {
        this.provinceCode = params?.provinceCode;
      } else {
        return this.$message.warning("切换失败");
      }
    },
    async getList() {
      let { code, data } = await API_listBase({
        provinceCode: this.getProvinceCode,
        baseId: this.getBaseId,
      });
      if (code === 200) {
        this.baseData = data.map((item, _index) => {
          return {
            ...item,
            value: item.baseLocation.split(","),
            name: item.unitName,
            province: item.province,
            computilityData: item.computilityData
              ? item.computilityData
              : {
                  baseCpuserverNumber: 0,
                  baseCpuScores: 0,
                  baseIdlecpuScores: 0,
                  baseMemoryCapacity: 0,
                  baseIdlememoryCapacity: 0,
                  baseStorageCapacity: 0,
                  baseIdlestorageCapacity: 0,
                  baseUploadBandwidthCapacity: 0,
                  baseIdleuploadBandwidthCapacity: 0,
                  baseDownloadBandwidthCapacity: 0,
                  baseIdledownloadBandwidthCapacity: 0,
                  baseGpuserverNumber: 0,
                  baseGpuScores: 0,
                  baseIdlegpuScores: 0,
                  baseNpuserverNumber: 0,
                  baseNpuScores: 0,
                  baseIdlenpuScores: 0,
                  baseFp16Computility: 0,
                  baseIdlefp16Computility: 0,
                  baseFp32Computility: 0,
                  baseIdlefp32Computility: 0,
                  baseGraphicsMemoryCapacity: 0,
                  baseIdlegraphicsMemoryCapacity: 0,
                },
          };
        });
      }
      // 初始化中国地图
      this.$nextTick(() => {
        this.myChart = this.$echarts.init(this.$refs.myEchart);
        this.getGeoJson(
          `${this.provinceCode}_full.json`,
          provinceObj[this.provinceCode]
        );
      });
    },
  },
  mounted() {
    // 地图底色
    this.mapImg = document.createElement("img");
    this.mapImg.style.height =
      this.mapImg.height =
      this.mapImg.width =
      this.mapImg.style.width =
        "100px";
    this.mapImg.src =
      "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAIAAAAmKNuZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMS1jMDAwIDc5LmRhYmFjYmIsIDIwMjEvMDQvMTQtMDA6Mzk6NDQgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMy4wIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3Qjk5OUJBRTZGNTMxMUVGODI5Q0EzOUY4MDEwOEUwNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo3Qjk5OUJBRjZGNTMxMUVGODI5Q0EzOUY4MDEwOEUwNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjdCOTk5QkFDNkY1MzExRUY4MjlDQTM5RjgwMTA4RTA3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjdCOTk5QkFENkY1MzExRUY4MjlDQTM5RjgwMTA4RTA3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+3sCwvQAAAdRJREFUeNqMVUtOAzEMta1uGKTuQD0K4iLdcy24QDlIz1KVHRJlZ+P87UwyZTat42+e7Rc8fnyezt/gPgFAIAA2on7hROIfzIactJAMjq97hLd3uP42n+eHKBa7wyNcfrLKaZO4wPVmRSqmxSFkrgm9ymmhpTQilSMx9Rt/7gO6j7ATu+pknRAsPrwRW1S7Cz+HJWOc4VvCoWZOpam2VkpJa2pPxiXHLrhdbq2D6nxx6DpRtV+3dgFnLLEV7EtmC6WEcmBwe4esx67q0ZSN4xbwBLVkzJrddQf7chg2P/FDpthxbQVm/4R9DaSjW9uS0MzrgRk+rlskthUWe2ld1rlHzHXcaxRNQPaoiYzu3jVKInY8CeFC4+TczEAUqV8DmkCOo7nJCHZjHOAs/MMRe1usFbO20BcZMYfTEMo5mSnEcE48CgRV6Uu1jyuCcuRWKEAsKeEKTWyc2s+dhL4XMyoWOIJ5+yQRFDbwCajvfXMUs8KTJem1UgkKGrpPi7taWoMazq5QR1+hFbDaiqt9HFJnoj/GTB1f2ZckboX8Y8lHD0OGFLupxc1xhy3q11s7+hOarMGQ8vDOABDuji/70xncI51eA1o/DtJekjbnrY0a6k+AAQAfPMeH5wCecwAAAABJRU5ErkJggg==";

    // 地图悬浮移入后的底色
    this.mapActiveImg = document.createElement("img");
    this.mapActiveImg.style.height =
      this.mapActiveImg.height =
      this.mapActiveImg.width =
      this.mapActiveImg.style.width =
        "100px";
    this.mapActiveImg.src =
      "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAIAAAAmKNuZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMS1jMDAwIDc5LmRhYmFjYmIsIDIwMjEvMDQvMTQtMDA6Mzk6NDQgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCAyMy4wIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3NjJDOUNEMDZGNTMxMUVGQjI2OUM4RUM4MzQwOTI5RiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo3NjJDOUNEMTZGNTMxMUVGQjI2OUM4RUM4MzQwOTI5RiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjc2MkM5Q0NFNkY1MzExRUZCMjY5QzhFQzgzNDA5MjlGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjc2MkM5Q0NGNkY1MzExRUZCMjY5QzhFQzgzNDA5MjlGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+LKM4xwAAAfVJREFUeNqEVV1OwzAMjqOqSKMPsN6AnYEdiCtxC47CzjBusJ+HDIkixThx6zpOO/LQxU7iON/32YOP97fwdXDTAHAY6cd5SGZE51CZMX29HzePq+lYmnS71yYcD+fvIW3K/qdNe80mj23Xnm+zaVafu/ZyGzhguuh48BQYxujjzehWh6yOX7XVj190MLlU4rO5OHgPIYDKkzDhYJygoANlXBNIT6B0NnSCAIr5HOPNJs8xmzpcbUb1lobgOIfBjQRm7MOAU2p9157yKggzYZCUe7WZifLmLRELHPVD/h2UmWewJF+NrsSFFfhcyWGCiDUJJcZQQY4V+/ULKJWGstPY12CTVnU6vVrFkjcKxVT8yk3bEl0yL2FQsR5O4aeomVCUkJeszXM0oMqDtbNgQ6iEdaFCCZMmB1Xo9Op7pbRCrkQksMBQQdgJ9iwag70xDVFJukq7DWV4vQ2CVF+i22cqdBlIkXDNUL8S6cxVgXcLoK52AQu1SKmjeLCBjIwXseOvh4KlhF1dK4uTxT3SzYSZoirQ2QZlsGe81toX+RsKa5RNYEOpe0G2LgOz2eqOVa2VabSNS11e/Ck7rXhG1xwDFR0UOXzZvBozs3d6DkBJNyy0vDk7Ynbzst8eP+cSj5XuH1u6Uv6hE1HTn7emkebdbv8nwADKuQThmsBu6AAAAABJRU5ErkJggg==";

    // 初始化中国地图
    this.getList();
  },
};
</script>

<style lang="less" scoped>
.map {
  flex: 1;
  width: 100%;
  color: #fff;
  position: relative;

  .navProvince,
  .navBase {
    position: absolute;
    left: 40px;
    width: 160px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: url("../../../../assets/img/dataView/nav_bg.webp") no-repeat;
    background-size: 160px 32px;
    background-position: center;
    cursor: pointer;
    z-index: 2;

    img {
      height: 16px;
      position: absolute;
      top: 50%;
      right: 10px;
      transform: translateY(-50%);
    }
  }

  .navBase {
    left: 220px;
  }

  .screen {
    position: absolute;
    right: 40px;
    width: 118px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: url("../../../../assets/img/dataView/screen_bg.webp") no-repeat;
    background-size: 118px 32px;
    background-position: center;
    cursor: pointer;
    z-index: 2;

    img {
      height: 24px;
      margin-right: 10px;
    }

    span {
      font-weight: normal;
      font-size: 16px;
      color: #4b94ff;
      line-height: 16px;
    }
  }
}

#personnel {
  width: 100%;
  height: 100%;
  z-index: 1;
}
select {
  width: 100%;
  padding: 6px 10px 6px 16px;
  box-sizing: border-box;
  font-size: 16px;
  color: #4b94ff;
  line-height: 16px;
  -webkit-appearance: none;
  /* for Chrome, Safari */
  -moz-appearance: none;
  /* for Firefox */
  -ms-appearance: none;
  /* for IE10+ */

  appearance: none;
  -moz-appearance: none;
  background: transparent;
  -webkit-appearance: none;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  -webkit-tap-highlight-color: transparent;

  option {
    background: transparent;
  }
}
</style>

<style scoped lang="less">
/deep/ .tooltip-chart {
  background-color: transparent;
  width: 520px;
  height: 334px;
  background: url("../../../../assets/img/dataView/tooltip_bg.webp") no-repeat;
  background-size: 100% 100%;
  background-position: center;
  padding: 16px 25px 16px 20px;
  grid-gap: 0 40px;
  overflow: auto;
  display: grid;
  grid-template-columns: repeat(2, 1fr);

  .item {
    font-weight: 500;
    font-size: 13px;
    color: #ffffff;
    line-height: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
 
    span {
      &.name{
        // color: #4b94ff;
      }
      &:first-child {
        position: relative;
        padding-left: 14px;

        &::after {
          content: "";
          position: absolute;
          top: 50%;
          left: 0;
          transform: translateY(-50%);
          width: 5px;
          height: 5px;
          border-radius: 50%;
          background: #fff;
        }
      }

      &:last-child {
        text-align: left;
      }
    }
  }
}
</style>

3.2 mapData.js 部分

ts 复制代码
export const provinceObj = {
  100000: "全国",
  110000: "北京",
  120000: "天津",
  130000: "河北",
  140000: "山西",
  150000: "内蒙古",
  210000: "辽宁",
  220000: "吉林",
  230000: "黑龙江",
  310000: "上海",
  320000: "江苏",
  330000: "浙江",
  340000: "安徽",
  350000: "福建",
  360000: "江西",
  370000: "山东",
  410000: "河南",
  420000: "湖北",
  430000: "湖南",
  440000: "广东",
  450000: "广西",
  460000: "海南",
  500000: "重庆",
  510000: "四川",
  520000: "贵州",
  530000: "云南",
  540000: "西藏",
  610000: "陕西",
  620000: "甘肃",
  630000: "青海",
  640000: "宁夏",
  650000: "新疆",
  710000: "台湾",
  810000: "香港",
  820000: "澳门",
};


export let provinceData = () => {
  let arr = [];
  for (const key in provinceObj) {
    arr.push({
      code: key,
      name: provinceObj[key],
    });
  }
  return arr;
};

/**
 * 根据名称查询对应的键
 * @param {*} name
 * @returns
 */
export let getCodeByName = (name) => {
  for (const [key, value] of Object.entries(provinceObj)) {
    if (value === name) {
      return key;
    }
  }
  return null; // 如果没有找到
};

/**
 * 基地展示数据
 * @param {*} param0
 * @returns
 */
export let formatHtml = ({ name, computilityData }) => {
  return `
        <div class="tooltip-chart">
        <div class="item">
            <span>基地名称</span>
            <span class="name">${name}</span>
        </div>
        <div class="item">
             <span>基地CPU服务器数量</span>
            <span>${computilityData?.baseCpuserverNumber || 0}</span>
        </div>
        <div class="item">
            <span>基地CPU总核数</span>
            <span>${computilityData?.baseCpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲CPU核数</span>
            <span>${computilityData?.baseIdlecpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地内存空间总容量</span>
            <span>${computilityData?.baseMemoryCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲内存空间容量</span>
            <span>${computilityData?.baseIdlememoryCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地存储空间总容量</span>
            <span>${computilityData?.baseStorageCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲存储空间容量</span>
            <span>${computilityData?.baseIdlestorageCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地上行网络带宽总量</span>
            <span>${computilityData?.baseUploadBandwidthCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲上行网络带宽</span>
            <span>${
              computilityData?.baseIdleuploadBandwidthCapacity || 0
            }</span>
        </div>
        <div class="item">
            <span>基地下行网络带宽总量</span>
            <span>${computilityData?.baseDownloadBandwidthCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲下行网络带宽</span>
            <span>${
              computilityData?.baseIdledownloadBandwidthCapacity || 0
            }</span>
        </div>
        <div class="item">
            <span>基地GPU服务器数量</span>
            <span>${computilityData?.baseGpuserverNumber || 0}</span>
        </div>
        <div class="item">
            <span>基地GPU总核数</span>
            <span>${computilityData?.baseGpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲GPU核数</span>
            <span>${computilityData?.baseIdlegpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地NPU服务器数量</span>
            <span>${computilityData?.baseNpuServerNumber || 0}</span>
        </div>
        <div class="item">
            <span>基地NPU总核数</span>
            <span>${computilityData?.baseNpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲NPU核数</span>
            <span>${computilityData?.baseIdlenpuScores || 0}</span>
        </div>
        <div class="item">
            <span>基地FP16总算力</span>
            <span>${computilityData?.baseFp16Computility || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲FP16算力</span>
            <span>${computilityData?.baseIdlefp16Computility || 0}</span>
        </div>
        <div class="item">
            <span>基地FP32总算力</span>
            <span>${computilityData?.baseFp32Computility || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲FP32算力</span>
            <span>${computilityData?.baseIdlefp32Computility || 0}</span>
        </div>
        <div class="item">
            <span>基地显存总量</span>
            <span>${computilityData?.baseGraphicsMemoryCapacity || 0}</span>
        </div>
        <div class="item">
            <span>基地空闲显存</span>
            <span>${computilityData?.baseIdlegraphicsMemoryCapacity || 0}</span>
        </div>
        </div>
    `;
};

4. 接口数据

  1. 把moke的接口数据也贴下,方便各位看代码
相关推荐
m0_7482309415 分钟前
Rust赋能前端: 纯血前端将 Table 导出 Excel
前端·rust·excel
qq_5895681023 分钟前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
黑客老陈1 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安1 小时前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
暴富的Tdy2 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js
neeef_se2 小时前
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
前端·vue.js·excel
m0_748235612 小时前
web 渗透学习指南——初学者防入狱篇
前端
℘团子এ2 小时前
js和html中,将Excel文件渲染在页面上
javascript·html·excel