Charts fails when a function or ternary condition is added to the values to be plotted. Charts.
When a function is received as a value in the ForEach loop, the application crashes (Thread 1: signal SIGABRT), or if it is a ternary operator (condition ? true: false) it does not show the graph. The function should convert the value/attribute of the Core Data entity only if necessary, the data is stored in a common unit and depending on the display condition in an AppStorage variable it should be seen converted to another unit or displayed. This error occurs with any type of chart. It fails with both RulerMark and other charts like LineMark. The function works fine with Text and other similar views.
The Chart
@AppStorage("unitView") var unitView: String = "Celsius"
...
// CHART
Chart {
if statsByUser.takens > 1 {
RuleMark(y: .value("AVG", getViewDegrees(statsByUser.avg, unitView)))
.lineStyle(StrokeStyle(lineWidth: 2, lineCap: .round, lineJoin: .round, dash: [4, 6]))
.foregroundStyle(.white.opacity(0.8))
}
ForEach(0..<temperatureByUserId.count, id:\.self) { item in
LineMark(x: .value("Date", item + 1),
y: .value("Temperature", getViewDegrees(temperatureByUserId[item].degress, unitView)))
.lineStyle(.init(lineWidth: 2, lineCap: .round, lineJoin: .round))
.foregroundStyle(.white) //.mint [.pink, .purple, .mint]
}
.interpolationMethod(.cardinal)
}
// X-Axis
.chartXScale(domain: 1 ... statsByUser.takens)
.chartXAxis(.hidden)
// Y-Axis
.chartYScale(domain: statsByUser.min ... statsByUser.max)
.chartYAxis {
AxisMarks{ _ in
AxisGridLine().foregroundStyle(.white)
AxisValueLabel(centered: true).foregroundStyle(.white)
}
}
}
The Functions
let unitDegress: [String] = ["Celsius", "Fahrenheit"]
func getViewDegrees(_ value: Double, _ unit: String) -> Double {
var returnValue = value
if unit == unitDegress[1] { // is Fahrenheit
let t = Measurement(value: value, unit: UnitTemperature.celsius)
returnValue = t.converted(to: .fahrenheit).value
}
return returnValue
}
Text works properly.
Text("\(getViewDegrees(temperatureByUser.last, unitView), specifier: decimalSpecifier)")