Feedback TestFlight build 58 (build 59): labels, needs-update, period selector, Home masonry
De 7 comentarios de TestFlight: - Labels de línea ilegibles (puntos 5+7): ChartLabels.showsLabel thin-out (máx 5 iPhone / 8 iPad, siempre primero y último). Charts multi-serie (Compare, Period, Year vs Year) etiquetan solo el ENDPOINT de cada serie. Prediction etiqueta solo el forecast final. Aplicado a Evolution, Rolling, Drawdown, Volatility, Compare, Period, YoY, Prediction. - 'Needs update' en meses pasados (punto 2): MonthlyCheckInView.snapshotForViewedMonth — el estado es por el MES QUE SE VE (effective month de referenceDate), no contra la última completion global. Diff usa el snapshot de ese mes. - Selector de periodo Performance (punto 6): slider 1..60 → picker segmentado consistente con el resto, opciones capadas a los meses de datos disponibles (availableHistoryMonths). Ya no deja pedir ventanas sin datos. - Home iPad/Mac (feedback previo): masonry con nº de columnas según ancho (2 iPad / 3 Mac ancho >=1250), reparto por peso, propio ScrollView. Pendiente de este lote: Goals no sincronizan (verificado modelo Goal CloudKit-OK → es el subset del partial-failure, no filtro ni esquema; necesita códigos internos del error), paste/OCR por campo (punto 3) y swipe entre charts (punto 4). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WoScpmHdVj1aUf4rAp6hbe
This commit is contained in:
@@ -6,10 +6,6 @@ struct PeriodComparisonChartView: View {
|
||||
@State private var selectedMonth: Int?
|
||||
|
||||
/// Period charts are short by design (a handful of months) — labels always help.
|
||||
private var showAllLabels: Bool {
|
||||
(viewModel.periodComparisonData.map { $0.points.count }.max() ?? 0) <= ChartLabels.alwaysShowThreshold
|
||||
}
|
||||
|
||||
private func selectionRows(for month: Int) -> [(label: String, value: String, color: Color)] {
|
||||
viewModel.periodComparisonData.compactMap { series in
|
||||
guard let point = series.points.first(where: { $0.monthOffset == month }) else { return nil }
|
||||
@@ -217,8 +213,18 @@ struct PeriodComparisonChartView: View {
|
||||
return result
|
||||
}
|
||||
|
||||
/// Last month offset per series — used to label only each series' endpoint.
|
||||
private var lastOffsetBySeries: [String: Int] {
|
||||
var m: [String: Int] = [:]
|
||||
for s in viewModel.periodComparisonData {
|
||||
m[s.id] = s.points.map(\.monthOffset).max()
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
private var periodChart: some View {
|
||||
let points = flatPoints
|
||||
let endpoints = lastOffsetBySeries
|
||||
let seriesIds = viewModel.periodComparisonData.map { $0.id }
|
||||
let seriesColors: [Color] = viewModel.periodComparisonData.map {
|
||||
Color(hex: $0.colorHex) ?? .gray
|
||||
@@ -240,10 +246,10 @@ struct PeriodComparisonChartView: View {
|
||||
y: .value("Return", point.returnPct)
|
||||
)
|
||||
.foregroundStyle(by: .value("Period", point.seriesLabel))
|
||||
.symbolSize(showAllLabels ? 40 : 30)
|
||||
.symbolSize(point.monthOffset == endpoints[point.seriesId] ? 38 : 22)
|
||||
.annotation(position: point.seriesLabel == viewModel.periodComparisonData.first?.label ? .top : .bottom,
|
||||
spacing: 3) {
|
||||
if showAllLabels {
|
||||
if point.monthOffset == endpoints[point.seriesId] {
|
||||
ChartValueBubble(
|
||||
text: ChartLabels.percent(point.returnPct),
|
||||
color: Color(hex: point.colorHex) ?? .gray
|
||||
|
||||
Reference in New Issue
Block a user