使用 chartScrollableAxes 为 Swift Charts 图表添加滑动手势
了解如何使用 chartScrollableAxes 为你的 Swift Chart 图表添加滑动手势,这在显示大量数据时特别有用。
使用 chartScrollableAxes 添加滑动支持
默认情况下,Chart 组件会尝试在屏幕中展示所有数据。
例如,示例代码:
var body: some View {
VStack(alignment: .leading) {
Text("周度销售额")
.font(.headline)
.padding(.leading)
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartXAxis {
AxisMarks(values: .automatic(desiredCount: 8)) { value in
AxisValueLabel()
}
}
.padding()
}
}
当只有少量数据时,上述展示方式是可行的。但当数据量更多时,就会导致数据挤压到一起,难以阅读:
在 iOS17 上推出的 .chartScrollableAxes
修饰器,正是为了解决这个问题。通过使用这个修饰符,你可以允许用户在图表上滚动查看超出当前视图范围的数据,非常适合处理大型数据集或需要细节查看的场景。
.chartScrollableAxes
可以自动为图表添加滑动支持(横向或纵向),并且会根据数据量、标签长度自动决定每页显示多少数据。要使用它,只需要添加到 Chart 组件上即可:
var body: some View {
VStack(alignment: .leading) {
Text("周度销售额")
.font(.headline)
.padding(.leading)
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal) // 添加水平滚动支持
.chartXAxis {
AxisMarks(values: .automatic(desiredCount: 8)) { value in
AxisValueLabel()
}
}
.padding()
}
}
它的使用效果非常类似于 ScrollView
组件。
你可以通过设置滚动方向:
.horizontal
(水平轴).vertical
(垂直轴)- 甚至同时启用水平和垂直轴:
[.horizontal, .vertical]
.chartScrollableAxes([.horizontal,.vertical]) // 添加水平滚动支持
使用 chartScrollTargetBehavior 控制滑动对齐位置
默认情况下,.chartScrollableAxes
不限制滚动停止的位置——取决于滑动的速度,可能停留在任意位置。
.chartScrollTargetBehavior
是 iOS17 上推出的另一个用于控制图表滚动行为的修饰符。它决定了当用户停止滚动时,图表的滚动位置如何调整,例如:
- 对齐到数据点:滚动停止后,图表自动对齐到最近的数据点。
- 分页效果:类似于分页滚动,每次滚动一个固定的距离。
.chartScrollTargetBehavior
和 ScrollView 中的 .scrollTargetBehavior
修饰器效果和使用方法都一样,我在另一篇文章中讲解过:
每次滑动固定屏幕长度(.paging)
.chartScrollTargetBehavior(.paging)
会保证每次图表滑动一个屏幕宽度的距离:
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal) // 添加水平滚动支持
.chartScrollTargetBehavior(.paging)
每次滑动固定数量(.valueAligned)
.chartScrollTargetBehavior(.valueAligned(unit: 1))
可以自定义设置每次滑动的 X 轴数据数量:
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal) // 添加水平滚动支持
.chartScrollTargetBehavior(.valueAligned(unit: 1))
你可以自定义 unit 的值。
使用 chartXVisibleDomain 设置 X 轴显示数量
例如,我们可以通过设置 .chartXVisibleDomain(length: 10)
,使 X 轴固定显示 10 个数据:
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal) // 添加水平滚动支持
.chartXVisibleDomain(length: 10)
.chartScrollTargetBehavior(.valueAligned(unit: 1))
但是特别注意:如果你的 X 轴使用时间,默认 X 轴的单位为秒。这意味着,如果你想显示 10 天的数据,则应该设置为:
// 86400 秒 = 1 天
.chartXVisibleDomain(length: 10*86400)
否则,你的应该将会挂起或崩溃。
使用 chartScrollPosition(initialX:) 设置初始滚动位置
默认情况下,Chart 从第一项数据开始展示,就像我们之前的实例代码:
使用 chartScrollPosition(initialX:) 修饰器,你可以自定义 Chart 渲染时的初始位置:
Chart(data) { item in
BarMark(
x: .value("周数", "第\(item.week)周"),
y: .value("销售额", item.sales)
)
.foregroundStyle(Color.blue.gradient)
}
.frame(height: 300)
.chartScrollableAxes(.horizontal) // 添加水平滚动支持
.chartScrollPosition(initialX: "第10周") // 设置初始滚动位置为第22周
.chartScrollTargetBehavior(.valueAligned(unit: 1))
这非常适合用来展示以日期作为 X 轴的数据。例如,如果要展示之前一年到之后一年的计划,你可以将初始位置设置在今天,而不是一年前。