Reputation: 31
I have 2 line charts in SwiftCharts that show the user's time asleep and total time in bed. When you first see the chart, it looks normal, but when you click on the different buttons (they are NavigationLinks) a random curved line comes at the bottom of it. It also appears when clicking on the toolbar items.
The line chart is supposed to look normal, but after pressing buttons, it makes a weird line. I have a chartXSelection which shows an annotation view, and when dragging through the chart, it disappears, but when you stay at the same value for multiple seconds, it appears again (couldn't take a screenshot because it disappears after moving the mouse away)
This is my code, with the annotation view:
var body: some View {
VStack {
NavigationLink(value: selectedStat) {
HStack {
VStack(alignment: .leading) {
Label("Time Asleep", systemImage: "bed.double.fill")
.font(.title3.bold())
.foregroundStyle(.cyan)
Text("Avg: \(formatTime(seconds: avgSleep, showDecimal: true))")
.font(.caption)
}
Spacer()
Image(systemName: "chevron.right")
}
}
.foregroundStyle(.secondary)
.padding(.bottom, 12)
Chart {
if let selectedHealthMetric {
RuleMark(x: .value("Selected Metric", selectedHealthMetric.date, unit: .day))
.foregroundStyle(Color.secondary.opacity(0.3))
.offset(y: -10)
.annotation(position: .top,
spacing: 0,
overflowResolution: .init(x: .fit(to: .chart), y: .disabled)) { annotationView }
}
RuleMark(y: .value("Average", avgSleep))
.foregroundStyle(.mint)
.lineStyle(.init(lineWidth: 1, dash: [5]))
ForEach(chartData) { sleep in
LineMark(
x: .value("Day", sleep.date, unit: .day),
y: .value("Time Asleep", sleep.value)
)
.foregroundStyle(.cyan)
.interpolationMethod(.catmullRom)
.symbol(.circle)
AreaMark(
x: .value("Day", sleep.date, unit: .day),
yStart: .value("Value", sleep.value),
yEnd: .value("Min Value", minValue)
)
.foregroundStyle(Gradient(colors: [.cyan.opacity(0.5), .clear]))
.interpolationMethod(.catmullRom)
}
}
.frame(height: 150)
.chartXSelection(value: $rawSelectedDate.animation(.easeInOut))
.chartXAxis {
AxisMarks {
AxisValueLabel(format: .dateTime.month(.defaultDigits).day())
}
}
.chartYAxis {
AxisMarks { value in
AxisGridLine()
.foregroundStyle(Color.secondary.opacity(0.3))
AxisValueLabel("\(formatTime(seconds: value.as(Double.self) ?? 0, showDecimal: true))")
}
}
.chartYScale(domain: .automatic(includesZero: false))
}
.padding()
.background(RoundedRectangle(cornerRadius: 12).fill(Color(.secondarySystemBackground)))
}
var annotationView: some View {
VStack(alignment: .leading) {
Text(selectedHealthMetric?.date ?? .now, format: .dateTime.weekday(.abbreviated).month(.abbreviated).day())
.font(.footnote.bold())
.foregroundStyle(.secondary)
Text(formatTime(seconds: selectedHealthMetric?.value ?? 0))
.fontWeight(.heavy)
.foregroundStyle(.cyan)
}
.padding(12)
.background(
RoundedRectangle(cornerRadius: 4)
.fill(Color(.secondarySystemBackground))
.shadow(color: .secondary.opacity(0.3), radius: 2, x: 2, y: 2)
)
}
Upvotes: 1
Views: 91
Reputation: 31
I figured it out, when I get the health data, I am adding to the array instead of updating it, which causes duplicate answers, which messes up the line chart.
Upvotes: 0