Задача
Я создаю гистограмму с помощью SwiftUI, и я ищу лучший подход для позиционирования среднего индикатора, горизонтальной желтой линии, показанной на рисунке ниже:

Цель
Мне нужно иметь возможность расположить желтую линию (прямоугольник с 1 точкой по высоте) относительно столбцов (также прямоугольников) графика. Для простоты давайте представим, что самый высокий возможный столб - 100 пунктов, а средний - 75. Моя цель - нарисовать желтую линию ровно на 75 пунктов выше дна столбцов.
Проблема
В моем примере я размещаю линию сверху графика с использованием ZStack. Я могу расположить линию вертикально, используя GeometryReader, однако я не знаю, как расположить ее относительно нижней части столбцов.
Вот мой код игровой площадки:
import SwiftUI
import PlaygroundSupport
struct BarChart: View {
var measurements : [Int]
var pastColor: Color
var todayColor: Color
var futureColor: Color
let labelsColor = Color(UIColor(white: 0.5, alpha: 1.0))
func monthAbbreviationFromInt(_ day: Int) -> String {
let da = Calendar.current.shortWeekdaySymbols
return da[day]
}
var body: some View {
ZStack {
VStack {
HStack {
Rectangle()
.fill(Color.yellow)
.frame(width: 12, height: 2, alignment: .center)
Text("Desired level")
.font(.custom("Helvetica", size: 10.0))
.foregroundColor(labelsColor)
}
.padding(.bottom , 50.0)
HStack {
ForEach(0..<7) { day in
VStack {
Spacer()
Text(String(self.measurements[day]))
.frame(width: CGFloat(40), height: CGFloat(20))
.font(.footnote)
.lineLimit(1)
.minimumScaleFactor(0.5)
.foregroundColor(self.labelsColor)
Rectangle()
.fill(day > 0 ? self.futureColor : self.pastColor)
.frame(width: 20, height: CGFloat(self.measurements[day]*2))
.transition(.slide)
.cornerRadius(3.0)
Text("\(self.monthAbbreviationFromInt(day))\n\(day)")
.multilineTextAlignment(.center)
.font(.footnote)
.frame(height: 20)
.lineLimit(2)
.minimumScaleFactor(0.2)
.foregroundColor(self.labelsColor)
}
.frame(height: 200, alignment: .bottom )
}
}
}
.padding()
VStack {
GeometryReader { geometry in
//Yellow line
Rectangle()
.path(in: CGRect(x: 0,
y: 350, //This is now a random value, but I should detect and use the bottom coordinate of the bars to place the line at exactly 75 points above that coordinate
width: geometry.size.width,
height: 1))
.fill(Color.yellow)
}
}
}
}
}
Как узнать относительное положение нижней части стержней, чтобы я мог правильно расположить линию?
Есть ли другой подход вы бы предложили?
Заранее спасибо