惊艳!四步在 Cesium 地球加载 Echarts 饼图,附完整代码与原理解析

389 阅读5分钟

各位掘友,大家好,我是 安大桃子。在当下数字化地图与地理信息蓬勃发展的浪潮里,WebGIS 技术成为关键力量。接下来,我将结合实际项目案例,为大家深度解析如何巧用 Vue、Cesium 以及相关 WebGIS 技术,攻克复杂地理数据可视化与交互难题,开启 WebGIS 开发 进阶之路

image.png

注意!本文全是干货,直接进入主题。在实际的数据可视化项目中,将 Echarts 丰富的图表样式与 Cesium 的 3D 地球场景相结合,能创造出极具直观性和吸引力的效果。今天就来分享如何在 Cesium 地球上添加 Echarts 饼图,仅需四步就能实现。

实现步骤

一、创建 canvas

这是承载 Echarts 饼图的基础容器,为后续的图表渲染提供空间。

二、渲染 Echarts 图表

将精心设计的饼图样式与数据填充至 canvas 中,呈现出直观的数据可视化效果。

三、创建 Primitive

在 Cesium 场景中构建用于承载饼图的基础图形单元,为下一步的贴图做准备。

四、将 canvas 作为材质贴到 Primitive 上

让渲染好的 Echarts 饼图无缝融入 Cesium 的 3D 地球场景,实现二者的完美结合。

下面直接上代码,完整代码在文末。

import * as Cesium from "cesium";
import * as echarts from "echarts"

// 可根据需求自定义饼图样式
const pieOption = {
    // 想要啥样的自己定样式
}
const drawPie = (options, { radius = 100000.0, lon, lat }) => {
    // 创建一个Canvas元素
    let canvasDom = document.createElement('canvas');
    // 设置Canvas宽高为400像素
    canvasDom.width = 400;
    canvasDom.height = 400;
    // 初始化ECharts图表实例
    let myChart = echarts.init(canvasDom);
    // 设置图表配置项
    myChart.setOption(options);
    // 监听图表渲染完成事件
    myChart.on('finished', () => {
        // 获取圆形几何体并添加到Cesium场景
        let criclePrimitive = getCriclePrimitive(myChart, { radius, lon, lat })
        viewer.scene.primitives.add(criclePrimitive)
        // 清理资源
        myChart.dispose();
        myChart = null;
        canvasDom = null;
    })
}
const getCriclePrimitive = (chart, { radius = 100000.0, lon, lat }) => {
    // 创建圆形几何体
    let circle = new Cesium.CircleGeometry({
        center: Cesium.Cartesian3.fromDegrees(lon, lat),
        radius: radius
    });
    // 生成几何体实例
    let circleGeometry = Cesium.CircleGeometry.createGeometry(circle);
    let circleGeometryInstance = new Cesium.GeometryInstance({
        geometry: circleGeometry,
        attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.ORANGE)
        }
    });
    // 创建Primitive实例
    let criclePrimitive = new Cesium.Primitive({
        geometryInstances: [
            circleGeometryInstance
        ],
        asynchronous: false,
        appearance: new Cesium.MaterialAppearance({
            material:
                new Cesium.Material({
                    fabric: {
                        type: 'Image',
                        uniforms: {
                            image: chart.getDataURL()
                        }
                    }
                })
        })
    })
    return criclePrimitive;
}

drawPie(pieOption, { lon: 116, lat: 39 })

函数 drawPie 的功能

  1. 创建 Canvas 元素:使用document.createElement('canvas')创建一个 Canvas 元素,并设置其宽高为 400 像素。此操作构建了一个空白画布,用于后续绘制 Echarts 饼图。
  2. 初始化 ECharts 图表:利用echarts.init(canvasDom)初始化 ECharts 图表实例,接着调用myChart.setOption(options)设置图表配置项。这一步将 Echarts 的强大图表绘制能力引入到刚刚创建的 canvas 中,为呈现饼图做好准备。
  3. 监听图表渲染完成事件:监听finished事件,在图表渲染完成后执行回调函数。该事件确保在饼图完全绘制好后,才进行下一步将其添加到 Cesium 场景的操作,保证了图表的完整性。
  4. 获取圆形几何体并添加到 Cesium 场景:在回调函数中调用getCriclePrimitive函数,传入图表实例和参数{ radius, lon, lat }获取圆形几何体criclePrimitive,并将其添加到 Cesium 场景中。这使得在 Cesium 的 3D 地球场景中成功创建了一个可以承载饼图的图形载体。
  5. 清理资源:调用myChart.dispose()销毁 ECharts 实例,将myChartcanvasDom设置为null以释放内存。有效避免了内存泄漏,保证程序在长时间运行中的稳定性。

函数 getCriclePrimitive 的功能

  1. 创建圆形几何体:通过Cesium.CircleGeometry创建一个圆形几何体,指定中心点坐标和半径。这一步确定了在 Cesium 场景中用于承载饼图的圆形区域的位置和大小。
  2. 生成几何体实例:调用Cesium.CircleGeometry.createGeometry(circle)生成几何体实例,并创建GeometryInstance,设置颜色属性为橙色。这使得圆形几何体具有了具体的外观属性,虽然最终会被饼图覆盖,但在某些情况下可能作为备用显示。
  3. 创建 Primitive 实例:创建Cesium.Primitive实例,指定几何体实例和材质外观,设置材质类型为Image,并将 Echarts 图表的截图作为纹理。这一步将渲染好的 Echarts 饼图以图像的形式贴到了之前创建的圆形几何体上,实现了在 Cesium 场景中展示 Echarts 饼图的关键一步。
  4. 返回圆形几何体:返回创建好的criclePrimitive对象。该对象包含了完整的带有饼图纹理的圆形几何体信息,可供 Cesium 场景使用。

image.png

存在问题

目前这种实现方式只是一种比较取巧的办法,加载后的饼图失去了 Echarts 的交互特性,本质上只是加载了图片。如果大家有更好的想法和方案,欢迎一起交流和学习。

图片描述
我是 安大桃子,专注前端代码世界的‘筑梦师’。这一趟前端开发的代码之旅暂时告一段落啦,希望文章中的代码思路和技巧能成为你构建前端项目的得力工具。前端技术日新月异,咱们一起在这充满挑战与机遇的领域持续探索,下次代码冒险,咱们不见不散!

源码仓库:完整源码和使用案例请查看此处,里面还有其他相关案例,如果觉得有用,欢迎给个star