ECharts 水球图不够炫?试试 RayChart 的创意可视化玩法

有趣的3D图表水球:从 ECharts 到 RayChart 的升维打击

在数据可视化大屏中,"水球图"(Liquid Fill Chart)绝对是展示百分比数据(如CPU使用率、完成度、剩余电量)的颜值担当。

大家最熟悉的莫过于 ECharts 的 echarts-liquidfill 插件。它简单、好用,但在这个"卷"视觉的时代,传统的 2D 扁平水球有时显得不够"震撼"。

今天我们来聊聊一个有趣的话题:如何用 RayChart 手搓一个真实的 3D 水球,并对比它与 ECharts 水球的区别。 raychart体验地址:https://chart3js.netlify.app

1. 传统的 2D 做法:ECharts LiquidFill

ECharts 的水球本质上是 2D Canvas/SVG 绘图

原理

它的"波浪"并不是真的流体,而是通过数学公式(通常是正弦函数 y = A * sin(Bx + C) + D)在 2D 平面上绘制出的闭合路径。通过不断改变相位(Offset),让曲线平移,从而产生"波动"的视觉错觉。

特点

  • 优点
    • 性能极佳:几乎不占用 GPU 资源。
    • 兼容性好:甚至可以在不支持 WebGL 的环境运行。
    • 配置简单:几行配置就能搞定。
  • 缺点
    • 扁平:没有厚度,没有光影。
    • 质感单一:虽然可以加渐变色,但无法表现出水的折射、玻璃的通透感。

2. 进阶的 3D 做法:RayChart 硬核实现

为了追求"透亮"、"像真水一样"的效果,我们必须引入 WebGLPBR(基于物理的渲染)

在我的开源项目 RayChart 中,我实现了一个 Liquid3D 组件。下面来看看它是如何"骗"过你的眼睛的。

核心构成

一个真实的 3D 水球通常由三部分组成:

  1. 玻璃外壳:一个透明的球体容器。
  2. 液体主体:球体内部被截断的下半部分。
  3. 液体表面:一个随波浪起伏的顶盖。

技术实现细节

A. 玻璃外壳 (The Glass Shell)

ECharts 很难做出的效果就是"玻璃感"。在 RayChart (基于 Three.js) 中,我们使用 MeshPhysicalMaterial,并开启 transmission(透光率)属性。

typescript 复制代码
const shellMaterial = new THREE.MeshPhysicalMaterial({
    color: 0xffffff,
    transmission: 0.9, // 90% 透光,像玻璃一样
    roughness: 0,      // 极其光滑
    ior: 1.5,          // 折射率,模拟玻璃/水晶
    thickness: 0.5,    // 厚度,产生真实的折射效果
    transparent: true
});

这让背景能够透过球体产生扭曲,质感瞬间拉满。

B. 液体主体:着色器里的"裁剪术"

液体本身其实也是一个球体(SphereGeometry),但我们需要根据水位把它"切"开。

普通的 clippingPlanes 切出来是平的,没有波浪。所以我们需要写一点 Shader(着色器)。

秘籍: 使用 onBeforeCompile 修改标准材质,在 Fragment Shader 中加入 discard 逻辑。

glsl 复制代码
// GLSL 片段着色器伪代码
float h = getWaveHeight(vWorldPosition.x, vWorldPosition.z); // 计算波浪高度
// 如果当前像素的高度 > 水位 + 波浪高度,就丢弃(不渲染)
if (vWorldPosition.y > uLevelY + h) discard;

这样,原本完整的球体就被"切"出了一个起伏的边缘。

C. 液体表面:动态波浪

被切掉的顶部不能空着,需要盖一个"盖子"。这个盖子是一个高密度的 PlaneGeometry

难点: 盖子的波动必须和球体的切口严丝合缝,否则会漏水。

解决方案:

  1. 几何同步:表面使用与主体完全相同的波浪公式(正弦波叠加)。
  2. 圆形遮罩:因为 Plane 是方形的,我们需要在 Shader 里把超出球体半径的部分裁掉。
glsl 复制代码
// Vertex Shader: 让顶点随波浪起伏
vec3 pos = position;
float waveH = getWaveHeight(worldPos.x, worldPos.z);
pos.y += waveH; // 顶点置换

// Fragment Shader: 切成圆形
if (length(vUv - 0.5) * 2.0 > 1.0) discard;

3. 终极对比:ECharts vs RayChart

维度 ECharts LiquidFill RayChart Liquid3D
渲染引擎 Canvas / SVG WebGL (Three.js)
视觉维度 2D 平面 3D 空间
质感 色块、渐变、扁平阴影 折射、反射、高光、环境光遮蔽
交互 鼠标悬浮高亮 360度旋转、缩放、甚至可以晃动液体
性能开销 ⭐ (极低) ⭐⭐⭐ (中高,依赖 GPU)
适用场景 普通报表、H5 页面、移动端 大屏可视化、数字孪生、高逼格演示

4. 总结

  • 如果你需要一个快速加载、兼容性强 的进度展示,ECharts 依然是首选。
  • 如果你在做酷炫的数据大屏 ,想要那种"看起来很贵"的效果,RayChart 的 3D 水球绝对值得一试。

RayChart 项目正在探索更多这样的 3D 图表组件,希望能把 WebGL 的门槛降下来,让大家都能轻松用上"电影级"的图表。


觉得有趣的话,欢迎点赞收藏!

相关推荐
如果你好2 小时前
TypeScript 接口(interface)完全指南:语法、特性与实战技巧
vue.js·typescript
天才熊猫君2 小时前
Vue 3 命令式弹窗组件
前端
NEXT062 小时前
CSS基础-标准盒模型与怪异盒模型
前端·css
DaMu2 小时前
Dreamcore3D ARPG IDE “手搓”游戏引擎,轻量级实时3D创作工具,丝滑操作,即使小白也能轻松愉快的创作出属于你自己的游戏世界!
前端·架构·three.js
代码猎人2 小时前
什么是尾调用,使用尾调用有什么好处?
前端
AI_56782 小时前
Webpack从“配置到提速”,4步解决“打包慢、体积大”问题
前端·javascript·vue.js
pinkQQx2 小时前
手把手搭建前端跨平台服务(IPlatform + iOS / Android / Web)
前端·javascript
江启年2 小时前
对useEffect和 useMemo的一些总结与感悟
前端
中微子2 小时前
Web 安全:跨域、XSS 攻击与 CSRF 攻击
前端