@@ -27,6 +27,7 @@ enum GraphDataIndex: Int {
2727 case smb = 16
2828 case tempTarget = 17
2929 case predictionCone = 18
30+ case smoothedBg = 19
3031}
3132
3233extension GraphDataIndex {
@@ -51,6 +52,7 @@ extension GraphDataIndex {
5152 case . smb: return " SMB "
5253 case . tempTarget: return " Temp Target "
5354 case . predictionCone: return " Prediction Cone "
55+ case . smoothedBg: return " Smoothed BG "
5456 }
5557 }
5658}
@@ -622,6 +624,20 @@ extension MainViewController {
622624 lineCone. axisDependency = YAxis . AxisDependency. right
623625 data. append ( lineCone)
624626
627+ // Dataset 19: Smoothed BG line — light-grey straight segments connecting
628+ // Trio's smoothed values, no dots. Populated only when displaySmoothedBG
629+ // is on. Linear mode (passes through each value Trio reported, no curve
630+ // interpolation).
631+ let lineSmoothedBg = LineChartDataSet ( entries: [ ChartDataEntry] ( ) , label: " " )
632+ lineSmoothedBg. setColor ( NSUIColor . lightGray)
633+ lineSmoothedBg. lineWidth = 1.5
634+ lineSmoothedBg. drawCirclesEnabled = false
635+ lineSmoothedBg. drawValuesEnabled = false
636+ lineSmoothedBg. highlightEnabled = false
637+ lineSmoothedBg. axisDependency = YAxis . AxisDependency. right
638+ lineSmoothedBg. mode = . linear
639+ data. append ( lineSmoothedBg)
640+
625641 data. setValueFont ( UIFont . systemFont ( ofSize: 12 ) )
626642
627643 // Add marker popups for bolus and carbs
@@ -772,20 +788,17 @@ extension MainViewController {
772788 let dataIndexPrediction = 1
773789 let lineBG = BGChart . lineData!. dataSets [ dataIndex] as! LineChartDataSet
774790 let linePrediction = BGChart . lineData!. dataSets [ dataIndexPrediction] as! LineChartDataSet
775- if Storage . shared. showLines. value {
776- lineBG. lineWidth = 2
777- linePrediction. lineWidth = 2
778- } else {
791+ // When smoothing is on, BG renders dots-only (the white smoothing line replaces
792+ // the BG connecting line). The user-controlled toggles only apply when off.
793+ if Storage . shared. displaySmoothedBG. value {
779794 lineBG. lineWidth = 0
780- linePrediction. lineWidth = 0
781- }
782- if Storage . shared. showDots. value {
783795 lineBG. drawCirclesEnabled = true
784- linePrediction. drawCirclesEnabled = true
785796 } else {
786- lineBG. drawCirclesEnabled = false
787- linePrediction . drawCirclesEnabled = false
797+ lineBG. lineWidth = Storage . shared . showLines . value ? 2 : 0
798+ lineBG . drawCirclesEnabled = Storage . shared . showDots . value
788799 }
800+ linePrediction. lineWidth = Storage . shared. showLines. value ? 2 : 0
801+ linePrediction. drawCirclesEnabled = Storage . shared. showDots. value
789802
790803 BGChart . rightAxis. axisMinimum = 0
791804
@@ -833,6 +846,7 @@ extension MainViewController {
833846
834847 topBG = Storage . shared. minBGScale. value
835848 let thresholds = graphRangeThresholds ( )
849+ let showSmoothed = Storage . shared. displaySmoothedBG. value
836850 for i in 0 ..< entries. count {
837851 // Clamp the plotted y-value to the same bounds the header text uses
838852 // (HIGH/LOW), so the graph stays consistent with the main display.
@@ -841,7 +855,15 @@ extension MainViewController {
841855 if plottedSgv > topBG - maxBGOffset {
842856 topBG = plottedSgv + maxBGOffset
843857 }
844- let value = ChartDataEntry ( x: Double ( entries [ i] . date) , y: plottedSgv, data: formatPillText ( line1: Localizer . toDisplayUnits ( String ( entries [ i] . sgv) ) , time: entries [ i] . date) )
858+ let cgmLine = Localizer . toDisplayUnits ( String ( entries [ i] . sgv) )
859+ // When the smoothed BG is available, render it ABOVE the raw CGM line.
860+ let pillText : String
861+ if showSmoothed, let smoothed = smoothedBg ( near: entries [ i] . date) {
862+ pillText = formatPillText ( line1: " ✨ \( Localizer . toDisplayUnits ( String ( smoothed) ) ) ✨ " , time: entries [ i] . date, line2: cgmLine)
863+ } else {
864+ pillText = formatPillText ( line1: cgmLine, time: entries [ i] . date)
865+ }
866+ let value = ChartDataEntry ( x: Double ( entries [ i] . date) , y: plottedSgv, data: pillText)
845867 mainChart. append ( value)
846868 smallChart. append ( value)
847869
@@ -872,13 +894,54 @@ extension MainViewController {
872894 }
873895 }
874896
897+ // When smoothing is on, force the main BG dataset to render dots-only (no
898+ // connecting line) so the smoothing line is the only line drawn through
899+ // the readings. When off, honor the user's Display Lines/Dots toggles.
900+ // The small chart keeps its original line-only style (set at creation in
901+ // createSmallBGGraph) so we don't touch lineBGSmall here.
902+ if showSmoothed {
903+ lineBG. lineWidth = 0
904+ lineBG. drawCirclesEnabled = true
905+ } else {
906+ lineBG. lineWidth = Storage . shared. showLines. value ? 2 : 0
907+ lineBG. drawCirclesEnabled = Storage . shared. showDots. value
908+ }
909+
910+ // Populate the smoothed-BG line dataset on the main chart only.
911+ // We iterate `smoothedBgData` directly so the line always extends to the
912+ // most recent smoothed value Trio has reported. To avoid the line being
913+ // pulled toward bolus / carb dots (Trio writes extra openaps records on
914+ // every treatment-triggered loop run, with timestamps that can land
915+ // between the regular 5-minute cycles), we skip any record that lands
916+ // within 4 minutes of the previously kept one. Regular runs are ~5 min
917+ // apart so they pass through; treatment-triggered runs that fire shortly
918+ // after a regular one are filtered out.
919+ let smoothedIndex = GraphDataIndex . smoothedBg. rawValue
920+ if let mainSmoothed = BGChart . lineData? . dataSets [ smoothedIndex] as? LineChartDataSet {
921+ mainSmoothed. removeAll ( keepingCapacity: false )
922+ if showSmoothed, !smoothedBgData. isEmpty {
923+ let firstBgTime = entries. first? . date ?? - . infinity
924+ let lastBgTime = entries. last? . date ?? . infinity
925+ let minSpacing : TimeInterval = 240
926+ var lastKeptTime : TimeInterval = - . infinity
927+ for sb in smoothedBgData where sb. time >= firstBgTime && sb. time <= lastBgTime + 150 {
928+ if sb. time - lastKeptTime < minSpacing { continue }
929+ let plotted = min ( max ( sb. bgMgdl, Double ( globalVariables. minDisplayGlucose) ) , Double ( globalVariables. maxDisplayGlucose) )
930+ mainSmoothed. append ( ChartDataEntry ( x: sb. time, y: plotted) )
931+ lastKeptTime = sb. time
932+ }
933+ }
934+ }
935+
875936 BGChart . rightAxis. axisMaximum = Double ( calculateMaxBgGraphValue ( ) )
876937 BGChart . setVisibleXRangeMinimum ( 600 )
877938 BGChart . data? . dataSets [ dataIndex] . notifyDataSetChanged ( )
939+ BGChart . data? . dataSets [ smoothedIndex] . notifyDataSetChanged ( )
878940 BGChart . data? . notifyDataChanged ( )
879941 BGChart . notifyDataSetChanged ( )
880942 BGChartFull . rightAxis. axisMaximum = Double ( calculateMaxBgGraphValue ( ) )
881943 BGChartFull . data? . dataSets [ dataIndex] . notifyDataSetChanged ( )
944+ BGChartFull . data? . dataSets [ smoothedIndex] . notifyDataSetChanged ( )
882945 BGChartFull . data? . notifyDataChanged ( )
883946 BGChartFull . notifyDataSetChanged ( )
884947
@@ -1649,6 +1712,17 @@ extension MainViewController {
16491712 lineConeSmall. axisDependency = YAxis . AxisDependency. right
16501713 data. append ( lineConeSmall)
16511714
1715+ // Dataset 19: Smoothed BG line on the small graph too.
1716+ let lineSmoothedBgSmall = LineChartDataSet ( entries: [ ChartDataEntry] ( ) , label: " " )
1717+ lineSmoothedBgSmall. setColor ( NSUIColor . lightGray)
1718+ lineSmoothedBgSmall. lineWidth = 1.0
1719+ lineSmoothedBgSmall. drawCirclesEnabled = false
1720+ lineSmoothedBgSmall. drawValuesEnabled = false
1721+ lineSmoothedBgSmall. highlightEnabled = false
1722+ lineSmoothedBgSmall. axisDependency = YAxis . AxisDependency. right
1723+ lineSmoothedBgSmall. mode = . cubicBezier
1724+ data. append ( lineSmoothedBgSmall)
1725+
16521726 BGChartFull . highlightPerDragEnabled = true
16531727 BGChartFull . leftAxis. enabled = false
16541728 BGChartFull . leftAxis. axisMaximum = maxBasal
0 commit comments