iBook/ipad_app/Sources/Views/Components/BubbleMetricsView.swift

53 lines
1.9 KiB
Swift

#if os(iOS)
import SwiftUI
@available(macOS 10.15, iOS 13.0, *)
struct BubbleMetric: Identifiable {
let id = UUID()
let label: String
let display: String
let valueMinutes: Double //
let color: Color
}
@available(macOS 10.15, iOS 13.0, *)
struct BubbleMetricsView: View {
let metrics: [BubbleMetric]
private func radius(for v: Double, maxV: Double) -> CGFloat {
guard maxV > 0 else { return 20 }
let norm = sqrt(v / maxV)
return 30 + norm * 70
}
var body: some View {
GeometryReader { geo in
let maxV = metrics.map { $0.valueMinutes }.max() ?? 1
ZStack {
ForEach(Array(metrics.enumerated()), id: \.[1].id) { idx, m in
//
let angle = Double(idx) / Double(metrics.count) * Double.pi * 2
let R = min(geo.size.width, geo.size.height) / 2 - 80
let x = geo.size.width/2 + CGFloat(cos(angle)) * R
let y = geo.size.height/2 + CGFloat(sin(angle)) * R
let r = radius(for: m.valueMinutes, maxV: maxV)
Circle()
.fill(m.color.opacity(0.75))
.frame(width: r, height: r)
.overlay(
VStack(spacing:4){
Text(m.display).font(.system(size: min(18, r*0.28))).bold().foregroundColor(.white)
Text(m.label).font(.system(size: min(14, r*0.22))).foregroundColor(.white)
}.padding(4)
)
.position(x: x, y: y)
.shadow(radius: 4, y: 2)
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
.frame(height: 340)
}
}
#endif