| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- import Combine
- import Foundation
- import SwiftUI
- import Swinject
- struct TagCloudView: View {
- var tags: [String]
- var shouldParseToMmolL: Bool
- @State private var totalHeight
- // = CGFloat.zero // << variant for ScrollView/List
- = CGFloat.infinity // << variant for VStack
- var body: some View {
- VStack {
- GeometryReader { geometry in
- self.generateContent(in: geometry)
- }
- }
- // .frame(height: totalHeight)// << variant for ScrollView/List
- .frame(maxHeight: totalHeight) // << variant for VStack
- }
- private func generateContent(in g: GeometryProxy) -> some View {
- var width = CGFloat.zero
- var height = CGFloat.zero
- return ZStack(alignment: .topLeading) {
- ForEach(self.tags, id: \.self) { tag in
- self.item(for: tag, isMmolL: shouldParseToMmolL)
- .padding([.horizontal, .vertical], 2)
- .alignmentGuide(.leading, computeValue: { d in
- if abs(width - d.width) > g.size.width
- {
- width = 0
- height -= d.height
- }
- let result = width
- if tag == self.tags.last! {
- width = 0 // last item
- } else {
- width -= d.width
- }
- return result
- })
- .alignmentGuide(.top, computeValue: { _ in
- let result = height
- if tag == self.tags.last! {
- height = 0 // last item
- }
- return result
- })
- }
- }.background(viewHeightReader($totalHeight))
- }
- // private func item(for textTag: String) -> some View {
- // var colorOfTag: Color {
- // switch textTag {
- // case textTag where textTag.contains("SMB Delivery Ratio:"):
- // return .uam
- // case textTag where textTag.contains("Bolus"):
- // return .green
- // case textTag where textTag.contains("TDD:"),
- // textTag where textTag.contains("tdd_factor"),
- // textTag where textTag.contains("Sigmoid function"),
- // textTag where textTag.contains("Logarithmic formula"),
- // textTag where textTag.contains("AF:"),
- // textTag where textTag.contains("Autosens/Dynamic Limit:"),
- // textTag where textTag.contains("Dynamic ISF/CR"),
- // textTag where textTag.contains("Basal ratio"),
- // textTag where textTag.contains("SMB Ratio"):
- // return .zt
- // case textTag where textTag.contains("Middleware:"):
- // return .red
- // case textTag where textTag.contains("SMB Ratio"):
- // return .orange
- // default:
- // return .insulin
- // }
- // }
- //
- // return ZStack { Text(textTag)
- // .padding(.vertical, 2)
- // .padding(.horizontal, 4)
- // .font(.subheadline)
- // .background(colorOfTag.opacity(0.8))
- // .foregroundColor(Color.white)
- // .cornerRadius(2) }
- // }
- private func item(for textTag: String, isMmolL: Bool) -> some View {
- var colorOfTag: Color {
- switch textTag {
- case textTag where textTag.contains("SMB Delivery Ratio:"):
- return .uam
- case textTag where textTag.contains("Bolus"):
- return .green
- case textTag where textTag.contains("TDD:"),
- textTag where textTag.contains("tdd_factor"),
- textTag where textTag.contains("Sigmoid function"),
- textTag where textTag.contains("Logarithmic formula"),
- textTag where textTag.contains("AF:"),
- textTag where textTag.contains("Autosens/Dynamic Limit:"),
- textTag where textTag.contains("Dynamic ISF/CR"),
- textTag where textTag.contains("Basal ratio"),
- textTag where textTag.contains("SMB Ratio"):
- return .zt
- case textTag where textTag.contains("Middleware:"):
- return .red
- case textTag where textTag.contains("SMB Ratio"):
- return .orange
- default:
- return .insulin
- }
- }
- func formattedTextTag(for tag: String) -> String {
- // List of glucose-related tags
- let glucoseTags = ["ISF:", "Target:", "minPredBG", "minGuardBG", "IOBpredBG", "COBpredBG", "UAMpredBG", "Dev:"]
- var updatedTag = tag
- // Apply conversion if necessary
- for glucoseTag in glucoseTags {
- if glucoseTag == "ISF:" {
- // Handle the special ISF case with the arrow
- if let range = updatedTag.range(of: "\(glucoseTag)\\s*\\d+→\\d+", options: .regularExpression) {
- let glucoseValueString = updatedTag[range]
- let values = glucoseValueString.components(separatedBy: "→")
- if let firstValue = Double(
- values[0]
- .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
- ),
- let secondValue = Double(
- values[1]
- .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
- )
- {
- let formattedFirstValue = isMmolL ? Double(firstValue.asMmolL) : firstValue
- let formattedSecondValue = isMmolL ? Double(secondValue.asMmolL) : secondValue
- let formattedGlucoseValueString =
- "\(glucoseTag) \(formattedFirstValue)→\(formattedSecondValue)"
- updatedTag = updatedTag.replacingOccurrences(
- of: glucoseValueString,
- with: formattedGlucoseValueString
- )
- }
- }
- } else {
- // General case for other glucose tags
- if let range = updatedTag.range(of: "\(glucoseTag)\\s*\\d+", options: .regularExpression) {
- let glucoseValueString = updatedTag[range]
- if let glucoseValue = Double(
- glucoseValueString
- .components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
- ) {
- let formattedValue = isMmolL ? Double(glucoseValue.asMmolL) : glucoseValue
- updatedTag = updatedTag.replacingOccurrences(
- of: glucoseValueString,
- with: "\(glucoseTag) \(formattedValue)"
- )
- }
- }
- }
- }
- return updatedTag
- }
- let formattedTextTag = formattedTextTag(for: textTag)
- return ZStack {
- Text(formattedTextTag)
- .padding(.vertical, 2)
- .padding(.horizontal, 4)
- .font(.subheadline)
- .background(colorOfTag.opacity(0.8))
- .foregroundColor(Color.white)
- .cornerRadius(2)
- }
- }
- private func viewHeightReader(_ binding: Binding<CGFloat>) -> some View {
- GeometryReader { geometry -> Color in
- let rect = geometry.frame(in: .local)
- DispatchQueue.main.async {
- binding.wrappedValue = rect.size.height
- }
- return .clear
- }
- }
- }
- struct TestTagCloudView: View {
- var body: some View {
- VStack {
- Text("Header").font(.largeTitle)
- TagCloudView(
- tags: ["Ninetendo", "XBox", "PlayStation", "PlayStation 2", "PlayStation 3", "PlayStation 4"],
- shouldParseToMmolL: false
- )
- Text("Some other text")
- Divider()
- Text("Some other cloud")
- TagCloudView(tags: ["Apple", "Google", "Amazon", "Microsoft", "Oracle", "Facebook"], shouldParseToMmolL: false)
- }
- }
- }
|