第 8 章:复杂图表类型
饼图、环形图和堆叠柱状图
1. 饼图(Pie Chart)
核心实现:
Chart(data) { item in
SectorMark(
angle: .value("Value", item.value),
innerRadius: .ratio(0), // 标准饼图
angularInset: 1.5
)
.foregroundStyle(by: .value("Category", item.category))
.annotation(position: .overlay) {
Text("\(Int(item.value))%")
.font(.caption)
}
}
设计要点:
- 适合展示比例关系(总和为100%)
- 建议不超过6-8个分类以避免视觉混乱
- 使用对比色区分不同扇区
- 添加百分比标签提升可读性
2. 环形图(Donut Chart)
与饼图的区别:
SectorMark(
angle: .value("Value", item.value),
innerRadius: .ratio(0.6) // 关键参数控制中心空洞大小
)
使用场景:
- 中心区域可放置总计数据或图标
- 视觉上更强调整体中的部分关系
- 适合仪表盘类应用
3. 堆叠柱状图(Stacked Bar Chart)
基础实现:
Chart {
ForEach(dataSeries) { series in
ForEach(series.dataPoints) { point in
BarMark(
x: .value("Category", point.category),
y: .value("Value", point.value)
)
.foregroundStyle(by: .value("Series", series.name))
}
.position(by: .value("Stack", "total")) // 堆叠关键参数
}
}
进阶技巧:
- 使用
position(by:)控制堆叠方式 - 添加
annotation显示各分段数值 - 结合
scrollable修饰符处理长分类标签
4. 组合使用案例
健康应用示例:
// 环形图显示每日目标完成率
DonutChartView(progress: 0.75)
// 堆叠柱状图展示每周运动类型分布
StackedBarChartView(weeklyData: workoutData)
// 饼图显示营养摄入比例
PieChartView(nutritionData: macroData)
5. 样式自定义
共享配置模式:
struct UnifiedChartStyle: ChartStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.content
.chartLegend(position: .bottom)
.chartXAxis {
AxisMarks(values: .automatic) { value in
AxisGridLine()
AxisTick()
AxisValueLabel()
}
}
}
}
6. 性能优化建议
- 对超过15个分类的饼图考虑合并"其他"类别
- 堆叠柱状图数据预处理时计算累计值
- 使用
drawingGroup()提升复杂图表渲染性能
7. 交互增强
.schartAngleSelection($selectedSlice) // 饼图选中交互
.onChange(of: selectedSlice) { newValue in
// 显示详细数据
}
8. 设计注意事项
- 避免使用3D效果扭曲数据感知
- 色盲友好配色方案(使用
Color.accessible) - 环形图中心空白区域合理利用(显示汇总数据)
专业提示:当需要比较多个分类在不同维度的分布时,堆叠柱状图比多个饼图更有效。例如比较A/B两组用户在年龄段的分布差异。
