|
|
@@ -54,8 +54,10 @@ extension MainChartView {
|
|
|
}
|
|
|
|
|
|
func combinedYDomain() -> ClosedRange<Double> {
|
|
|
- let minValue = min(state.minValueCobChart, state.minValueIobChart)
|
|
|
- let maxValue = max(state.maxValueCobChart, state.maxValueIobChart)
|
|
|
+ let iobMin = scaleIobAmountForChart(state.minValueIobChart)
|
|
|
+ let iobMax = scaleIobAmountForChart(state.maxValueIobChart)
|
|
|
+ let minValue = min(state.minValueCobChart, iobMin)
|
|
|
+ let maxValue = max(state.maxValueCobChart, iobMax)
|
|
|
return Double(minValue) ... Double(maxValue)
|
|
|
}
|
|
|
|
|
|
@@ -79,6 +81,17 @@ extension MainChartView {
|
|
|
.position(by: .value("Axis", axis))
|
|
|
}
|
|
|
|
|
|
+ /// Scales IOB amounts for chart display.
|
|
|
+ ///
|
|
|
+ /// As IOB and COB share the same Y axis and COB is usually >> IOB,
|
|
|
+ /// we need to visually weigh IOB by multiplying it by a scaling factor:
|
|
|
+ ///
|
|
|
+ /// - Parameter rawAmount: The unscaled IOB amount
|
|
|
+ /// - Returns: The scaled IOB amount for visual representation
|
|
|
+ private func scaleIobAmountForChart<T: Numeric & Comparable>(_ rawAmount: T) -> T where T: ExpressibleByIntegerLiteral {
|
|
|
+ rawAmount > 0 ? rawAmount * 8 : rawAmount * 9
|
|
|
+ }
|
|
|
+
|
|
|
func drawCOBIOBChart() -> some ChartContent {
|
|
|
// Filter out duplicate entries by `deliverAt`,
|
|
|
// We sometimes get two determinations when editing carbs, one without the entry-to-be-edited and then another one after editing the entry.
|
|
|
@@ -115,9 +128,7 @@ extension MainChartView {
|
|
|
// MARK: - IOB line and area mark
|
|
|
|
|
|
let rawAmount = item.iob?.doubleValue ?? 0
|
|
|
-
|
|
|
- // as iob and cob share the same y axis and cob is usually >> iob we need to weigh iob visually
|
|
|
- let amountIOB: Double = rawAmount > 0 ? rawAmount * 8 : rawAmount * 9
|
|
|
+ let amountIOB: Double = scaleIobAmountForChart(rawAmount)
|
|
|
|
|
|
AreaMark(x: .value("Time", date), y: .value("Amount", amountIOB))
|
|
|
.foregroundStyle(by: .value("Type", "IOB"))
|