vue中动态渲染echarts地图(svg)

本文介绍了如何在Vue应用中使用ECharts库,包括注册自定义SVG地图、动态获取和渲染地理坐标数据,以及使用keyframeAnimation和path动画。

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

1.首先查看官网示例

2.在vue中使用
 2.1注册自己的svg,

在methods,新建一个函数

.....
//导入自己的svg
 import senor from "@/assets/images/holeSenor.svg";
....
  createECharts() {

            let chartDom = document.getElementById("main");

            let myChart = echarts.init(chartDom);

            let option;

            const that = this;


           //重点注册
            $.get(senor, function (svg) {

                // 向 echarts 注册 SVG 字符串或解析过的 SVG DOM

                echarts.registerMap("senor", { svg: svg });

                option = {

                  //自己配置相应信息,查考官网

                };

                myChart.setOption(option);

            });

      },
2.2 根据左坐标信息,去渲染svg
 //官网参考代码
option = {
    tooltip: {},
    geo: {
      tooltip: {
        show: true
      },
      map: 'iceland_svg',
      roam: true
    },
    series: {
      type: 'custom',
      coordinateSystem: 'geo',
      geoIndex: 0,
      zlevel: 1,
      //坐标点位
      data: [
        [488.2358421078053, 459.70913833075736, ],
        [770.3415644319939, 757.9672194986475,],
        [1180.0329284196291, 743.6141808346214, ],
        [894.03790632245, 1188.1985153835008, ],
        [1372.98925630313, 477.3839988649537,],
        [1378.62251255796, 935.6708486282843,]
      ],
     // 渲染部分
      renderItem(params, api) {}}
    }
  };

但是我们需要动态去接受坐标,从而去渲染svg,故需在data中定义一个数组,去动态接受,完整代码如下:

<template>
    <div id="main"></div>
</template>
  
<script>
import { getHolePosition, } from "@/api/visualization";
import $ from 'jquery';
import * as echarts from 'echarts';
import senor from "@/assets/images/holeSenor.svg";

export default {
    data() {
        return {
            dataRef: [] // 用于存储孔位信息的数组
        };
    },
    methods: {
        getmap() {
            getHolePosition().then((res) => {
                this.dataRef = res.data
                this.$nextTick(() => {
                    this.createECharts();
                })
            });
        },
        createECharts() {
            let chartDom = document.getElementById("main");
            let myChart = echarts.init(chartDom);
            let option;
            const that = this;

            $.get(senor, function (svg) {
                // 首先向 echarts 注册 SVG 字符串或解析过的 SVG DOM
                echarts.registerMap("senor", { svg: svg });
                option = {
                    tooltip: {
                        trigger: 'item',
                        formatter: function (params) {
                            let formattedText =
                                '<b>X:</b> ' + params.value[0] +
                                '<b>,</b> ' +
                                '<b>Y:</b> ' + params.value[1] +
                                '<br>' +
                                '<b>设备名称:</b> ' + params.value[2];

                            return formattedText;
                        }
                    },
                    geo: {
                        tooltip: {

                            show: true
                        },

                        map: 'senor',
                        roam: true,
                    },
                    series: {
                        type: 'custom',
                        coordinateSystem: 'geo',
                        geoIndex: 0,
                        zlevel: 1,
                        encode: {
                            tooltip: [0, 1, 2]
                        },

                        data: that.dataRef,
                        renderItem(params, api) {
                            const coord = api.coord([
                                api.value(0, params.dataIndex) / 100,
                                api.value(1, params.dataIndex) / 100
                            ]);

                            const circles = [];
                            for (let i = 0; i < 5; i++) {
                                circles.push({
                                    type: 'circle',
                                    shape: {
                                        cx: 0,
                                        cy: 0,
                                        r: 30
                                    },
                                    style: {
                                        stroke: 'red',
                                        fill: 'none',
                                        lineWidth: 2
                                    },
                                    // Ripple animation
                                    keyframeAnimation: {
                                        duration: 4000,
                                        loop: true,
                                        delay: (-i / 4) * 4000,
                                        keyframes: [
                                            {
                                                percent: 0,
                                                scaleX: 0,
                                                scaleY: 0,
                                                style: {
                                                    opacity: 1
                                                }
                                            },
                                            {
                                                percent: 1,
                                                scaleX: 1,
                                                scaleY: 0.4,
                                                style: {
                                                    opacity: 0
                                                }
                                            }
                                        ]
                                    }
                                });
                            }
                            return {
                                type: 'group',
                                x: coord[0],
                                y: coord[1],
                                children: [
                                    ...circles,
                                    {
                                        type: 'path',
                                        shape: {
                                            d: 'M16 0c-5.523 0-10 4.477-10 10 0 10 10 22 10 22s10-12 10-22c0-5.523-4.477-10-10-10zM16 16c-3.314 0-6-2.686-6-6s2.686-6 6-6 6 2.686 6 6-2.686 6-6 6z',
                                            x: -10,
                                            y: -35,
                                            width: 20,
                                            height: 40
                                        },
                                        style: {
                                            fill: 'red'
                                        },
                                        // Jump animation.
                                        keyframeAnimation: {
                                            duration: 1000,
                                            loop: true,
                                            delay: Math.random() * 1000,
                                            keyframes: [
                                                {
                                                    y: -10,
                                                    percent: 0.5,
                                                    easing: 'cubicOut'
                                                },
                                                {
                                                    y: 0,
                                                    percent: 1,
                                                    easing: 'bounceOut'
                                                }
                                            ]
                                        }
                                    }
                                ]
                            };
                        }
                    },

                };
                myChart.setOption(option);
            });

        },

    },
    mounted() {
        this.getmap();
    }
};
</script>
<style scoped>
#main {
    position: absolute;
    top: 17%;
    left: 15%;
    width: 70%;
    height: 70%;
    background-color: rgba(0, 0, 0, 0);
}
</style>
  

这里有个容易错误的地方,函数层级嵌套太多,this指向可能会出现问题 ,故在这个函数里用that接受了this,再使用this.什么时,就替换成that.,即可

3.效果图

<think>好的,我现在需要帮助用户解决在Vue3中获取数据并动态渲染ECharts图表的问题。首先,我得回忆一下Vue3和ECharts结合使用的基本步骤,同时结合用户提供的引用内容来确保答案的准确性。 用户的问题是关于动态加载数据和渲染图表,所以首先应该考虑如何在Vue3组件中获取数据,通常是异步获取,比如从API获取数据。然后,数据获取之后如何更新ECharts的配置项,并重新渲染图表。同时,用户提供的引用中有几个关键点需要注意: 引用[3]提到在mounted钩子中使用定时器延迟初始化ECharts,可能是为了解决DOM未渲染完成的问题。但更好的做法可能是在nextTick中处理,或者确保DOM已经挂载后再初始化。 引用[5]指出在动态渲染地图时,this的指向问题,需要使用that来保存this的引用,避免在嵌套函数中丢失上下文。这在Vue3的setup语法中使用可能有所不同,因为Vue3的组合式API更推荐使用ref和reactive来管理状态,可能不需要用that,但需要注意作用域。 引用[4]提到了全局引入和按需引入ECharts的方式,用户可能需要按需引入以减少包体积,这里需要给出两种方式的示例,但用户的问题更关注动态渲染,所以可能需要侧重于数据获取后的配置更新。 接下来,步骤应该是: 1. 安装ECharts:用户需要先安装ECharts包,可能还需要安装Vue相关的集成库,但根据引用中的示例,用户可能更倾向于直接使用echarts.init方法。 2.Vue3组件中引入ECharts:按需引入还是全局引入,这里可以引用[4]中的方法,给出两种方式的示例,但用户的问题可能更适合按需引入,因为动态加载数据通常希望保持轻量。 3. 组件的挂载和初始化:在onMounted生命周期钩子中初始化图表,但需要注意DOM元素的引用是否正确。例如,使用ref来获取DOM节点,可能需要使用Vue3的ref和模板引用来获取DOM元素。 4. 获取数据并更新图表:使用异步方法(如axios或fetch)获取数据,然后在数据返回后更新图表的配置项,并调用setOption方法重新渲染图表。这里需要注意在数据加载完成前可能显示空白或加载状态,以及可能的错误处理。 5. 响应式更新:如果数据变化需要重新渲染图表,可能需要使用watch或watchEffect来监听数据变化,并触发图表的重新渲染。此时需要注意销毁旧实例,避免内存泄漏,或者在更新时正确清除旧图表。 6. 销毁图表实例:在组件卸载时,使用dispose方法销毁ECharts实例,防止内存泄漏。 此外,引用[5]提到动态渲染地图时可能需要处理SVG地图数据,这里可能需要额外的步骤来注册地图数据,例如使用echarts.registerMap方法。但用户的问题可能更关注通用图表,如柱状图或折线图,所以可能需要分情况说明。 另外,引用[3]中的定时器方法可能不是最佳实践,应该推荐使用nextTick或在确保DOM可用的情况下初始化图表,避免不可预测的延迟问题。 现在需要将这些步骤整理成一个清晰的示例,包括代码结构和关键点说明。例如,使用setup语法,在onMounted中初始化图表,使用async/await获取数据,然后更新配置。同时处理窗口resize事件,以确保图表自适应大小。 还需要考虑错误处理,比如数据获取失败时的反馈,以及ECharts实例是否已经创建的判断,避免重复初始化。 最后,生成相关问题,可能需要涉及性能优化、响应式数据处理、图表类型选择等。</think>### 在 Vue3 中获取数据并动态渲染 ECharts 图表的实现步骤 #### 1. 安装 ECharts 依赖 ```bash npm install echarts --save ``` #### 2. 创建基础组件结构 ```vue <template> <div ref="chartRef" style="width: 600px; height: 400px"></div> </template> <script setup> import { ref, onMounted, onBeforeUnmount } from 'vue'; import * as echarts from 'echarts'; const chartRef = ref(null); // 获取 DOM 引用 let chartInstance = null; // 存储 ECharts 实例 // 初始化图表 const initChart = async () => { if (!chartRef.value) return; // 异步获取数据 const data = await fetchData(); // 动态配置项 const option = { xAxis: { type: 'category', data: data.categories }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: data.values }] }; // 首次渲染或更新 if (!chartInstance) { chartInstance = echarts.init(chartRef.value); } chartInstance.setOption(option); }; // 模拟 API 请求 const fetchData = () => { return new Promise(resolve => { setTimeout(() => { resolve({ categories: ['A', 'B', 'C', 'D'], values: [120, 200, 150, 80] }); }, 1000); }); }; // 窗口自适应 const handleResize = () => { chartInstance?.resize(); }; onMounted(() => { initChart(); window.addEventListener('resize', handleResize); }); onBeforeUnmount(() => { window.removeEventListener('resize', handleResize); chartInstance?.dispose(); // 销毁实例[^3] }); </script> ``` #### 关键实现细节: 1. **DOM 引用处理** - 使用 `ref` 绑定容器元素,确保 DOM 已渲染后初始化图表[^3] - 避免直接使用 `setTimeout` 延迟,推荐在 `onMounted` 生命周期操作 2. **数据动态更新** - 通过 `async/await` 实现异步数据加载 - 数据变化时调用 `setOption` 更新图表(可结合 `watch` 监听数据变化) 3. **性能优化** - 添加窗口 `resize` 监听实现自适应[^3] - 组件卸载时销毁实例避免内存泄漏[^3] 4. **错误处理扩展** ```javascript const initChart = async () => { try { // ...原有逻辑 } catch (error) { console.error('图表初始化失败:', error); } }; ``` #### 示例效果 - 初始显示空白容器 - 1秒后动态渲染带数据的柱状图 - 窗口缩放时自动调整图表尺寸
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值