Similar to a chart consisting of BarMark
, I want my LineMark
chart to drop to zero if there is no value for a point instead of simply connecting the existing values.
Example:
import Charts
import SwiftUI
struct ChartExample: View {
let data: [(x: Int, y: Int)] = [(0, 1), (1, 3), (5, 1), (10, 1)]
var body: some View {
Chart {
ForEach(data, id: \.x) { point in
LineMark(x: .value("x", point.x), y: .value("y", point.y))
}
}.padding()
}
}
#Preview {
ChartExample()
}
Resulting LineMark chart: Wanted LineMark chart:
How can I achieve such behaviour? Do not expect that the entity (number, minute, hour, day…) or the span (1…10, 1 day, 3 months…) is always the same.
Are there any modifiers, or have these points somehow be added manually?
You do need to generate zero marks explicitly, because the SwiftUI charts have no idea for which X values the data is missing.
As an example, in your case you do want to interpolate from x=0
to x=1
, but not from x=0
to x=2
; there is no way to express this logic in SwiftUI Charts.
Code to fill the missing values might look like:
let data: [(x: Int, y: Int)] = [(0, 1), (1, 3), (5, 1), (10, 1)]
let filledData: [(x: Int, y: Int)] = data.reduce(into: []) { out, point in
if let last = out.last {
var xToFill = last.x+1
while xToFill < point.x {
out.append((xToFill, 0))
xToFill += 1
}
}
out.append(point)
}