antvis/G2

如何实现一个 3D 图表 #5375

xiaoiver posted onGitHub

伪 3D 和真 3D

Canvas2D / SVG 都可以实现伪 3D 效果。例如 zdogvchart。下图为 vchart 的 3D Scatter Plot,使用 Canvas2D 渲染:

image

个人认为问题主要出在交互上,如果不考虑相机交互,伪 3D 通过投影变换实现相对简单。而以真 3D 的 plot.lyecharts-gl 为例:

Aug-03-2023 10-21-29

自底向上涉及渲染器(g-webgl)、组件库(GUI)、G2

渲染器及其插件

  • g 提供相机能力
  • g-webgl 提供基于 WebGL 的渲染能力,内置支持 2D 图形
  • g-plugin-3d 提供 3D 图形扩展,包括 Geometry、Material 和光照
  • g-plugin-control 提供 3D 场景下的相机交互

GUI Axis

特定组件使用到的 Line、Text(这个最重要)、Path 需要支持公告牌效果(永远面朝相机)

https://github.com/antvis/GUI/pull/304

@antv/coord

需要支持 Cartesian3D,在 Cartesian 基础上扩展 z 和 depth:

const coord = new Coordinate3D({
  x: 0,
  y: 0,
  z: 0,
  width: 100,
  height: 50,
  depth: 100,
  transformations: [['cartesian3D']],
});

https://github.com/antvis/coord/pull/44

G2

在 G2 中 3D Scatter Plot 期望的用法(Spec)如下:

{
  type: 'point3D', // 散点图
  padding: 'auto',
  data: {
    type: 'fetch',
    value: 'data/cars2.csv',
  },
  encode: {
    x: 'Horsepower',
    y: 'Miles_per_Gallon',
    z: 'Weight_in_lbs', // z 通道
    size: 'Origin',
    color: 'Cylinders',
    shape: 'sphere', // 使用 Sphere
  },
  scale: {
    x: { nice: true },
    y: { nice: true },
    z: { nice: true },
  },
  coordinate: { type: 'cartesian3D', depth: 300 }, // 使用 Cartesian3D
  axis: {
    x: { gridLineWidth: 3 },
    y: { gridLineWidth: 3 },
    z: { gridLineWidth: 3 },
  },
}

Mark

交互

支持渲染到多个画布

同一个画布中的图形都会受相机影响,例如下面的 legend 展示效果也随相机旋转发生了改变:

Aug-03-2023 10-23-39

在 plot.ly 的实现中,图表主题使用 WebGL 渲染,而 legend 使用 SVG 渲染。

参考


Fund this Issue

$0.00
Funded

Pull requests