2

I'm building a Bar chart using Swift Charts. The chart displays daily totals for a given week. I'm seeing a glitch when transitioning between consecutive weeks, where the first X axis label does not animate correctly and remains visible a bit more than expected.

This is a code example, that reproduces the issue. In this example, I added a button that just toggles between the current and the previous week, with an animation.

import Charts
import Foundation
import SwiftUI

struct DailyTotal: Identifiable {
    let date: Date
    let value: Double
    
    var id: Date { date }
}

struct ChartView: View {
    @State private var displayCurrentWeek = true
    @State private var totals = Self.currentWeekTotals
    
    var body: some View {
        VStack {
            Chart(totals) { total in
                BarMark(
                    x: .value("Day", total.date, unit: .day),
                    y: .value("Total", total.value)
                )
            }
            .chartXAxis {
                AxisMarks(values: .stride(by: .day)) { _ in
                    AxisValueLabel(format: .dateTime.weekday(), centered: true)
                }
            }
            .frame(height: 200)
            
            Button("Toggle Week") {
                withAnimation {
                    displayCurrentWeek.toggle()
                    totals = displayCurrentWeek ? Self.currentWeekTotals : Self.previousWeekTotals
                }
            }
        }
    }
}

let dayDuration: TimeInterval = 24 * 3600

extension ChartView {
    static let previousWeekTotals = [
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -13 * dayDuration), value: 10),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -12 * dayDuration), value: 10),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -11 * dayDuration), value: 25),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -10 * dayDuration), value: 20),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -09 * dayDuration), value: 5),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -08 * dayDuration), value: 10),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -07 * dayDuration), value: 5),
    ]
    
    static let currentWeekTotals = [
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -6 * dayDuration), value: 20),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -5 * dayDuration), value: 15),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -4 * dayDuration), value: 5),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -3 * dayDuration), value: 10),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -2 * dayDuration), value: 20),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -1 * dayDuration), value: 15),
        DailyTotal(date: Date(timeIntervalSinceReferenceDate: -0 * dayDuration), value: 10),
    ]
}

struct ChartView_Previews: PreviewProvider {
    static var previews: some View {
        ChartView()
            .padding()
            .previewInterfaceOrientation(.landscapeLeft)
    }
}

This is the preview for the above code, you can see that 'Tue' or 'Wed' labels glitch upon pressing the toggle button.

enter image description here

This seems like an issue with Swift Charts, but perhaps I'm doing something wrong. I also noticed the issue is not present if I don't customise the X axis, but the default setting is not acceptable for my design.

Thanks!

0 Answers0