Vue3.x使用Echarts绘制世界地图并进行定点

文章介绍了如何在Vue3.x项目中使用Echarts库来绘制世界地图,并根据经纬度数据在地图上定点。关键步骤包括导入Echarts和世界地图Geojson数据,初始化地图,以及设置定点坐标和样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue3.x使用Echarts绘制世界地图并进行定点

一、需求

  • 绘制世界地图并根据返回经纬度数据进行定点
  • 将定点数据展示在世界地图内

二、解决

<template>
    <div>
        ...
		<div id="worldgraph"></div>
    </div>
</template>

<script setup>
import * as echarts from 'echarts';
import worldData from '@/assets/json/world.json';
import { ref, onMounted, onUnmounted } from 'vue';

// 世界地图画布
const worldGraph = ref(null);

/* 挂载 */
onMounted(() => {
    initData()
})
/* 卸载 */
onUnmounted(() => {
  if (worldGraph.value) {
    worldGraph.value.dispose();
    worldGraph.value = null;
  }
});
/* 初始化IP画像数据 */
const initData = () => {
    if (worldGraph.value) {
        worldGraph.value.dispose();
        worldGraph.value = null;
    }
    const point = []
    // 添加美国坐标点
    point.push({
        name: '美国',
        value: [-97.822, 37.751 + 15], // +15使定点坐标位置正确
        type: 'iconData'
    })
    drawnWorldChart(point)
};
/* 绘制世界地图图谱 */
const drawnWorldChart = (point) => {
  if (!document.getElementById('ipprotrait-worldgraph')) {
    return;
  }
  echarts.registerMap('world', JSON.stringify(worldData));
  worldGraph.value = echarts.init(document.getElementById('ipprotrait-worldgraph'));
  let option = {
    grid: {
      width: '100%',
      height: '100%',
      left: '0%',
      right: '0%',
      bottom: '0%',
      containLabel: true
    },
    geo: {
      type: 'map',
      map: 'world',
      aspectScale: 0.85,
      emphasis: {
        label: {
          show: false
        },
        itemStyle: {
          areaColor: '#F6FBFF',
          borderColor: '#CEE0E7',
        }
      },
      zoom: 1.2,
      itemStyle: {
        areaColor: '#F6FBFF',
        borderColor: '#CEE0E7',
      },
    },
    series: [
      // 标记点
      {
        type: 'scatter',
        coordinateSystem: 'geo',
        symbolSize: 30,
        symbol: 'image://data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAKKADAAQAAAABAAAAKAAAAAB65masAAAE+ElEQVRYCbVYTWhUVxQ+b+a9mUk0hAhGDFiS2grusgpGMHFRaAQjAYm2G6lOEFQIXbiYhRQUF110UYpiSgMSN63GRYqLttiNP2gpgbitaWMpXdREsTTNZP7evH7fzWQySe59P9PJhce775zvfOe799177ryxpI7meV47wkYln/9Qksm3vYWFrDc/L7g7pLN27ixa7e28NwMzB8zXMH9hWdY8/VGaFQUMYduAvyium/FevJDivXsp98kTCtPSQKDEDx4UZ3AwZ3V1icTjnwL4GYQuaQM0xtACIa7Ty+d/kDdv3ipcv55yHz3S0JlN8UOHJHHhQk7a2v6wksn3IfJ3M3rNE0ogxPVKqfSd+/Rpc/7qVQevbY0hSi+ZlOSlS8V4b29WbHsAIn8KCg8UCHFdEDdTunu3pTA2FgsiDONPnDtXto8fX4TI7qCZ9E3INYfX+j1nrlHiOIDCjRsxcnLJMIffoHwFIvAi15x6rX4sdfgUJ7hVDp94o0CMrJ27tXDtWqruNeeTmJyKmxVhpWxp0UaBQI+ylLiPH2sDG2EkN3Mwl4nPLBBFmHXOFNgou8rBgm9o2l2MKX8H+Nnl4WFjEa7li3V3i3PypMT27VPm8vPnUrx9W8rPntXCtH0W86bJSfrexY7+dSPI3mioPPfg6MrihGg2+Ktm5/RpsU+dEpBXbahzEjtwQEq3bknx5s2qXdfhKYQrC6E98G8SaHrFu03HV20SztxGcat+CqaPmKDGcxxttw7nJ1Ad/LqgVRtfa+3MrdpX7/QRE9QwGcwVSaCNErP2zgwZVtecwa3MYTCVXNrlZprB11ZbW9EvcSN9lVyvdZwmgbOxzk4dfp2NuzWohcFUcs3quEwCp2XHjiZpbdXFVG3FO3cEJan6vLFDH8uNb2MO5hKZ1uFMAn/DUfQq3sOdb27lmRlVSnQiaWOZCaqFKkc+v4ANtanEMLN2YQLsea47aR8+nHbv30+YJYqqcy4KsnPiRF2FGjkK4jiqUuvyGHcqZqAfu+vH7NCQLYuLutj/b2tpkeapqRI+Bd7DpDzQEZpeMevbA69U+tMeGNDFNcRGbuYwiWMSo0A68e3wOQptDiPkY2MbOMnNHH7EvgIR+JXV2rpsHznix1GXj5zkZg4/Al+BmPosFvDlRDqdw92PJ5oPXBXOyyqHT7SvwErcmGzfvmgfPepDE82luMCJqLGgyECBGGEes/eJc+ZMXrb5ft8E5Vrxg8NJpxWn4g6IChRYiR+3Eom5xNmzbgBfoJscluPMATgeCAYglECMtIT/Vz6KDw5asf37w/BqMYwlB7kUpxa13hhKIENA+DPOly+TmUx9ZQdlJZHJ5MlBrvUyzE+hBSqKeDxjdXQs2TjWojbGxDo6/kVNzUSJjSQQI/8HGybtjIy41t69ofMQyxjGKo7QkSHXYC0fEnxrlcsTqStXcpLw/R2xEgYMsYxhbC1XmH6kGawSOs4ovsL+Spw/H7iriSEWs2f8OK/yajp1CcRMLGH2hu1jx7x4X5+GdsVEHzHEqhgj0uyoSyDpkHBaYrGP+X+ftWfPpgy00UeMwm5ChDMYfw+GCxfxCoVvvJcvh5ZHRpKSy62EpVLSND6et3btmkKB/yAs15bg8MOW//P9Unr4sLDU3+/xYp82+rYkaVRSCOnyisW/CxMTZV7s0xaVZ0vxENSH75iiutBvVLL/APCb6OqC62Y+AAAAAElFTkSuQmCC',
        // rippleEffect: { // 坐标点动画
        //   period: 2,
        //   scale: 4,
        //   brushType: 'fill'
        // },
        label: {
          show: false,
        },
        data: point,
        // itemStyle: { // 坐标点颜色
        //   show: true,
        //   color: '#F53F3F',
        //   shadowColor: '#fff'
        // }
      }
    ]
  };
  worldGraph.value.setOption(option);
};
</script>
  • 最后效果图如下:
    在这里插入图片描述
### 错误原因分析 `this.dom.getContext is not a function` 这一错误通常发生在尝试初始化 ECharts 图表时,由于 DOM 元素未被正确获取或不符合 ECharts 初始化的要求所导致。具体来说: - **DOM 获取方式不当**:ECharts 要求通过原生 JavaScript 方法(如 `document.getElementById` 或 `document.querySelector`)来获取目标容器的 DOM 元素[^1]。 - **框架限制**:如果是在特定前端框架(如 Vue、React 或 UniApp)中使用 ECharts,则可能因为这些框架对 DOM 操作进行了封装,或者存在逻辑层与视图层分离的情况(如小程序架构),从而导致无法直接访问到原始 DOM 元素[^3]。 --- ### 解决方案 #### 方案 1: 使用正确的 DOM 获取方法 确保在调用 ECharts 的 `init` 方法前,已通过原生 DOM API 正确获取到了目标容器元素。例如,在纯 HTML 页面中可以这样操作: ```javascript const domElement = document.getElementById(&#39;main&#39;); // 替换为实际的 ID 名称 if (domElement) { const myChart = echarts.init(domElement); } ``` 注意:此处不能使用某些框架特有的选择器工具(如 jQuery 的 `$()` 或其他自定义函数)。必须严格遵循 ECharts 对 DOM 元素的需求。 --- #### 方案 2: 避免使用伪引用机制 当项目中有复杂的模板渲染流程时,可能会引入一些特殊的选择器语法(比如带有 `:ref` 属性绑定的方式)。这种情况下应改为直接指定具有唯一性的 CSS 选择器或 ID 来定位目标 div 元素[^2]。例如: ```html <div id="chart-container"></div> <script type="text/javascript"> var chartDiv = document.getElementById(&#39;chart-container&#39;); if (chartDiv) { let chartInstance = echarts.init(chartDiv); } </script> ``` 上述代码片段展示了如何利用标准的 `id` 字段作为锚定点完成图表实例化过程。 --- #### 方案 3: 处理跨平台环境下的兼容性问题 对于像 UniApp 这样的多端开发框架而言,其内部实现可能导致传统意义上的 DOM 结构不存在于运行环境中。因此需要采用专门设计用于此类场景下的替代品——例如 uCharts 插件。尽管如此仍需认识到两点局限之处: 1. 性能损耗不可避免; 2. 功能覆盖范围有限。 假如确实有必要坚持沿用官方版 ECharts 克服现有障碍的话,则可考虑借助 Web Components 技术构建独立组件加载策略;又或者是探索基于 Canvas API 手动绘制图形路径的可能性。 --- #### 示例代码展示 下面给出一段完整的示例程序供参考学习之用: ```javascript // 确保页面完全加载后再执行脚本 window.onload = function () { try { // 定位绘图区域 const containerNode = document.querySelector(&#39;#myChart&#39;); if (!containerNode || typeof containerNode !== &#39;object&#39;) throw new Error(&#39;Invalid node reference.&#39;); // 实例化图表对象 const instanceOfChart = echarts.init(containerNode); // 设置初始配置项显示数据 instanceOfChart.setOption({ title: { text: &#39;Sample Chart&#39; }, tooltip: {}, xAxis: { data: [&#39;A&#39;, &#39;B&#39;, &#39;C&#39;] }, yAxis: [], series: [{ name: &#39;&#39;, type: &#39;bar&#39;, data: [5, 20, 36]}], }); } catch(err){ console.error(`Error during initialization:${err.message}`); } }; ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值