I'm attempting to create a word map that shows the words without overlapping without bloating the code load. how would you do it and why? I'm also open to handling this in other ways beside a geo reader.
let description = trigger.description.lowercased()
let wordsWithoutPunctuation = description.components(separatedBy: CharacterSet.punctuationCharacters).joined()
let words = wordsWithoutPunctuation.components(separatedBy: " ")
let determiners = ["the", "a", "an", "this", "that", "these", "those", "my", "your", "and", "her", "its", "our", "to"]
let filteredWords = words.filter { !determiners.contains($0) }
let wordCounts = Dictionary(grouping: filteredWords, by: { $0 }).mapValues { $0.count }
let sortedWords = wordCounts.sorted { $1.value < $0.value }
let topWords = Array(sortedWords.prefix(5))
let maxCount = topWords.first?.value ?? 1
GeometryReader { geometry in
ZStack {
ForEach(topWords, id: \.key) { word in
let wordSize = "\(word.key) (\(word.value))".size(withAttributes: [.font: UIFont.systemFont(ofSize: min(CGFloat(word.value) / CGFloat(maxCount) * 30, 30))])
Text("\(word.key) (\(word.value))")
.foregroundColor(.BrandGreen)
.font(.system(size: min(CGFloat(word.value) / CGFloat(maxCount) * 30, 30))) // Adjust the multiplier and maximum size as needed
.position(
x: CGFloat.random(in: wordSize.width / 2..<geometry.size.width - wordSize.width / 2),
y: CGFloat.random(in: wordSize.height / 2..<geometry.size.height - wordSize.height / 2)
)
}
}
}
}
.frame(width: 180, height: 180)
.padding(5)
.background(Color.harp)
.cornerRadius(30)
.aspectRatio(1, contentMode: .fit)
.clipShape(RoundedRectangle(cornerRadius: 30))
.shadow(color: Color.black.opacity(0.2), radius: 5, x: 0, y: 0)