我有一个应用程序,其日期沿 x 轴排列。用户可以选择显示数据的日期范围。通过输入日期范围的日期,可以沿 x 轴移动该日期范围。通过了解日期范围的位置,我可以调整 y 轴位置和分辨率,以便查看该范围内的所有数据点。
现在我想在滚动图表时实现相同的功能。这是我到目前为止的代码:
Chart {
...
}
.chartScrollableAxes(.horizontal)
.chartScrollPosition(initialX: today)
.chartXVisibleDomain(length: range)
滚动效果很好,但数据点会移入和移出视图。如果我知道哪些数据点位于日期范围内 (
chartXVisibleDomain
),我可以相应地调整 y 轴。
这就是我提出问题的原因。或者还有其他视图修改器可以实现此目的吗?
您知道 x 轴的长度(如您使用的
.chartXVisibleDomain(length: range)
)。您还可以使用 chartScrollPosition(x:)
知道当前滚动位置,因此 X 值的可见范围就是从滚动位置到(滚动位置 + 范围)的所有值。
一旦您知道了可见 X 值的范围,您就可以使用它来过滤数据。
这是一个例子:
struct ChartData: Identifiable {
var id: Date { date }
let date: Date
let y: Double
}
let data = (1..<20).map { i in ChartData(
date: Calendar.current.startOfDay(for: .now).addingTimeInterval(86400 * Double(i)),
y: Double(i)
) }
struct ContentView: View {
@State var scrollPos = Date()
var body: some View {
VStack {
Chart(data) { p in
BarMark(x: .value("X", p.date, unit: .day), y: .value("Y", p.y))
}
.chartScrollPosition(x: $scrollPos)
// two days visible at a time
.chartXVisibleDomain(length: 86400 * 2)
.chartScrollableAxes(.horizontal)
.containerRelativeFrame(.vertical, count: 2, spacing: 0)
Text(scrollPos, format: .dateTime)
// a list to show the visible Y values
List {
let visibleRange = scrollPos.addingTimeInterval(-86400)...scrollPos.addingTimeInterval(86400 * 2)
let visibleData = data.filter { visibleRange.contains($0.date) }
ForEach(visibleData) { p in Text(p.y, format: .number) }
}
}
.padding()
}
}
请注意,我从可见范围的下限中减去了一天,因为即使您滚动超过条形图的 x 坐标,条形图的一部分仍然可见。如果您使用折线图,这可能没有必要。