SwiftUI & UI Frameworks 进阶 1m
将 Swift Charts 带入三维
Bring Swift Charts to the third dimension
2025年6月9日
一句话判断
Swift Charts 终于支持 3D 了——把 Chart 换成 Chart3D,加个 Z 轴,你的企鹅数据集就能转着看了。
这场 Session 讲了什么
Swift Charts 从 2D 扩展到三维,核心 API 变化很小:
Chart->Chart3DPointMark多接受一个 Z 值- 新增
SurfacePlot用于绘制数学曲面
demo 用 Palmer 群岛企鹅数据集(喙长、鳍长、体重三个维度),把之前需要三张 2D 图才能表达的关系压缩到一张 3D 散点图里。旋转视角就能看到三个物种的聚类差异。
SurfacePlot 类似 2D 的 LinePlot,接受一个 (Double, Double) -> Double 的闭包,在 XZ 平面上评估 Y 值生成连续曲面。demo 用线性回归做了鳍长+喙长预测体重的曲面可视化。
值得深挖的点
-
2D 和 3D 不是非此即彼的选择。Session 明确说了:当数据形状比精确值更重要、且交互能增强理解时才用 3D。别为了炫酷而 3D。
-
相机投影有两种模式:orthographic(正交,默认)和 perspective(透视)。正交投影下前后点一样大,适合精确比较;透视投影有近大远小效果,适合沉浸感。
-
SurfacePlot 的 foregroundStyle 支持两种新值:
heightBased(按高度着色)和normalBased(按曲面角度着色),加上渐变可以做出很有表现力的可视化。 -
visionOS 上 3D 图表是天然适配,空间计算环境下三维数据可视化是刚需场景。
代码片段
从 2D 散点图升级到 3D,只需加 Z 轴:
// 2D 版本
Chart(penguins) { penguin in
PointMark(
x: .value("Flipper Length", penguin.flipperLength),
y: .value("Weight", penguin.weight)
)
.foregroundStyle(by: .value("Species", penguin.species))
}
// 3D 版本 —— 改动极小
Chart3D(penguins) { penguin in
PointMark(
x: .value("Flipper Length", penguin.flipperLength),
y: .value("Weight", penguin.weight),
z: .value("Beak Length", penguin.beakLength)
)
.foregroundStyle(by: .value("Species", penguin.species))
}
SurfacePlot 绘制数学曲面:
Chart3D {
SurfacePlot { x, z in
// 线性回归预测
return regression.predict(flipperLength: x, beakLength: z)
}
.foregroundStyle(.heightBased.gradient(.elliptical))
}
.chart3DPose(.init(azimuth: .degrees(45), inclination: .degrees(30)))
最佳实践
- 选好初始 pose。
chart3DPose设置 azimuth(水平旋转)和 inclination(俯仰角),选一个能展示数据主要聚类的初始视角。 - 静态数据用 orthographic,追求沉浸感用 perspective。
- 3D 图表必须提供交互。如果用户不能旋转缩放,3D 只会增加理解难度。
- 在 visionOS 上优先考虑 3D 图表,它比 2D 更适合空间展示。
还有什么值得关注
- 支持 3D 的 mark 类型:
PointMark、RuleMark、RectangleMark,以及专属的SurfacePlot。BarMark和LineMark暂不支持 3D。 - 2D 的很多 modifier(axis marks、selection、foregroundStyle)在 3D 里都能用。
- WWDC24 的 “Swift Charts: Vectorized and function plots” 可以补充 LinePlot/SurfacePlot 的背景知识。
SwiftUI