Hello
I'm currently working on a new gui in my App and I wanted to use the new Swift Charts Framework. It's very beautiful but I'm struggling with performance here. I want to draw a LineMark in realtime. I have code that create me a point every 25ms over a runtime of about 10 seconds. So I have round about 400 Samples which should drawn in realtime to the Chart so I can see the LineMark being drawn.
On a first try I used a Binding to the Chart to update the Chart and after 2-3 seconds the ui becomes unresponsive and started lagging. I'm currently using an ObservableObject and the .drawingGroup
modifier to improve the Performance. This Helps but it's not perfect.
Is there a better way to increase the Performance or what's the way to have a realtime drawing line graph?
Here's the Code I use:
struct ChartView: View {
@ObservedObject public var model = FNMeasurementModel()
private let gradient = LinearGradient(gradient: Gradient (colors: [.mint.opacity(0.1),.mint.opacity(0.0)]), startPoint: .top, endPoint: .bottom)
var body: some View {
Chart() {
ForEach(model.data) { item in
LineMark(
x: .value("Ratio", item.ratio ?? .zero),
y: .value("Speed", item.speed ?? .zero)
)
.interpolationMethod(.catmullRom)
.foregroundStyle(.mint)
AreaMark(
x: .value("Ratio", item.ratio ?? .zero),
y: .value("Speed", item.speed ?? .zero)
)
.foregroundStyle(gradient)
}
}
.chartXAxis{
AxisMarks(position: .bottom, values: stride(from: 0, to: 1.0, by: 0.2).map { $0 })
}
.chartXScale(domain: 0...1.0)
.chartYScale(domain: 0...100)
.frame(height: 100)
.padding(.vertical, 5)
}
}
The ObservableObject
class FNMeasurementModel: ObservableObject {
@Published public var data: [FNMeasurementResult] = []
func append(_ sample: FNMeasurementResult) -> Void { data.append(sample) }
func reset() -> Void { data.removeAll() }
}
My Result Type
public class FNMeasurementResult: Identifiable {
public var id: UUID = UUID()
public var ratio: Double?
public var speed: Double?
public init(speed: Double? = nil, ratio: Double? = nil) {
self.ratio = ratio
self.speed = speed
}
}