refactor(Turnips): use Alignment Guide for Chart Bottom Legend
MODIFY
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChart.swift
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChart.swift
@@ -41,7 +41,7 @@ extension Array where Element == [Int] {
private func minMaxAndRatios(
rect: CGRect
) -> (min: CGFloat, max: CGFloat, ratioY: CGFloat, ratioX: CGFloat) {
- let ratioX = rect.maxX/(CGFloat(self.count) - 1)
+ let ratioX = rect.maxX/(CGFloat(self.count - 1))
let min: CGFloat = self
.compactMap { $0.first }

MODIFY
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChartBottomLegendView.swift
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChartBottomLegendView.swift
@@ -14,40 +14,52 @@ struct TurnipsChartBottomLegendView: View {
private let weekdays = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
var body: some View {
- GeometryReader(content: texts)
+ GeometryReader(content: computeTexts)
}
- func texts(for geometry: GeometryProxy) -> some View {
- let frame = geometry.frame(in: .local)
- let (_, _, _, ratioX) = predictions.minMax?.roundedMinMaxAndRatios(rect: frame) ?? (0, 0, 0, 0)
+ func computeTexts(for geometry: GeometryProxy) -> some View {
+ let rect = geometry.frame(in: .local)
+ let (_, _, _, ratioX) = predictions.minMax?.roundedMinMaxAndRatios(rect: rect) ?? (0, 0, 0, 0)
let count = predictions.minMax?.count ?? 0
+ return texts(count: count, ratioX: ratioX)
+ }
- return VStack {
- ZStack {
+ func texts(count: Int, ratioX: CGFloat) -> some View {
+ VStack {
+ ZStack(alignment: .leading) {
ForEach(0..<count) { offset in
- self.yAxisText(offset: offset, ratioX: ratioX, frame: frame)
+ self.meridiem(offset: offset, ratioX: ratioX)
}
}
- ZStack {
+ ZStack(alignment: .leading) {
ForEach(Array(weekdays.enumerated()), id: \.0) { offset, weekday in
- // TODO: investigate AlignmentGuide instead of guessing the exact position
- Text(weekday)
- .font(.callout)
- .fontWeight(.bold)
- .foregroundColor(.text)
- .position(x: CGFloat(offset + 1) * ratioX/2 + CGFloat(offset) * ratioX * 1.5, y: frame.midY)
+ self.weekdays(offset: offset, weekday: weekday, ratioX: ratioX)
}
}
}
}
- // TODO: investigate AlignmentGuide instead of guessing the exact position
- func yAxisText(offset: Int, ratioX: CGFloat, frame: CGRect) -> some View {
- let isAM = offset == 0 || offset.isMultiple(of: 2)
- return Text(isAM ? "AM" : "PM")
+ func meridiem(offset: Int, ratioX: CGFloat) -> some View {
+ Text(offset.isAM ? "AM" : "PM")
.font(.footnote)
.fontWeight(.semibold)
.foregroundColor(.text)
- .position(x: CGFloat(offset) * ratioX, y: frame.midY)
+ .alignmentGuide(.leading, computeValue: { d in
+ -CGFloat(offset) * ratioX
+ })
}
+
+ func weekdays(offset: Int, weekday: String, ratioX: CGFloat) -> some View {
+ Text(weekday)
+ .font(.callout)
+ .fontWeight(.bold)
+ .foregroundColor(.text)
+ .alignmentGuide(.leading, computeValue: { d in
+ -CGFloat(offset * 2 + 1) * ratioX + d.width/2
+ })
+ }
+}
+
+private extension Int {
+ var isAM: Bool { self == 0 || isMultiple(of: 2) }
}

MODIFY
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChartView.swift
ACHNBrowserUI/ACHNBrowserUI/views/turnips/charts/TurnipsChartView.swift
@@ -27,13 +27,13 @@ struct TurnipsChartView: View {
private var chart: some View {
VStack(spacing: 10) {
- HStack {
+ HStack(spacing: 8) {
TurnipsChartVerticalLegend(predictions: predictions)
.frame(width: 30)
curves
}
TurnipsChartBottomLegendView(predictions: predictions)
- .padding(.leading, 30)
+ .padding(.leading, 38)
.frame(height: 50)
}.padding()
}

refactor(Turnips): use Alignment Guide for Chart Bottom Legend