多轴图表(双 Y 轴、混合图表)
概述
多轴图表是数据可视化中的高级技术,允许在同一图表中展示多个数据维度或不同量纲的数据。通过双 Y 轴或混合图表类型(如折线图+柱状图组合),可以更高效地呈现复杂数据关系。
双 Y 轴实现
核心概念
双 Y 轴适用场景
- 比较不同量纲的数据(如温度℃ vs. 降水量mm)
- 显示同一时间范围内两种不同尺度的趋势
SwiftUI Charts 实现方案
Chart { // 主 Y 轴数据(左侧) BarMark( x: .value("Date", data.date), y: .value("Sales", data.sales) ) // 次 Y 轴数据(右侧) LineMark( x: .value("Date", data.date), y: .value("Profit Rate", data.profitRate) ) .foregroundStyle(.red) .yAxis(.secondary) // 关键配置 } .chartYAxis { AxisMarks(position: .leading) // 左侧主Y轴 AxisMarks(position: .trailing) // 右侧次Y轴 }
样式控制
- 轴标签格式化
.chartYAxis { AxisMarks(position: .trailing, values: .automatic) { value in AxisGridLine() AxisTick() AxisValueLabel { Text("\(value.as(Int.self)!)%") .foregroundStyle(.red) } } }
混合图表类型
常见组合模式
| 组合类型 | 适用场景 | 示例 |
|---|---|---|
| 柱状图+折线图 | 数值对比+趋势展示 | 销售额(柱状)vs. 增长率(线) |
| 面积图+散点图 | 分布展示+突出关键点 | 温度分布(面积)vs. 极端值(点) |
实现示例
Chart {
// 柱状图部分
BarMark(
x: .value("Month", data.month),
y: .value("Revenue", data.revenue)
)
.foregroundStyle(.blue)
// 折线图部分
LineMark(
x: .value("Month", data.month),
y: .value("Users", data.users)
)
.foregroundStyle(.orange)
.symbol(.circle)
}
.chartYAxis {
AxisMarks(position: .leading) // 共用Y轴
}
高级技巧
1. 轴对齐策略
// 强制双Y轴零基线对齐
.chartYScale(domain: [0, maxPrimaryValue])
.chartYScale(domainSecondary: [0, maxSecondaryValue])
2. 图例(legend)优化
.chartLegend(position: .top) {
HStack {
Circle().fill(.blue).frame(width: 10)
Text("Revenue")
Circle().fill(.orange).frame(width: 10)
Text("User Growth")
}
}
3. 交互增强
// 同步高亮两个数据系列
.chartOverlay { proxy in
Color.clear
.onTapGesture { location in
if let date = proxy.value(atX: location.x) as String? {
highlightDate = date
}
}
}
案例:加密货币行情图表
功能需求
- 主Y轴(左):显示价格(USD)
- 次Y轴(右):显示交易量(BTC)
- 组合类型:蜡烛图(价格) + 柱状图(交易量)
关键代码
Chart(cryptoData) { item in
// 蜡烛图
BarMark(
x: .value("Day", item.date),
yStart: .value("Low", item.lowPrice),
yEnd: .value("High", item.highPrice),
width: .fixed(8)
)
.foregroundStyle(
item.openPrice > item.closePrice ? .red : .green
)
// 交易量柱状图
BarMark(
x: .value("Day", item.date),
y: .value("Volume", item.volume)
)
.yAxis(.secondary)
.foregroundStyle(.gray.opacity(0.3))
}
常见问题解决
Q1: 轴刻度不对齐怎么办?
- 方案:手动设置
chartYScale的domain和domainSecondary
Q2: 如何避免视觉混淆?
- 最佳实践:
- 使用对比色但保持低饱和度
- 为次要数据系列添加透明度
- 添加清晰的图例说明
Q3: 性能优化建议
- 大数据集时:
- 对次要系列启用
interpolationMethod(.monotone) - 使用
Canvas替代标准Mark绘制
- 对次要系列启用
