大前端可视化实战:用 ECharts+Three.js 实现 3D 数据看板

1. 技术选型与核心概念
  • ECharts:处理 2D 数据可视化(折线图/柱状图等)
  • Three.js:构建 3D 场景和模型
  • 融合原理:将 ECharts 的 Canvas 渲染结果作为 Three.js 的纹理贴图,实现 2D/3D 混合渲染
2. 环境搭建
npm install echarts three.js --save  # 基础依赖
npm install @tweenjs/tween.js --save  # 动画过渡

3. 核心实现步骤
3.1 初始化 Three.js 场景
// 创建场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 添加光源
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
directionalLight.position.set(10, 20, 15);
scene.add(directionalLight);

3.2 创建 ECharts 实例作为纹理
// 创建隐藏的Canvas容器
const chartContainer = document.createElement('div');
chartContainer.style.width = '1024px';
chartContainer.style.height = '768px';
chartContainer.style.position = 'absolute';
chartContainer.style.left = '-9999px';
document.body.appendChild(chartContainer);

// 初始化ECharts
const chart = echarts.init(chartContainer);
chart.setOption({
  xAxis: { type: 'category', data: ['Q1', 'Q2', 'Q3', 'Q4'] },
  yAxis: { type: 'value' },
  series: [{ type: 'bar', data: [320, 450, 210, 380] }]
});

// 将ECharts Canvas转为Three.js纹理
const texture = new THREE.CanvasTexture(chart.getDom().querySelector('canvas'));

3.3 构建 3D 数据看板
// 创建3D面板几何体
const geometry = new THREE.PlaneGeometry(8, 6);
const material = new THREE.MeshPhongMaterial({ 
  map: texture,  // 绑定ECharts纹理
  side: THREE.DoubleSide,
  transparent: true
});
const panel = new THREE.Mesh(geometry, material);
panel.position.z = -10;
scene.add(panel);

// 添加3D标注点
const dataPoints = [
  { x: -3, y: 2, z: -8, value: 320 },
  { x: -1, y: 1.5, z: -8, value: 450 },
  { x: 1, y: 0.5, z: -8, value: 210 },
  { x: 3, y: 1.8, z: -8, value: 380 }
];

dataPoints.forEach(point => {
  const sphere = new THREE.Mesh(
    new THREE.SphereGeometry(0.2, 16, 16),
    new THREE.MeshBasicMaterial({ color: 0xff0000 })
  );
  sphere.position.set(point.x, point.y, point.z);
  scene.add(sphere);
});

3.4 实现交互联动
// ECharts点击事件传递到3D场景
chart.on('click', params => {
  const index = params.dataIndex;
  const point = dataPoints[index];
  
  // 高亮对应3D点
  new TWEEN.Tween(camera.position)
    .to({ x: point.x * 1.5, y: point.y + 2, z: point.z + 5 }, 1000)
    .easing(TWEEN.Easing.Quadratic.Out)
    .start();
});

// Three.js射线拾取
renderer.domElement.addEventListener('click', event => {
  const mouse = new THREE.Vector2();
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
  
  const raycaster = new THREE.Raycaster();
  raycaster.setFromCamera(mouse, camera);
  const intersects = raycaster.intersectObjects(scene.children);
  
  if (intersects.length > 0) {
    const obj = intersects[0].object;
    // 触发ECharts数据更新
    chart.dispatchAction({ type: 'highlight', seriesIndex: 0, dataIndex: 1 });
  }
});

4. 性能优化技巧
  1. 纹理更新策略

    // 仅当数据变化时更新纹理
    function updateChartTexture() {
      texture.needsUpdate = true;
      chart.resize();  // 防止Canvas尺寸失真
    }
    

  2. GPU 实例化渲染:对相同形态的 3D 标注点使用 THREE.InstancedMesh

  3. 按需渲染

    function animate() {
      requestAnimationFrame(animate);
      TWEEN.update();  // 更新补间动画
      if (needsRender) renderer.render(scene, camera);
    }
    

5. 效果增强方案
  • 数据流动画:用 Three.js 的 ShaderMaterial 实现流光特效
  • 深度混合:通过 THREE.DepthTexture 实现 2D/3D 元素层级交互
  • 响应式适配:监听窗口大小变化,动态调整相机比例: $$ \text{aspect} = \frac{\text{window.innerWidth}}{\text{window.innerHeight}} $$
6. 部署注意事项
  1. 使用 Webpack 的 asset/resource 处理 GLSL 着色器文件
  2. 通过 glTF 格式导入复杂 3D 模型替代原生几何体
  3. 在 Vue/React 中封装为可复用组件:
    <template>
      <div ref="container"></div>
    </template>
    <script>
    import { init3DDashboard } from './dashboard';
    export default {
      mounted() {
        init3DDashboard(this.$refs.container);
      }
    }
    </script>
    

项目示例


完整代码库:github.com/echarts-three-dashboard

通过 ECharts 的丰富图表能力与 Three.js 的 3D 渲染结合,可构建出深度交互的沉浸式数据看板,适用于智慧大屏、实时监控等场景。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐