I am trying to implement a horizontal scrollable chart. However, the y axis moves along when scrolling. How can I make the y axis stay put?
Here is my code:
struct DataPoint: Identifiable {
var id = UUID()
let x: Double
let y: Double
}
let minGlobalX: Double = 0
let maxGlobalX: Double = 100
let data: [DataPoint] = (Int(minGlobalX) ..< Int(maxGlobalX)).map { DataPoint(x: Double($0), y: Double(arc4random()) / Double(UInt32.max)) }
struct ContentView: View {
var body: some View {
Chart(data) {
LineMark(
x: .value("x", $0.x),
y: .value("y", $0.y)
)
.lineStyle(StrokeStyle(lineWidth: 1))
}
.chartScrollableAxes(.horizontal)
.chartXScale(domain: [minGlobalX, maxGlobalX])
.chartXAxis {
AxisMarks(position: .bottom, values: [0]) {
AxisGridLine(stroke: .init(lineWidth: 1))
}
}
.chartYScale(domain: [0, 1])
.chartYAxis {
AxisMarks(position: .leading, values: [0]) {
AxisGridLine(stroke: .init(lineWidth: 1))
}
}
.padding(20)
}
}
The axis lines are just AxisGridLine
s positioned at the "0" position of the chart. When you scroll the chart, the "0" position moves, and so the line moves with it as well.
You can add the lines using a chartOverlay
instead. Position some 1-wide Rectangle
s using ChartProxy.plotContainerFrame
:
.chartOverlay { proxy in
GeometryReader { geo in
let plotContainer = geo[proxy.plotContainerFrame!]
Rectangle()
.frame(width: 1, height: plotContainer.height)
.offset(x: plotContainer.minX, y: plotContainer.minY)
Rectangle()
.frame(width: plotContainer.width, height: 1)
.offset(x: plotContainer.minX, y: plotContainer.maxY)
}
}