From 862f7d4f116add1cb86ac1345f1921a0810830d7 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 16 Jul 2016 13:55:22 -0700 Subject: [PATCH 1/3] Displaying the units when highlighting chart values, and re-using highlight views while panning. --- Loop.xcodeproj/project.pbxproj | 4 + Loop/Managers/StatusChartManager.swift | 53 ++++++++---- Loop/Models/ChartAxisValueDoubleLog.swift | 13 ++- Loop/Models/ChartAxisValueDoubleUnit.swift | 31 +++++++ Loop/Views/StatusChartHighlightLayer.swift | 98 ++++++++++++++-------- 5 files changed, 147 insertions(+), 52 deletions(-) create mode 100644 Loop/Models/ChartAxisValueDoubleUnit.swift diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 3ca077d245..972ae99ca4 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -126,6 +126,7 @@ 43EB40861C82646A00472A8C /* StatusChartManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EB40851C82646A00472A8C /* StatusChartManager.swift */; }; 43EB40C21C83F84900472A8C /* StatusChartHighlightLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EB40C11C83F84900472A8C /* StatusChartHighlightLayer.swift */; }; 43EDDBF31C361C75007D89B5 /* xDripG5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43EDDBF11C361C75007D89B5 /* xDripG5.framework */; }; + 43F41C331D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */; }; 43F4EF1D1BA2A57600526CE1 /* DiagnosticLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */; }; 43F5C2C91B929C09003EB13D /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F5C2C81B929C09003EB13D /* HealthKit.framework */; }; 43F5C2DB1B92A5E1003EB13D /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F5C2DA1B92A5E1003EB13D /* SettingsTableViewController.swift */; }; @@ -337,6 +338,7 @@ 43EDDBF51C361D24007D89B5 /* CommonCrypto.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = CommonCrypto.framework.dSYM; path = Carthage/Build/iOS/CommonCrypto.framework.dSYM; sourceTree = ""; }; 43EDDBF61C361D24007D89B5 /* xDripG5.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = xDripG5.framework.dSYM; path = Carthage/Build/iOS/xDripG5.framework.dSYM; sourceTree = ""; }; 43EDEE6B1CF2E12A00393BE3 /* Loop.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Loop.entitlements; sourceTree = ""; }; + 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartAxisValueDoubleUnit.swift; sourceTree = ""; }; 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiagnosticLogger.swift; sourceTree = ""; }; 43F5C2C81B929C09003EB13D /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 43F5C2D41B92A4A6003EB13D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -434,6 +436,7 @@ 43DE92601C555C26001FFDE1 /* AbsorptionTimeType+CarbKit.swift */, 438849EB1D29EC34003B3F23 /* AmplitudeService.swift */, 4331E0791C85650D00FBE832 /* ChartAxisValueDoubleLog.swift */, + 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */, 434F24CA1CFCB7AB0004498F /* GlucoseRxMessage.swift */, 436FACED1D0BA636004E2427 /* InsulinDataSource.swift */, 436A0DA41D236A2A00104B24 /* LoopError.swift */, @@ -953,6 +956,7 @@ 43776F901B8022E90074EA36 /* AppDelegate.swift in Sources */, 437CCADA1D284ADF0075D2C3 /* AuthenticationTableViewCell.swift in Sources */, 43CE7CDE1CA8B63E003CC1B0 /* NSDate.swift in Sources */, + 43F41C331D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift in Sources */, 43F5C2DB1B92A5E1003EB13D /* SettingsTableViewController.swift in Sources */, 43B371861CE583890013C5A6 /* BasalStateView.swift in Sources */, 434FF1EA1CF26C29000DB779 /* IdentifiableClass.swift in Sources */, diff --git a/Loop/Managers/StatusChartManager.swift b/Loop/Managers/StatusChartManager.swift index c664c218c2..02535069a0 100644 --- a/Loop/Managers/StatusChartManager.swift +++ b/Loop/Managers/StatusChartManager.swift @@ -73,23 +73,31 @@ class StatusChartsManager { var glucoseValues: [GlucoseValue] = [] { didSet { - glucosePoints = glucoseValues.map({ + // TODO: Use the preferred unit + let unit = HKUnit.milligramsPerDeciliterUnit() + let unitString = unit.glucoseUnitDisplayString + + glucosePoints = glucoseValues.map { return ChartPoint( x: ChartAxisValueDate(date: $0.startDate, formatter: dateFormatter), - y: ChartAxisValueDouble($0.quantity.doubleValueForUnit(HKUnit.milligramsPerDeciliterUnit())) + y: ChartAxisValueDoubleUnit($0.quantity.doubleValueForUnit(unit), unitString: unitString) ) - }) + } } } var predictedGlucoseValues: [GlucoseValue] = [] { didSet { - predictedGlucosePoints = predictedGlucoseValues.map({ + // TODO: Use the preferred unit + let unit = HKUnit.milligramsPerDeciliterUnit() + let unitString = unit.glucoseUnitDisplayString + + predictedGlucosePoints = predictedGlucoseValues.map { return ChartPoint( x: ChartAxisValueDate(date: $0.startDate, formatter: dateFormatter), - y: ChartAxisValueDouble($0.quantity.doubleValueForUnit(HKUnit.milligramsPerDeciliterUnit()), formatter: integerFormatter) + y: ChartAxisValueDoubleUnit($0.quantity.doubleValueForUnit(unit), unitString: unitString, formatter: integerFormatter) ) - }) + } } } @@ -98,7 +106,7 @@ class StatusChartsManager { IOBPoints = IOBValues.map { return ChartPoint( x: ChartAxisValueDate(date: $0.startDate, formatter: dateFormatter), - y: ChartAxisValueDouble($0.value, formatter: decimalFormatter) + y: ChartAxisValueDoubleUnit($0.value, unitString: "U", formatter: decimalFormatter) ) } } @@ -106,10 +114,13 @@ class StatusChartsManager { var COBValues: [CarbValue] = [] { didSet { + let unit = HKUnit.gramUnit() + let unitString = unit.unitString + COBPoints = COBValues.map { ChartPoint( x: ChartAxisValueDate(date: $0.startDate, formatter: dateFormatter), - y: ChartAxisValueDouble($0.quantity.doubleValueForUnit(HKUnit.gramUnit()), formatter: integerFormatter) + y: ChartAxisValueDoubleUnit($0.quantity.doubleValueForUnit(unit), unitString: unitString, formatter: integerFormatter) ) } } @@ -122,7 +133,7 @@ class StatusChartsManager { let startX = ChartAxisValueDate(date: entry.startDate, formatter: dateFormatter) let endX = ChartAxisValueDate(date: entry.endDate, formatter: dateFormatter) let zero = ChartAxisValueInt(0) - let value = ChartAxisValueDoubleLog(actualDouble: entry.value, formatter: decimalFormatter) + let value = ChartAxisValueDoubleLog(actualDouble: entry.value, unitString: "U/hour", formatter: decimalFormatter) let newPoints = [ ChartPoint(x: startX, y: zero), @@ -214,6 +225,14 @@ class StatusChartsManager { private var doseChart: Chart? + private var glucoseChartCache: ChartPointsTouchHighlightLayerViewCache? + + private var IOBChartCache: ChartPointsTouchHighlightLayerViewCache? + + private var COBChartCache: ChartPointsTouchHighlightLayerViewCache? + + private var doseChartCache: ChartPointsTouchHighlightLayerViewCache? + // MARK: - Generators func glucoseChartWithFrame(frame: CGRect) -> Chart? { @@ -275,7 +294,7 @@ class StatusChartsManager { prediction = ChartPointsScatterCirclesLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, chartPoints: predictedGlucosePoints, displayDelay: 0, itemSize: CGSize(width: 2, height: 2), itemFillColor: UIColor.glucoseTintColor.colorWithAlphaComponent(0.75)) } - let highlightLayer = StatusChartHighlightLayer( + glucoseChartCache = ChartPointsTouchHighlightLayerViewCache( xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, @@ -292,7 +311,7 @@ class StatusChartsManager { targetOverrideDurationLayer, xAxis, yAxis, - highlightLayer, + glucoseChartCache?.highlightLayer, prediction, circles ] @@ -356,7 +375,7 @@ class StatusChartsManager { return v }) - let highlightLayer = StatusChartHighlightLayer( + IOBChartCache = ChartPointsTouchHighlightLayerViewCache( xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, @@ -371,7 +390,7 @@ class StatusChartsManager { xAxis, yAxis, zeroGuidelineLayer, - highlightLayer, + IOBChartCache?.highlightLayer, IOBArea, IOBLine, ] @@ -425,7 +444,7 @@ class StatusChartsManager { let gridLayer = ChartGuideLinesLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, axis: .XAndY, settings: guideLinesLayerSettings, onlyVisibleX: true, onlyVisibleY: false) - let highlightLayer = StatusChartHighlightLayer( + COBChartCache = ChartPointsTouchHighlightLayerViewCache( xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, @@ -439,7 +458,7 @@ class StatusChartsManager { gridLayer, xAxis, yAxis, - highlightLayer, + COBChartCache?.highlightLayer, COBArea, COBLine ] @@ -492,7 +511,7 @@ class StatusChartsManager { return v }) - let highlightLayer = StatusChartHighlightLayer( + doseChartCache = ChartPointsTouchHighlightLayerViewCache( xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, @@ -507,7 +526,7 @@ class StatusChartsManager { xAxis, yAxis, zeroGuidelineLayer, - highlightLayer, + doseChartCache?.highlightLayer, doseArea, doseLine ] diff --git a/Loop/Models/ChartAxisValueDoubleLog.swift b/Loop/Models/ChartAxisValueDoubleLog.swift index a1d28e4794..8e413b926c 100644 --- a/Loop/Models/ChartAxisValueDoubleLog.swift +++ b/Loop/Models/ChartAxisValueDoubleLog.swift @@ -12,7 +12,9 @@ import SwiftCharts class ChartAxisValueDoubleLog: ChartAxisValueDoubleScreenLoc { - init(actualDouble: Double, formatter: NSNumberFormatter, labelSettings: ChartLabelSettings = ChartLabelSettings()) { + let unitString: String? + + init(actualDouble: Double, unitString: String? = nil, formatter: NSNumberFormatter, labelSettings: ChartLabelSettings = ChartLabelSettings()) { let screenLocDouble: Double switch actualDouble { @@ -24,6 +26,8 @@ class ChartAxisValueDoubleLog: ChartAxisValueDoubleScreenLoc { screenLocDouble = 0 } + self.unitString = unitString + super.init(screenLocDouble: screenLocDouble, actualDouble: actualDouble, formatter: formatter, labelSettings: labelSettings) } @@ -39,7 +43,14 @@ class ChartAxisValueDoubleLog: ChartAxisValueDoubleScreenLoc { actualDouble = 0 } + self.unitString = nil + super.init(screenLocDouble: screenLocDouble, actualDouble: actualDouble, formatter: formatter, labelSettings: labelSettings) } + override var description: String { + let suffix = unitString != nil ? " \(unitString!)" : "" + + return super.description + suffix + } } diff --git a/Loop/Models/ChartAxisValueDoubleUnit.swift b/Loop/Models/ChartAxisValueDoubleUnit.swift new file mode 100644 index 0000000000..3f0052797b --- /dev/null +++ b/Loop/Models/ChartAxisValueDoubleUnit.swift @@ -0,0 +1,31 @@ +// +// ChartAxisValueDoubleUnit.swift +// Loop +// +// Created by Nate Racklyeft on 7/16/16. +// Copyright © 2016 Nathan Racklyeft. All rights reserved. +// + +import UIKit +import SwiftCharts + + +class ChartAxisValueDoubleUnit: ChartAxisValueDouble { + let unitString: String + + init(_ double: Double, unitString: String, formatter: NSNumberFormatter) { + self.unitString = unitString + + super.init(double, formatter: formatter) + } + + init(_ double: Double, unitString: String) { + self.unitString = unitString + + super.init(double) + } + + override var description: String { + return "\(super.description) \(unitString)" + } +} diff --git a/Loop/Views/StatusChartHighlightLayer.swift b/Loop/Views/StatusChartHighlightLayer.swift index 914dc6ad69..cf188d6403 100644 --- a/Loop/Views/StatusChartHighlightLayer.swift +++ b/Loop/Views/StatusChartHighlightLayer.swift @@ -10,43 +10,71 @@ import Foundation import SwiftCharts -class StatusChartHighlightLayer: ChartPointsTouchHighlightLayer { - init( - xAxis: ChartAxisLayer, - yAxis: ChartAxisLayer, - innerFrame: CGRect, - chartPoints: [T], - tintColor: UIColor, - labelCenterY: CGFloat = 0, - gestureRecognizer: UIPanGestureRecognizer? = nil - ) { - super.init(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, chartPoints: chartPoints, gestureRecognizer: gestureRecognizer, - modelFilter: { (screenLoc, chartPointModels) -> ChartPointLayerModel? in +class ChartPointsTouchHighlightLayerViewCache { + private lazy var containerView = UIView(frame: .zero) + + private lazy var xAxisOverlayView = UIView() + + private lazy var point = ChartPointEllipseView(center: .zero, diameter: 16) + + private lazy var labelY: UILabel = { + let label = UILabel() + label.font = UIFont.monospacedDigitSystemFontOfSize(15, weight: UIFontWeightBold) + label.textAlignment = .Center + label.backgroundColor = UIColor.whiteColor() + + return label + }() + + private lazy var labelX: UILabel = { + let label = UILabel() + label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1) + label.textColor = UIColor.secondaryLabelColor + + return label + }() + + private(set) var highlightLayer: ChartPointsTouchHighlightLayer! + + init(xAxis: ChartAxisLayer, yAxis: ChartAxisLayer, innerFrame: CGRect, chartPoints: [ChartPoint], tintColor: UIColor, labelCenterY: CGFloat, gestureRecognizer: UIPanGestureRecognizer? = nil) { + + highlightLayer = ChartPointsTouchHighlightLayer( + xAxis: xAxis, + yAxis: yAxis, + innerFrame: innerFrame, + chartPoints: chartPoints, + gestureRecognizer: gestureRecognizer, + modelFilter: { (screenLoc, chartPointModels) -> ChartPointLayerModel? in if let index = chartPointModels.map({ $0.screenLoc.x }).findClosestElementIndexToValue(screenLoc.x) { return chartPointModels[index] } else { return nil } }, - viewGenerator: { (chartPointModel, layer, chart) -> U? in - let containerView = U(frame: chart.bounds) + viewGenerator: { [unowned self] (chartPointModel, layer, chart) -> UIView? in + let containerView = self.containerView + containerView.frame = chart.bounds + containerView.alpha = 1 // This is animated to 0 when touch last ended - let xAxisOverlayView = UIView(frame: xAxis.rect.offsetBy(dx: 0, dy: 1)) - xAxisOverlayView.backgroundColor = UIColor.whiteColor() - xAxisOverlayView.opaque = true - containerView.addSubview(xAxisOverlayView) + let xAxisOverlayView = self.xAxisOverlayView + if xAxisOverlayView.superview == nil { + xAxisOverlayView.frame = xAxis.rect.offsetBy(dx: 0, dy: 1) + xAxisOverlayView.backgroundColor = UIColor.whiteColor() + xAxisOverlayView.opaque = true + containerView.addSubview(xAxisOverlayView) + } - let point = ChartPointEllipseView(center: chartPointModel.screenLoc, diameter: 16) - point.fillColor = tintColor.colorWithAlphaComponent(0.5) - containerView.addSubview(point) + let point = self.point + point.center = chartPointModel.screenLoc + if point.superview == nil { + point.fillColor = tintColor.colorWithAlphaComponent(0.5) + containerView.addSubview(point) + } if let text = chartPointModel.chartPoint.y.labels.first?.text { - let label = UILabel() - label.font = UIFont.monospacedDigitSystemFontOfSize(15, weight: UIFontWeightBold) + let label = self.labelY label.text = text - label.textColor = tintColor - label.textAlignment = .Center label.sizeToFit() label.frame.size.height += 4 label.frame.size.width += label.frame.size.height / 2 @@ -54,29 +82,31 @@ class StatusChartHighlightLayer: ChartPointsTouchHighl label.center.x = chartPointModel.screenLoc.x label.frame.origin.x = min(max(label.frame.origin.x, innerFrame.origin.x), innerFrame.maxX - label.frame.size.width) label.frame.origin.makeIntegralInPlaceWithDisplayScale(chart.view.traitCollection.displayScale) - label.layer.borderColor = tintColor.CGColor - label.layer.borderWidth = 1 / chart.view.traitCollection.displayScale label.layer.cornerRadius = label.frame.size.height / 2 - label.backgroundColor = UIColor.whiteColor() + label.layer.borderWidth = 1 / max(1, chart.view.traitCollection.displayScale) + + if label.superview == nil { + label.textColor = tintColor + label.layer.borderColor = tintColor.CGColor - containerView.addSubview(label) + containerView.addSubview(label) + } } if let text = chartPointModel.chartPoint.x.labels.first?.text { - let label = UILabel() - label.font = UIFont.preferredFontForTextStyle(UIFontTextStyleCaption1) + let label = self.labelX label.text = text - label.textColor = UIColor.secondaryLabelColor label.sizeToFit() label.center = CGPoint(x: chartPointModel.screenLoc.x, y: xAxisOverlayView.center.y) label.frame.origin.makeIntegralInPlaceWithDisplayScale(chart.view.traitCollection.displayScale) - containerView.addSubview(label) + if label.superview == nil { + containerView.addSubview(label) + } } return containerView } ) - } } From 9dc486f60466240f1768adb5eb588a5bba329b67 Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 16 Jul 2016 22:33:59 -0700 Subject: [PATCH 2/3] git mv --- ...tLayer.swift => ChartPointsTouchHighlightLayerViewCache.swift} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Loop/Views/{StatusChartHighlightLayer.swift => ChartPointsTouchHighlightLayerViewCache.swift} (100%) diff --git a/Loop/Views/StatusChartHighlightLayer.swift b/Loop/Views/ChartPointsTouchHighlightLayerViewCache.swift similarity index 100% rename from Loop/Views/StatusChartHighlightLayer.swift rename to Loop/Views/ChartPointsTouchHighlightLayerViewCache.swift From b35b2aa7b1a694d376c9e84db30045c77657102b Mon Sep 17 00:00:00 2001 From: Nathan Racklyeft Date: Sat, 16 Jul 2016 23:54:49 -0700 Subject: [PATCH 3/3] Fixing project file --- Loop.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Loop.xcodeproj/project.pbxproj b/Loop.xcodeproj/project.pbxproj index 972ae99ca4..0c2f9a8d52 100644 --- a/Loop.xcodeproj/project.pbxproj +++ b/Loop.xcodeproj/project.pbxproj @@ -124,9 +124,9 @@ 43E344A61B9E1B3300C85C07 /* NSBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43E344A51B9E1B3300C85C07 /* NSBundle.swift */; }; 43E344A81B9EAA8400C85C07 /* RemoteSettings.plist in Resources */ = {isa = PBXBuildFile; fileRef = 43E344A71B9EAA8300C85C07 /* RemoteSettings.plist */; }; 43EB40861C82646A00472A8C /* StatusChartManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EB40851C82646A00472A8C /* StatusChartManager.swift */; }; - 43EB40C21C83F84900472A8C /* StatusChartHighlightLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43EB40C11C83F84900472A8C /* StatusChartHighlightLayer.swift */; }; 43EDDBF31C361C75007D89B5 /* xDripG5.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43EDDBF11C361C75007D89B5 /* xDripG5.framework */; }; 43F41C331D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */; }; + 43F41C351D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F41C341D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift */; }; 43F4EF1D1BA2A57600526CE1 /* DiagnosticLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */; }; 43F5C2C91B929C09003EB13D /* HealthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 43F5C2C81B929C09003EB13D /* HealthKit.framework */; }; 43F5C2DB1B92A5E1003EB13D /* SettingsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43F5C2DA1B92A5E1003EB13D /* SettingsTableViewController.swift */; }; @@ -332,13 +332,13 @@ 43E344A51B9E1B3300C85C07 /* NSBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSBundle.swift; sourceTree = ""; }; 43E344A71B9EAA8300C85C07 /* RemoteSettings.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = RemoteSettings.plist; sourceTree = ""; }; 43EB40851C82646A00472A8C /* StatusChartManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusChartManager.swift; sourceTree = ""; }; - 43EB40C11C83F84900472A8C /* StatusChartHighlightLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusChartHighlightLayer.swift; sourceTree = ""; }; 43EDDBF01C361C75007D89B5 /* CommonCrypto.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CommonCrypto.framework; path = Carthage/Build/iOS/CommonCrypto.framework; sourceTree = ""; }; 43EDDBF11C361C75007D89B5 /* xDripG5.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = xDripG5.framework; path = Carthage/Build/iOS/xDripG5.framework; sourceTree = ""; }; 43EDDBF51C361D24007D89B5 /* CommonCrypto.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = CommonCrypto.framework.dSYM; path = Carthage/Build/iOS/CommonCrypto.framework.dSYM; sourceTree = ""; }; 43EDDBF61C361D24007D89B5 /* xDripG5.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = xDripG5.framework.dSYM; path = Carthage/Build/iOS/xDripG5.framework.dSYM; sourceTree = ""; }; 43EDEE6B1CF2E12A00393BE3 /* Loop.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Loop.entitlements; sourceTree = ""; }; 43F41C321D3A17AA00C11ED6 /* ChartAxisValueDoubleUnit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartAxisValueDoubleUnit.swift; sourceTree = ""; }; + 43F41C341D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChartPointsTouchHighlightLayerViewCache.swift; sourceTree = ""; }; 43F4EF1C1BA2A57600526CE1 /* DiagnosticLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiagnosticLogger.swift; sourceTree = ""; }; 43F5C2C81B929C09003EB13D /* HealthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HealthKit.framework; path = System/Library/Frameworks/HealthKit.framework; sourceTree = SDKROOT; }; 43F5C2D41B92A4A6003EB13D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -614,13 +614,13 @@ 437CEEC91CD84DB7003C8C80 /* BatteryLevelHUDView.swift */, 437CCADB1D284B830075D2C3 /* ButtonTableViewCell.swift */, 434F54581D28805E002A9274 /* ButtonTableViewCell.xib */, + 43F41C341D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift */, 4346D1E61C77F5FE00ABAFE3 /* ChartTableViewCell.swift */, 437CEEBB1CD6DE6A003C8C80 /* HUDView.swift */, 437CEEBD1CD6E0CB003C8C80 /* LoopCompletionHUDView.swift */, 438DADC71CDE8F8B007697A5 /* LoopStateView.swift */, 437CEEC71CD84CBB003C8C80 /* ReservoirVolumeHUDView.swift */, 436FACEB1D0BA246004E2427 /* SegmentedControlTableViewCell.swift */, - 43EB40C11C83F84900472A8C /* StatusChartHighlightLayer.swift */, 43A5676A1C96155700334FAC /* SwitchTableViewCell.swift */, 434F54621D28DD80002A9274 /* ValidatingIndicatorView.swift */, ); @@ -976,12 +976,12 @@ 436FACEC1D0BA246004E2427 /* SegmentedControlTableViewCell.swift in Sources */, 43DBF0591C93F73800B3C386 /* CarbEntryTableViewController.swift in Sources */, 43DE925C1C547A20001FFDE1 /* WatchContext.swift in Sources */, + 43F41C351D3B623800C11ED6 /* ChartPointsTouchHighlightLayerViewCache.swift in Sources */, 43EB40861C82646A00472A8C /* StatusChartManager.swift in Sources */, 437CEEC81CD84CBB003C8C80 /* ReservoirVolumeHUDView.swift in Sources */, 43C0944A1CACCC73001F6403 /* NotificationManager.swift in Sources */, 434FF1EE1CF27EEF000DB779 /* UITableViewCell.swift in Sources */, 438849EA1D297CB6003B3F23 /* NightscoutService.swift in Sources */, - 43EB40C21C83F84900472A8C /* StatusChartHighlightLayer.swift in Sources */, 437CCADC1D284B830075D2C3 /* ButtonTableViewCell.swift in Sources */, 4315D2871CA5CC3B00589052 /* CarbEntryEditTableViewController.swift in Sources */, 4331E0781C85302200FBE832 /* CGPoint.swift in Sources */,