Wanted to play a bit with SwiftUI and Charts as some learning project. and encountered the issue with compiling time.
I have a SwiftUI struct conforming to ChartContent protocol in my code. To generate the content I use a switch statement. When I have 3 cases in a switch - everything compiles instantly. When adding the forth one is added - the same file compiles almost 90s.
Why it may be like that? Shall I structure my code differently to avoid such issues?
Longer example with code samples:
I have following definitions for some weather chart:
struct MeteogramContent: ChartContent {
let parameters: [MeteogramParameter]
init(_ parameters: [MeteogramParameter]) {
self.parameters = parameters
}
var body: some ChartContent {
ForEach(parameters) { parameter in
ForEach(parameter.data) { dataPoint in
switch parameter.style {
case .line:
LineMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).foregroundStyle(by: .value("Param", parameter.name))
case .dot:
PointMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).symbolSize(7)
.foregroundStyle(by: .value("Param", parameter.name))
case .bar:
BarMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).foregroundStyle(by: .value("Param", parameter.name))
}
}
}
}
}
Which bases on the following model:
struct DataPoint: Identifiable {
let id = UUID()
let timestamp: Date
let value: Double
}
typealias DataSerie = [DataPoint]
struct MeteogramParameter: Identifiable {
enum ChartStyle {
case line
case dot
case bar
}
let id = UUID()
let name: String
let data: DataSerie
let color: Color
let style: ChartStyle
}
then when I add
enum ChartStyle {
case line
case dot
case bar
case range
}
and extend MeteogramContent with handling for that another case as below, the compilation time is skyrocketing to 90s just for this single file.
struct MeteogramContent: ChartContent {
let parameters: [MeteogramParameter]
init(_ parameters: [MeteogramParameter]) {
self.parameters = parameters
}
var body: some ChartContent {
ForEach(parameters) { parameter in
ForEach(parameter.data) { dataPoint in
switch parameter.style {
case .line:
LineMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).foregroundStyle(by: .value("Param", parameter.name))
case .dot:
PointMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).symbolSize(7)
.foregroundStyle(by: .value("Param", parameter.name))
case .bar:
BarMark(
x: .value("Date", dataPoint.timestamp),
y: .value("Value", dataPoint.value)
).foregroundStyle(by: .value("Param", parameter.name))
case .range:
AreaMark(x: .value("Date", dataPoint.timestamp),
yStart: .value("Value Min", 0),
yEnd: .value("Value Max", dataPoint.value)
)
.foregroundStyle(by: .value("Param", parameter.name))
}
}
}
}
}