Vue3+TS+ECharts5实现中国地图数据信息显示

news2024/12/25 0:38:07

1.引言

最近在做一个管理系统,主要技术栈使用的是Vue3+TS+Vite+ElementPlus,主要参考项目是yudao-ui-admin-vue3,其中用到ECharts5做数字大屏,展示中国地图相关信息,以此基础做一个分享,写下这篇文章。

"dependencies": {
    "@element-plus/icons-vue": "^2.1.0",
    "@kjgl77/datav-vue3": "^1.6.1",
    "@vueuse/core": "^10.2.1",
    "echarts": "^5.4.2",
    "echarts-wordcloud": "^2.1.0",
    "element-plus": "2.3.7",
    "vue": "3.3.4",
    "vue-i18n": "9.2.2",
    "vue-router": "^4.2.4",
    "vue-types": "^5.1.0",
    "vuedraggable": "^4.1.0"
  }

在读这篇文章之前,建议先读一下自适应大屏容器组件这篇文章。

2.封装ECharts组件

通常在实际项目中,需要用到ECharts图表的地方肯定很多,我们可以封装一个ECharts组件,方便使用,这里在 yudao-ui-admin-vue3基础上,添加了一个响应式变量,为了在引用ECharts父组件中获取到ECharts初始化实例,在地图中自动随机显示各省份数据的函数中使用。

为什么要添加这个响应式变量了?我实际使用中遇到的问题,如果把ECharts初始化实例赋值为响应式变量,会导致tooltip提示框在设置trigger: ‘axis’显示不出来,如果赋值为非响应式变量,父组件接受变量时数据为空,拿不到数据,所以我的解决办法是添加一个响应式变量,这样双方都可以满足。

<script lang="ts" setup>
import type { EChartsOption } from 'echarts'
import echarts from '@/plugins/echarts'
import { debounce } from 'lodash-es'
import 'echarts-wordcloud'
import { propTypes } from '@/utils/propTypes'
import { PropType } from 'vue'
import { useAppStore } from '@/store/modules/app'
import { isString } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'

defineOptions({ name: 'EChart' })

const { getPrefixCls, variables } = useDesign()

const prefixCls = getPrefixCls('echart')

const appStore = useAppStore()

const props = defineProps({
  options: {
    type: Object as PropType<EChartsOption>,
    required: true
  },
  width: propTypes.oneOfType([Number, String]).def('100%'),
  height: propTypes.oneOfType([Number, String]).def('100%')
})

const isDark = computed(() => appStore.getIsDark)

const theme = computed(() => {
  const echartTheme: boolean | string = unref(isDark) ? true : 'auto'

  return echartTheme
})

const options = computed(() => {
  return Object.assign(props.options, {
    darkMode: unref(theme)
  })
})

const elRef = ref<ElRef>()

let echartRef: Nullable<echarts.ECharts> = null
/**********************添加的响应式变量******************/
const eChart = ref()

const contentEl = ref<Element>()

const styles = computed(() => {
  const width = isString(props.width) ? props.width : `${props.width}px`
  const height = isString(props.height) ? props.height : `${props.height}px`

  return {
    width,
    height
  }
})

const initChart = () => {
  if (unref(elRef) && props.options) {
    echartRef = echarts.init(unref(elRef) as HTMLElement)
    echartRef?.setOption(unref(options))
    /**********************初始化后再赋值******************/
    eChart.value = echartRef
  }
}

watch(
  () => options.value,
  (options) => {
    if (echartRef) {
      echartRef?.setOption(options)
    }
  },
  {
    deep: true
  }
)

const resizeHandler = debounce(() => {
  if (echartRef) {
    echartRef.resize()
  }
}, 100)

const contentResizeHandler = async (e: TransitionEvent) => {
  if (e.propertyName === 'width') {
    resizeHandler()
  }
}

onMounted(() => {
  initChart()

  window.addEventListener('resize', resizeHandler)

  contentEl.value = document.getElementsByClassName(`${variables.namespace}-layout-content`)[0]
  unref(contentEl) &&
    (unref(contentEl) as Element).addEventListener('transitionend', contentResizeHandler)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', resizeHandler)
  unref(contentEl) &&
    (unref(contentEl) as Element).removeEventListener('transitionend', contentResizeHandler)
})

onActivated(() => {
  if (echartRef) {
    echartRef.resize()
  }
})

defineExpose({ eChart })
</script>

<template>
  <div ref="elRef" :class="[$attrs.class, prefixCls]" :style="styles"></div>
</template>

3.数据的准备

数据主要分为ECharts5需要的中国地图数据,需要显示的自定义数据,以及各个省份的中心经纬度数据。

1.地图数据。由于ECharts5地图不能直接引入,需要自己下载JSON数据,然后引入。地图数据下载地址为阿里云数据可视化平台,下载JSON数据,可根据自己的需要对南海诸岛的数据做编辑。数据下载后,放入asserts目录中,引入。

2.自定义显示数据。自定义显示数据就是想要在地图上显示的信息,当鼠标点击某个省份后,tooltip显示框显示的数据内容。本地中,显示的数据为各个省份合同数以及合同金额,如下图所示。

数据格式为:

interface digitalScreenDataType {
  name: string
  value: number
}
interface contractInfoForFirstArea {
  name: string
  contractInfoByFirstArea: digitalScreenDataType[]
}

数据内容举例:

[
    {
      name: '北京市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.9923 },
        { name: '合同总数', value: 51 }
      ]
    },
    {
      name: '天津市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 170.2683 },
        { name: '合同总数', value: 30790 }
      ]
    }
]

3.各个省份的中心经纬度数据。此数据主要为了显示各省份的中心点,利用的ECharts的配置,可以让中心点具有不同的显示效果。ECharts文档传送门。

数据定义:

const geoCodeMap = [
  { name: '北京市', delay: 63, lossPercent: 2, value: [119.337634104, 26.0911937119] },
  { name: '天津市', delay: 63, lossPercent: 2, value: [117.190182, 39.125596] },
  { name: '河北省', delay: 63, lossPercent: 2, value: [114.502461, 38.045474] },
  { name: '山西省', delay: 63, lossPercent: 2, value: [112.549248, 37.857014] },
  { name: '内蒙古自治区', delay: 63, lossPercent: 2, value: [111.670801, 40.818311] },
  { name: '辽宁省', delay: 63, lossPercent: 2, value: [123.429096, 41.796767] },
  { name: '吉林省', delay: 63, lossPercent: 2, value: [125.3245, 43.886841] },
  { name: '黑龙江省', delay: 63, lossPercent: 2, value: [126.642464, 45.756967] },
  { name: '上海市', delay: 63, lossPercent: 2, value: [121.487899486, 31.24916171] },
  { name: '江苏省', delay: 63, lossPercent: 2, value: [118.767413, 32.041544] },
  { name: '浙江省', delay: 63, lossPercent: 2, value: [120.153576, 30.287459] },
  { name: '安徽省', delay: 63, lossPercent: 2, value: [117.283042, 31.86119] },
  { name: '福建省', delay: 63, lossPercent: 2, value: [119.306239, 26.075302] },
  { name: '江西省', delay: 63, lossPercent: 2, value: [115.892151, 28.676493] },
  { name: '山东省', delay: 63, lossPercent: 2, value: [117.000923, 36.675807] },
  { name: '河南省', delay: 63, lossPercent: 2, value: [113.665412, 34.757975] },
  { name: '湖北省', delay: 63, lossPercent: 2, value: [114.298572, 30.584355] },
  { name: '湖南省', delay: 63, lossPercent: 2, value: [112.982279, 28.19409] },
  { name: '广东省', delay: 63, lossPercent: 2, value: [113.280637, 23.125178] },
  { name: '广西壮族自治区', delay: 63, lossPercent: 2, value: [108.320004, 22.82402] },
  { name: '海南省', delay: 63, lossPercent: 2, value: [110.33119, 20.031971] },
  { name: '重庆市', delay: 63, lossPercent: 2, value: [106.504962, 29.533155] },
  { name: '四川省', delay: 63, lossPercent: 2, value: [104.065735, 30.659462] },
  { name: '贵州省', delay: 63, lossPercent: 2, value: [106.713478, 26.578343] },
  { name: '云南省', delay: 63, lossPercent: 2, value: [102.712251, 25.040609] },
  { name: '西藏自治区', delay: 63, lossPercent: 2, value: [91.132212, 29.660361] },
  { name: '陕西省', delay: 63, lossPercent: 2, value: [108.948024, 34.263161] },
  { name: '甘肃省', delay: 63, lossPercent: 2, value: [103.823557, 36.058039] },
  { name: '青海省', delay: 63, lossPercent: 2, value: [96.07, 36.62] },
  { name: '宁夏回族自治区', delay: 63, lossPercent: 2, value: [106.278179, 38.46637] },
  { name: '新疆维吾尔自治区', delay: 63, lossPercent: 2, value: [87.617733, 43.792818] },
  { name: '台湾省', delay: 63, lossPercent: 2, value: [121.509062, 25.044332] },
  { name: '香港特别行政区', delay: 63, lossPercent: 2, value: [114.173355, 22.320048] },
  { name: '澳门特别行政区', delay: 63, lossPercent: 2, value: [113.54909, 22.198951] }
]

配置项:

{
      type: 'effectScatter',
      coordinateSystem: 'geo',
      symbolSize: 7,
      effectType: 'ripple',
      legendHoverLink: false,
      showEffectOn: 'render',
      rippleEffect: {
        period: 4,
        scale: 2.5,
        brushType: 'stroke'
      },
      zlevel: 1,
      itemStyle: {
        color: '#99FBFE',
        shadowBlur: 5,
        shadowColor: '#fff'
      },
      data: geoCodeMap
    }

4.地图展示组件

/** * @LeftTop.vue * @author: zgr * @createTime: 2023/9/25 */

<template>
  <EChart :options="options" ref="chinaMapRef" />
</template>

<script lang="ts" setup>

interface digitalScreenDataType {
  name: string
  value: number
}
interface contractInfoForFirstArea {
  name: string
  contractInfoByFirstArea: digitalScreenDataType[]
}


import * as echarts from 'echarts'
import chinaData from '@/assets/map/china.json'
echarts.registerMap('china', chinaData)


defineOptions({ name: 'ContractMap' })
//计时器
const timer = reactive({
  //地图动态显示数据
  mapIntervalTimer: null
})
const geoCodeMap = [
  { name: '北京市', delay: 63, lossPercent: 2, value: [119.337634104, 26.0911937119] },
  { name: '天津市', delay: 63, lossPercent: 2, value: [117.190182, 39.125596] },
  { name: '河北省', delay: 63, lossPercent: 2, value: [114.502461, 38.045474] },
  { name: '山西省', delay: 63, lossPercent: 2, value: [112.549248, 37.857014] },
  { name: '内蒙古自治区', delay: 63, lossPercent: 2, value: [111.670801, 40.818311] },
  { name: '辽宁省', delay: 63, lossPercent: 2, value: [123.429096, 41.796767] },
  { name: '吉林省', delay: 63, lossPercent: 2, value: [125.3245, 43.886841] },
  { name: '黑龙江省', delay: 63, lossPercent: 2, value: [126.642464, 45.756967] },
  { name: '上海市', delay: 63, lossPercent: 2, value: [121.487899486, 31.24916171] },
  { name: '江苏省', delay: 63, lossPercent: 2, value: [118.767413, 32.041544] },
  { name: '浙江省', delay: 63, lossPercent: 2, value: [120.153576, 30.287459] },
  { name: '安徽省', delay: 63, lossPercent: 2, value: [117.283042, 31.86119] },
  { name: '福建省', delay: 63, lossPercent: 2, value: [119.306239, 26.075302] },
  { name: '江西省', delay: 63, lossPercent: 2, value: [115.892151, 28.676493] },
  { name: '山东省', delay: 63, lossPercent: 2, value: [117.000923, 36.675807] },
  { name: '河南省', delay: 63, lossPercent: 2, value: [113.665412, 34.757975] },
  { name: '湖北省', delay: 63, lossPercent: 2, value: [114.298572, 30.584355] },
  { name: '湖南省', delay: 63, lossPercent: 2, value: [112.982279, 28.19409] },
  { name: '广东省', delay: 63, lossPercent: 2, value: [113.280637, 23.125178] },
  { name: '广西壮族自治区', delay: 63, lossPercent: 2, value: [108.320004, 22.82402] },
  { name: '海南省', delay: 63, lossPercent: 2, value: [110.33119, 20.031971] },
  { name: '重庆市', delay: 63, lossPercent: 2, value: [106.504962, 29.533155] },
  { name: '四川省', delay: 63, lossPercent: 2, value: [104.065735, 30.659462] },
  { name: '贵州省', delay: 63, lossPercent: 2, value: [106.713478, 26.578343] },
  { name: '云南省', delay: 63, lossPercent: 2, value: [102.712251, 25.040609] },
  { name: '西藏自治区', delay: 63, lossPercent: 2, value: [91.132212, 29.660361] },
  { name: '陕西省', delay: 63, lossPercent: 2, value: [108.948024, 34.263161] },
  { name: '甘肃省', delay: 63, lossPercent: 2, value: [103.823557, 36.058039] },
  { name: '青海省', delay: 63, lossPercent: 2, value: [96.07, 36.62] },
  { name: '宁夏回族自治区', delay: 63, lossPercent: 2, value: [106.278179, 38.46637] },
  { name: '新疆维吾尔自治区', delay: 63, lossPercent: 2, value: [87.617733, 43.792818] },
  { name: '台湾省', delay: 63, lossPercent: 2, value: [121.509062, 25.044332] },
  { name: '香港特别行政区', delay: 63, lossPercent: 2, value: [114.173355, 22.320048] },
  { name: '澳门特别行政区', delay: 63, lossPercent: 2, value: [113.54909, 22.198951] }
]
let preSelectMapIndex = 0
const dataList = ref<contractInfoForFirstArea[]>([])
const options = reactive<echarts.EChartsOption>({
  showLegendSymbol: false,
  tooltip: {
    trigger: 'item',
    //是否显示提示框组件
    show: true,
    backgroundColor: 'rgba(0,0,55,0.4)',
    textStyle: {
      color: 'white',
      fontSize: 14,
      lineHeight: 20
    },
    // 如果需要自定义 tooltip样式,需要使用formatter
    formatter: function (params) {
      let toolTipHtml = ''
      let data = dataList.value
      for (let i = 0; i < data.length; i++) {
        if (params.name === data[i].name) {
          toolTipHtml += data[i].name + ':<br>'
          for (let j = 0; j < data[i].contractInfoByFirstArea.length; j++) {
            toolTipHtml +=
              data[i].contractInfoByFirstArea[j].name +
              ':' +
              data[i].contractInfoByFirstArea[j].value +
              '<br>'
          }
        }
      }
      return toolTipHtml
    }
  },
  visualMap: {
    min: 0,
    max: 800,
    show: false,
    seriesIndex: 0,
    // 颜色
    inRange: {
      color: ['rgba(41,166,206, .5)', 'rgba(69,117,245, .9)']
    }
  },
  // 底部背景
  geo: {
    show: true,
    aspectScale: 0.85, //长宽比
    zoom: 1.6,
    top: '30%',
    left: '25%',
    map: 'china',
    roam: false,
    itemStyle: {
      areaColor: 'rgba(0,0,0,0)',
      shadowColor: 'rgba(138,181,218,0.8)',
      borderColor: '#232652',
      borderWidth: 2
    },
    emphasis: {
      itemStyle: {
        areaColor: '#00aeef',
        shadowColor: 'rgba(138,181,218,0.8)'
      }
    }
  },
  series: [
    {
      name: '',
      type: 'map',
      aspectScale: 0.85, //长宽比
      zoom: 1.6,
      map: 'china', // 自定义扩展图表类型
      top: '30%',
      left: '25%',
      itemStyle: {
        color: 'red',
        areaColor: 'rgba(19,54,162, .5)',
        borderColor: 'rgba(0,242,252,.3)',
        borderWidth: 1,
        shadowBlur: 7,
        shadowColor: '#00f2fc'
      },
      emphasis: {
        itemStyle: {
          areaColor: '#4f7fff',
          borderColor: 'rgba(0,242,252,.6)',
          borderWidth: 2,
          shadowBlur: 10,
          shadowColor: '#00f2fc'
        }
      },
      label: {
        formatter: (params) => `${params.name}`,
        show: true,
        position: 'insideRight',
        fontSize: 12,
        color: '#efefef'
      },
      data: [] as contractInfoForFirstArea[]
    },
    {
      type: 'effectScatter',
      coordinateSystem: 'geo',
      symbolSize: 7,
      effectType: 'ripple',
      legendHoverLink: false,
      showEffectOn: 'render',
      rippleEffect: {
        period: 4,
        scale: 2.5,
        brushType: 'stroke'
      },
      zlevel: 1,
      itemStyle: {
        color: '#99FBFE',
        shadowBlur: 5,
        shadowColor: '#fff'
      },
      data: geoCodeMap
    }
  ]
})
const getData = async () => {
  let resData: contractInfoForFirstArea[] = [
    {
      name: '北京市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.9923 },
        { name: '合同总数', value: 51 }
      ]
    },
    {
      name: '天津市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 170.2683 },
        { name: '合同总数', value: 30790 }
      ]
    },
    {
      name: '上海市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.2098 },
        { name: '合同总数', value: 5 }
      ]
    },
    {
      name: '重庆市',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 4.5777 },
        { name: '合同总数', value: 144 }
      ]
    },
    {
      name: '新疆维吾尔自治区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 2.5839 },
        { name: '合同总数', value: 78 }
      ]
    },
    {
      name: '西藏自治区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.2476 },
        { name: '合同总数', value: 14 }
      ]
    },
    {
      name: '宁夏回族自治区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 1.3043 },
        { name: '合同总数', value: 353 }
      ]
    },
    {
      name: '内蒙古自治区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 4.4069 },
        { name: '合同总数', value: 256 }
      ]
    },
    {
      name: '广西壮族自治区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.9392 },
        { name: '合同总数', value: 47 }
      ]
    },
    {
      name: '黑龙江省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 1.5711 },
        { name: '合同总数', value: 53 }
      ]
    },
    {
      name: '吉林省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 5.3852 },
        { name: '合同总数', value: 157 }
      ]
    },
    {
      name: '辽宁省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 5.1029 },
        { name: '合同总数', value: 193 }
      ]
    },
    {
      name: '河北省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 17.9545 },
        { name: '合同总数', value: 1101 }
      ]
    },
    {
      name: '山东省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 9.7 },
        { name: '合同总数', value: 568 }
      ]
    },
    {
      name: '江苏省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 6.6828 },
        { name: '合同总数', value: 239 }
      ]
    },
    {
      name: '安徽省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 7.2328 },
        { name: '合同总数', value: 260 }
      ]
    },
    {
      name: '浙江省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 7.7085 },
        { name: '合同总数', value: 309 }
      ]
    },
    {
      name: '福建省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 3.15 },
        { name: '合同总数', value: 241 }
      ]
    },
    {
      name: '广东省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 28.461 },
        { name: '合同总数', value: 1102 }
      ]
    },
    {
      name: '海南省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 8.5549 },
        { name: '合同总数', value: 423 }
      ]
    },
    {
      name: '云南省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 5.5561 },
        { name: '合同总数', value: 422 }
      ]
    },
    {
      name: '贵州省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 2.8905 },
        { name: '合同总数', value: 82 }
      ]
    },
    {
      name: '四川省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 10.9661 },
        { name: '合同总数', value: 409 }
      ]
    },
    {
      name: '湖南省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 3.0104 },
        { name: '合同总数', value: 144 }
      ]
    },
    {
      name: '湖北省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 3.7586 },
        { name: '合同总数', value: 157 }
      ]
    },
    {
      name: '河南省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 8.2312 },
        { name: '合同总数', value: 230 }
      ]
    },
    {
      name: '山西省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 6.1501 },
        { name: '合同总数', value: 322 }
      ]
    },
    {
      name: '陕西省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 3.265 },
        { name: '合同总数', value: 133 }
      ]
    },
    {
      name: '甘肃省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 1.4853 },
        { name: '合同总数', value: 58 }
      ]
    },
    {
      name: '青海省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 1.2578 },
        { name: '合同总数', value: 30 }
      ]
    },
    {
      name: '江西省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 2.8155 },
        { name: '合同总数', value: 67 }
      ]
    },
    {
      name: '台湾省',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0.0032 },
        { name: '合同总数', value: 2 }
      ]
    },
    {
      name: '香港特别行政区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0 },
        { name: '合同总数', value: 0 }
      ]
    },
    {
      name: '澳门特别行政区',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0 },
        { name: '合同总数', value: 0 }
      ]
    },
    {
      name: '南海诸岛',
      contractInfoByFirstArea: [
        { name: '合同总额(亿)', value: 0 },
        { name: '合同总数', value: 0 }
      ]
    }
  ]

  dataList.value = resData
  options.series[0].data = resData
}

// 重新随机选中地图区域
const reSelectMapRandomArea = () => {
  const length = 34
  nextTick(() => {
    try {
      const map = chinaMapRef.value.eChart
      let index = Math.floor(Math.random() * length)
      while (index === preSelectMapIndex || index >= length) {
        index = Math.floor(Math.random() * length)
      }
      map.dispatchAction({
        type: 'unselect',
        seriesIndex: 0,
        dataIndex: preSelectMapIndex
      })
      map.dispatchAction({
        type: 'showTip',
        seriesIndex: 0,
        dataIndex: index
      })
      map.dispatchAction({
        type: 'select',
        seriesIndex: 0,
        dataIndex: index
      })
      preSelectMapIndex = index
    } catch (error) {
      console.log('2345' + error)
    }
  })
}
const chinaMapRef = ref()
const handleMapRandomSelect = () => {
  nextTick(() => {
    try {
      const map = chinaMapRef.value.eChart
      setTimeout(() => {
        reSelectMapRandomArea()
      }, 0)
      // 移入区域,清除定时器、取消之前选中并选中当前
      map.on('mouseover', function (params) {
        clearInterval(timer.mapIntervalTimer)
        map.dispatchAction({
          type: 'unselect',
          seriesIndex: 0,
          dataIndex: preSelectMapIndex
        })
        map.dispatchAction({
          type: 'select',
          seriesIndex: 0,
          dataIndex: params.dataIndex
        })
        preSelectMapIndex = params.dataIndex
      })
      // 移出区域重新随机选中地图区域,并开启定时器
      map.on('globalout', function () {
        reSelectMapRandomArea()
        startInterval()
      })
      startInterval()
    } catch (error) {
      console.log('134' + error)
    }
  })
}
// 开启定时器
const startInterval = () => {
  // 应通过接口获取配置时间,暂时写死5s
  const time = 2000
  if (timer.mapIntervalTimer !== null) {
    clearInterval(timer.mapIntervalTimer)
  }
  timer.mapIntervalTimer = setInterval(() => {
    reSelectMapRandomArea()
  }, time)
}

//去除定时器
const clearData = () => {
  if (timer.mapIntervalTimer) {
    clearInterval(timer.mapIntervalTimer)
    timer.mapIntervalTimer = null
  }
}

onMounted(() => {
  getData()
  handleMapRandomSelect()
})

onUnmounted(() => {
  clearData()
})
</script>

<style scoped></style>

几个需要说明的地方:

1.option配置中的显示数据。本例中,数据直接写死赋值,在实际使用中,我们可能是从后端异步拉取数据然后再显示,这就会有一个问题,组件加载完毕,数据却还没有获取完毕。本人在实际项目的办法是初始化一个定时器,1秒钟获取一次数据,如果加载到数据就销毁定时器,继续赋值给option中的数据。

const getData = async () => {
  let resData: contractInfoForFirstArea[] = digitalScreenStore.getContractInfoForFirstArea
  if (resData.length > 0 && timer.initDataTimer !== null) {
    // 清除多次执行定时器
    clearInterval(Number(timer.initDataTimer))
    timer.initDataTimer = null
  }
  dataList.value = resData
  options.series[0].data = resData
}


const getInitDataTimer = () => {
  timer.initDataTimer = setInterval(getData, 1000)
}

onMounted(() => {
  getInitDataTimer()
  getData()
})

2.tooltip中的formatter函数。如果简单的字符串满足不了显示数据的要求,可以自定义函数,返回一段自定义HTML,显示对应数据。

3.自动随机选择省份区域,并显示tooltip数据。主要为三个函数,handleMapRandomSelect,reSelectMapRandomArea,startInterval,最初引用链接为koi-screen Vue2版,ECharts5的配置也有一些变化,所以改进为现在的Vue3+ECharts5版。

5.总结

本篇文章简单介绍了ECharts组件的封装,以及地图组件的封装,大概描述了实际项目中遇到的问题以及自己的一些解决办法,行文比较简单概括,所给代码并不能达到文章开始图片效果,对于一些问题可能还不是能很好的理解,欢迎批评指正,一起探讨交流进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1059570.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

解决ASP.NET Core的中间件无法读取Response.Body的问题

概要 本文主要介绍如何在ASP.NET Core的中间件中&#xff0c;读取Response.Body的方法&#xff0c;以便于我们实现更多的定制化开发。本文介绍的方法适用于.Net 3.1 和 .Net 6。 代码和实现 现象解释 首先我们尝试在自定义中间件中直接读取Response.Body&#xff0c;代码如…

Appleid苹果账号自动解锁改密(自动解锁二验改密码)

目前该项目能实现以下功能&#xff1a; 多用户使用&#xff0c;权限控制多账号管理账号分享页&#xff0c;支持设置密码、有效期、自定义HTML内容自动解锁与关闭二步验证自动/定时修改密码自动删除Apple ID中的设备代理池与Selenium集群&#xff0c;提高解锁成功率允许手动触发…

先输入列,再输入行

想要的表格行数和列数是 5 行 5 列&#xff0c;以下是相应的代码实现&#xff1a; # 定义表格行数和列数 rows 5 cols 5# 创建一个二维列表作为表格 table [[ for j in range(cols)] for i in range(rows)]print("请输入表格数据&#xff1a;")while True:# 获取…

Python无废话-办公自动化Excel读取操作

openpyxl模块介绍 openpyxl是一个用于处理Excel文件的Python库,用于读取/写入Excel2010 xlsx/xlsm/xltx/xltm文件(不支持xls格式)。通过使用openpyxl库&#xff0c;可 以轻松地在Python程序中实现对Excel文件的操作。 openpyxl 安装 方式1&#xff1a;使用pip 命令安装&…

操作系统学习笔记1

文章目录 1、OS的一个宏观比喻2、OS的目的和功能3、OS的发展4、OS的运行机制5、OS的特征6、OS的体系结构 参考视频&#xff1a;操作系统 1、OS的一个宏观比喻 2、OS的目的和功能 3、OS的发展 4、OS的运行机制 中断、系统调用、异常。 5、OS的特征 6、OS的体系结构

【逐步剖C++】-第二章-C++类和对象(下)

前言&#xff1a;本文是对类和对象知识点的最后一篇总结&#xff0c;前两篇的链接如下&#xff1a; 【逐步剖C】-第二章-C类和对象&#xff08;上&#xff09; 【逐步剖C】-第二章-C类和对象&#xff08;中&#xff09; 这三篇加起来就是笔者学习在类和对象中的所有总结了&…

计算机网络网络层、应用层、数据链路层协议详解

目录 一、计算机网络 二、网络层 三、应用层 四、数据链路层 一、计算机网络 计算机网络是将多台计算机和其他网络设备通过通信链路连接起来&#xff0c;以实现数据交换和资源共享的系统。它是现代信息社会的基础设施之一&#xff0c;为人们提供了快速、可靠、安全的数据传…

学校项目培训之Carla仿真平台之Carla学习内容

一、Blender Blender入门&#xff1a;https://www.bilibili.com/video/BV1fb4y1e7PD/ Blender导入骨骼&#xff1a;https://www.bilibili.com/video/BV1hc41157nL 做一个车&#xff1a;https://www.bilibili.com/video/BV1hY411q7w2 二、Roadrunner RoadRunner Scenario…

Flink状态管理与检查点机制

1.状态分类 相对于其他流计算框架,Flink 一个比较重要的特性就是其支持有状态计算。即你可以将中间的计算结果进行保存,并提供给后续的计算使用: 具体而言,Flink 又将状态 (State) 分为 Keyed State 与 Operator State: 1.1 算子状态 算子状态 (Operator State):顾名思义…

计组—— I/O系统

&#x1f4d5;&#xff1a;参考王道课件 目录 一、I/O系统的基本概念 1.什么是“I/O”&#xff1f; ​编辑2.主机如何和I/O设备进行交互&#xff1f; 3.I/O控制方式 &#xff08;1&#xff09;程序查询方式 &#xff08;2&#xff09;程序中断方式 &#xff08;3&#x…

【MATLAB源码-第41期】基于压缩感知算法的OFDM系统信道估计和LS算法对比仿真。

操作环境&#xff1a; MATLAB 2013b 1、算法描述 压缩感知&#xff08;Compressed Sensing, CS&#xff09;是一种从稀疏或可压缩信号中重构完整信号的数学理论和技术。下面详细介绍压缩感知和它在OFDM信道估计中的应用。 1. 压缩感知基本概念 在传统采样理论中&#xff0…

数字电路逻辑与设计 之循环码和 移存码

有发现错误的能力&#xff0c;不能纠正 只能检查单次的错误&#xff0c;不能完全抗干扰 可以按照上面的方法来循环构造 移存码可以通过前推后推来实现

pytorch_神经网络构建1

文章目录 pytorch简介神经网络基础分类问题分析:逻辑回归模型逻辑回归实现多层神经网络多层网络搭建保存模型 pytorch简介 为什么神经网络要自定义数据类型torch.tensor? tensor可以放在gpu上训练,支持自动求导,方便快速训练,同时支持numpy的运算,是加强版,numpy不支持这些 为…

C++项目:【高并发内存池】

文章目录 一、项目介绍 二、什么是内存池 1.池化技术 2.内存池 3.内存池主要解决的问题 4.malloc 三、定长的内存池 四、高并发内存池整体框架设计 1.高并发内存池--thread cache 1.1申请内存&#xff1a; 1.2释放内存&#xff1a; 1.3用TLS实现thread cache无锁访…

GD32F10 串口通信

1. 什么是通信 通信&#xff0c;指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递&#xff0c;从广义上指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法&#xff0c;任意媒质&#xff0c;将信息从某方准确安全地传送到另方。通信双方如果想正确传输…

SystemUI导航栏

SystemUI导航栏 1、系统中参数项1.1 相关开关属性2.2 属性设置代码 2、设置中设置“三按钮”导航更新流程2.1 属性资源覆盖叠加2.2 SystemUI导航栏接收改变广播2.3 SystemUI导航栏布局更新2.4 时序图 android13-release 1、系统中参数项 1.1 相关开关属性 设置->系统->…

C++算法 —— 动态规划(9)完全背包问题

文章目录 1、动规思路简介2、完全背包【模板】3、零钱兑换4、零钱兑换Ⅱ5、完全平方数 背包问题需要读者先明白动态规划是什么&#xff0c;理解动规的思路&#xff0c;并不能给刚接触动规的人学习。所以最好是看了之前的动规博客&#xff0c;以及01背包博客&#xff0c;才能看完…

学习C++语言可以适用于哪些方面

学习C可以让你具备开发各种类型软件和系统的能力&#xff0c;它是一种通用的、高性能的编程语言。以下是学习C的一些用途和应用领域&#xff1a; 系统开发&#xff1a;C被广泛用于操作系统、驱动程序和嵌入式系统的开发。通过学习C&#xff0c;你可以编写底层的系统代码&#x…

java大富翁

一、 概述 Java Swing大富翁游戏是一个经典的大富翁桌面游戏的简单实现&#xff0c;使用Java Swing库创建。该游戏允许玩家在一个虚拟棋盘上掷骰子&#xff0c;购买和升级属性&#xff0c;赚取租金和尽量丰富自己。这个文档说明将介绍如何安装和运行游戏&#xff0c;以及游戏规…

【C++】C++11——右值引用和移动语义、左值引用和右值引用、右值引用使用场景和意义、完美转发、新的类功能

文章目录 C115.右值引用和移动语义5.1左值引用和右值引用5.2左值引用与右值引用比较5.3右值引用使用场景和意义5.4右值引用引用左值及其一些更深入的使用场景分析5.5完美转发 6.新的类功能 C11 5.右值引用和移动语义 右值引用是C11引入的一个新特性&#xff0c;用于支持移动语义…