news 2026/7/1 10:51:45

Three.js Echarts结合教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Three.js Echarts结合教程

Echarts结合 ·Combine Echarts· ▶ 在线运行案例

  • 案例合集:三维可视化功能案例(threehub.cn)
  • 开源仓库github地址:https://github.com/z2586300277/three-cesium-examples
  • 400个案例代码:网盘链接

你将学到什么

  • glTF/FBX/OBJ 外部模型加载
  • 相机交互控制器
  • CSS2D/3D 标签渲染
  • ECharts 与三维融合
  • requestAnimationFrame 渲染循环

效果说明

本案例演示Echarts结合效果:ECharts 图表与 Three.js 场景同屏联动展示;核心用到 OrbitControls、glTF/Draco、ECharts。建议先打开文首在线案例查看动态画面,再对照下方源码逐步理解。

核心概念

  • Loader异步加载模型;glTF 返回gltf.scene,加载后注意scale与坐标系。Draco 需配置DRACOLoader
  • OrbitControls轨道旋转缩放;开enableDamping时每帧需controls.update()
  • DOM 元素叠加在 3D 坐标上,适合信息面板(注意与 WebGL 深度关系)。
  • 二维图表/飞线与 Cesium/Three 场景叠加或纹理映射。

实现步骤

  • 搭建 Scene / Camera / Renderer 与 OrbitControls
  • Loader 异步加载模型/纹理资源
  • rAF 循环中 update 并 render
  • 代码要点

    import * as THREE from 'three'

    import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' import { CSS3DRenderer, CSS3DObject } from 'three/examples/jsm/renderers/CSS3DRenderer.js' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js' import * as echarts from 'echarts'

    const DOM = document.getElementById('box')

    const scene = new THREE.Scene()

    const camera = new THREE.PerspectiveCamera(75, DOM.clientWidth / DOM.clientHeight, 0.1, 10000)

    camera.position.set(50, 90, 300)

    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true, logarithmicDepthBuffer: true })

    renderer.setSize(DOM.clientWidth, DOM.clientHeight)

    DOM.appendChild(renderer.domElement)

    scene.add(new THREE.AmbientLight(0xffffff, 3))

    new OrbitControls(camera, renderer.domElement)

    const css3DRender = setCss3DRenderer(DOM)

    new GLTFLoader().load(FILE_HOST + "files/model/Fox.glb", gltf => scene.add(gltf.scene))

    animate()

    function animate() {

    requestAnimationFrame(animate)

    renderer.render(scene, camera)

    css3DRender.render(scene, camera) }

    window.onresize = () => {

    renderer.setSize(box.clientWidth, box.clientHeight)

    camera.aspect = box.clientWidth / box.clientHeight

    camera.updateProjectionMatrix()

    css3DRender.resize()

    }

    /css3d 渲染/ function setCss3DRenderer(DOM) {

    const css3DRender = new CSS3DRenderer()

    css3DRender.resize = () => {

    css3DRender.setSize(DOM.clientWidth, DOM.clientHeight)

    css3DRender.domElement.style.zIndex = 0

    css3DRender.domElement.style.position = 'relative'

    css3DRender.domElement.style.top = -DOM.clientHeight + 'px'

    css3DRender.domElement.style.height = DOM.clientHeight + 'px'

    css3DRender.domElement.style.width = DOM.clientWidth + 'px'

    css3DRender.domElement.style.pointerEvents = 'none'

    }

    css3DRender.resize()

    DOM.appendChild(css3DRender.domElement)

    return css3DRender

    }

    /图表 ----------------------------------------------------------------------/

    const container = document.createElement("div") container.style.width = "300px" container.style.height = "200px" const myChart = echarts.init(container)

    myChart.setOption({ graphic: { elements: [ { type: 'text', left: 'center', top: 'center', style: { text: 'Echarts', fontSize: 80, fontWeight: 'bold', lineDash: [0, 200], lineDashOffset: 0, fill: 'transparent', stroke: '#fff', lineWidth: 1 }, keyframeAnimation: { duration: 3000, loop: true, keyframes: [ { percent: 0.7, style: { fill: 'transparent', lineDashOffset: 200, lineDash: [200, 0] } }, { // Stop for a while. percent: 0.8, style: { fill: 'transparent' } }, { percent: 1, style: { fill: 'black' } } ] } } ] } })

    const css3DObject = new CSS3DObject(container) css3DObject.position.set(0, 130, 0) scene.add(css3DObject)

    const container2 = document.createElement("div") container2.style.width = "300px" container2.style.height = "300px" const myChart2 = echarts.init(container2)

    myChart2.setOption({ xAxis: { type: 'category', boundaryGap: false, data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { data: [820, 932, 901, 934, 1290, 1330, 1320], type: 'line', areaStyle: {} } ] })

    const css3DObject2 = new CSS3DObject(container2) css3DObject2.position.set(0, -80, 0) scene.add(css3DObject2)

    完整源码:GitHub

    小结

    • 本文提供Echarts结合完整 Three.js 源码与在线 Demo,建议先运行案例再改 uniform/参数做二次实验
    • 更多 Three.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 10:50:20

MPC5643L/SPC56EL评估板硬件设计解析与调试实战

1. 项目概述与核心价值对于从事汽车电子或高性能工业控制开发的工程师而言,拿到一颗像MPC5643L或SPC56EL这样的Power Architecture内核微控制器,第一件事往往不是直接写代码,而是先搞定它的“食宿”——也就是硬件评估板。一块设计精良的评估…

作者头像 李华
网站建设 2026/7/1 10:49:46

现代C++内存模型与无锁编程:从硬件重排序到内存序语义

现代C内存模型与无锁编程:从硬件重排序到内存序语义 ​摘要:本文从硬件层面的指令重排序出发,逐步推导出C11引入的形式化内存模型。我们不仅讨论六种内存序的形式语义,更深入分析它们在x86(TSO)和ARM&#…

作者头像 李华
网站建设 2026/7/1 10:45:19

DALL-E 3 2024最新版隐藏功能全解锁:支持SVG矢量输出、长文本上下文记忆增强、跨图一致性锚点控制(仅限v3.1.2+,内测通道即将关闭)

更多请点击: https://intelliparadigm.com 第一章:DALL-E 3 2024新版核心特性概览 DALL-E 3 2024新版在图像生成质量、文本理解深度与工作流集成能力上实现显著跃升。其底层多模态架构经过重构,支持更长、更复杂的自然语言提示(P…

作者头像 李华
网站建设 2026/7/1 10:44:53

微信聊天记录永久保存:5步轻松掌握WeChatMsg完全指南

微信聊天记录永久保存:5步轻松掌握WeChatMsg完全指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChat…

作者头像 李华
网站建设 2026/7/1 10:41:11

遗传算法实战:用Python实现N皇后问题求解

1. 这不是教科书,而是一次真实的GA项目复盘:从Matlab到Python的N皇后实战手记你点开这篇文章,大概率不是为了背诵“遗传算法是模拟生物进化过程的优化方法”这种定义。你真正想搞清楚的是:当一个真实项目摆在面前——比如用遗传算…

作者头像 李华