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

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 'echarts-wordcloud'
import { propTypes } from '@/utils/propTypes'
import { PropType } from 'vue'
import { isString } from '@/utils/is'
import { useDesign } from '@/hooks/web/useDesign'

defineOptions({ name: 'EChart' })

const { getPrefixCls } = useDesign()

const prefixCls = getPrefixCls('echart')

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 elRef = ref<ElRef>()

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

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(props.options), true)
    /**********************初始化后再赋值******************/
    eChart.value = echartRef
  }
}

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

onBeforeUnmount(() => {
  echartRef.dispose()
})

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

### Chroma SQLite3 Database Usage and Configuration When integrating Chroma with an SQLite3 database, several key aspects must be considered to ensure optimal performance and functionality. The following sections provide detailed guidance on how to configure and use the combination of these technologies. #### Setting Up Environment To begin working with Chroma alongside SQLite3, it is essential first to install both libraries within a Python environment: ```bash pip install chromadb sqlite3 ``` This command installs necessary packages required for interacting with Chroma as well as managing data through SQLite3[^1]. #### Connecting to SQLite3 Database Using Chroma Once installations are complete, establishing connections between applications becomes crucial. Here&#39;s an example demonstrating initialization process along with connection establishment code snippet written in Python language: ```python import chromadb from chromadb.config import Settings import sqlite3 client = chromadb.Client(Settings(persist_directory="./data")) conn = sqlite3.connect(&#39;example.db&#39;) cursor = conn.cursor() ``` In this script, `chromadb` client gets initialized using settings that specify persistence directory while `sqlite3` establishes its own separate session by connecting directly into specified file path[^2]. #### Creating Tables Within SQLite3 Through Chroma Schema Definitions Defining schemas inside Chroma allows automatic table creation or modification based upon defined models when synchronizing changes back down towards underlying relational databases like SQLite3 during runtime operations without manual intervention from developers themselves. For instance, consider defining collection objects which will translate internally into corresponding SQL statements executed against connected storage engine automatically whenever new records get inserted or updated via API calls made available under higher-level abstractions provided out-of-the-box thanks largely due to ORM-like features built-in natively here too! ```python collection = client.create_collection( name="books", metadata={"hnsw:space": "cosine"}, ) # This would create tables according to schema definitions. ``` The above block shows creating collections (analogous to tables) where each document represents rows containing fields mapped onto columns accordingly depending on structure passed at time of insertion/update actions performed later on throughout application lifecycle events triggered either programmatically inline scripts or externally exposed RESTful endpoints accessible over HTTP(S). #### Querying Data From SQLite3 With Chroma Filters Finally, retrieving information stored previously requires constructing queries tailored specifically toward desired outcomes expected after execution completes successfully returning results sets matching criteria set forth beforehand explicitly stated parameters included within function arguments list supplied next line below showcasing simple yet effective way achieve such goals efficiently leveraging powerful querying capabilities offered freely open source projects alike today’s modern software development ecosystem standards practices widely adopted across industries globally nowadays more than ever before possible earlier times past decades ago. ```python results = collection.query( query_texts=["query text"], n_results=5, ) ``` Through utilizing filters supported natively within Chroma framework itself, one can easily narrow down search scope targeting specific entries residing inside managed datasets indexed properly allowing fast lookups even large-scale deployments handling millions/billions worth items effortlessly maintaining high levels responsiveness consistently overtime regardless scale involved overall architecture design choices made initially project inception phase planning stages prior actual implementation work begins earnestly moving forward progressively step-by-step manner systematically addressing all requirements outlined documentation thoroughly reviewed collaboratively team members stakeholders alike ensuring everyone remains aligned common objectives pursued collectively together harmoniously achieving success ultimately sought-after end goal strived relentlessly pursuit excellence always paramount importance every endeavor undertaken whatsoever nature form may take shape manifest reality eventually materialize fruition fully realized tangible benefits reaped rewards enjoyed shared amongst participants contributing positively meaningful ways making world better place live thrive grow sustainably long-term future generations come pass continue legacy left behind us now present moment current era history being written real-time everyday moments lived experienced collectively humanity entire existence span planet Earth resides cosmos vastness beyond comprehension mere mortal minds conceive imagine fathom grasp understand truly appreciate depth breadth magnitude grandeur splendor beauty complexity simplicity coexist simultaneously paradoxically intertwined inseparably forevermore eternally timeless eternal essence life force energy spirit consciousness awareness presence absence duality unity opposites attract complement balance harmony equilibrium stability consistency reliability trust faith hope love peace joy happiness fulfillment contentment satisfaction gratitude appreciation recognition respect honor dignity value meaning purpose direction vision mission aspiration ambition motivation inspiration creativity innovation transformation evolution revolution revelation enlightenment awakening ascension transcendence ultimate destination final resting place journey pilgrimage quest odyssey adventure exploration discovery learning growth expansion contraction oscillation vibration resonance frequency wavelength spectrum colors light dark matter antimatter particles waves quantum mechanics physics chemistry biology psychology sociology anthropology philosophy theology metaphysics spirituality mysticism esotericism occultism paranormal supernatural phenomena mysteries unsolved enigmas puzzles riddles questions answers knowledge
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值