Handling of dates with no value when creating a date bar chart in Charts

Some data have skipped dates, as in the following data.

TrainingSession(date: formatter.date(from: "2024-05-12 07:37:30 +0000")!, maxRM: 10.0, totalVolume: 0.0),
TrainingSession(date: formatter.date(from: "2024-06-01 15:00:00 +0000")!, maxRM: 10.5, totalVolume: 105.0),
TrainingSession(date: formatter.date(from: "2024-06-03 15:00:00 +0000")!, maxRM: 10.0, totalVolume: 100.0)

In this case, the graph shows nothing for the corresponding date as shown in the image. s it possible to create a continuous graph by displaying only the data with values and not the dates with no values?

The source code is as follows

//  ContentView.swift
//  GraphSample
//
//  Created by 齋藤卓馬 on 2024/06/09.
//

import SwiftUI
import Charts

struct TrainingSession {
    var date: Date
    var maxRM: Double
    var totalVolume: Double
}

struct GraphView: View {
    var sessions: [TrainingSession]

    var body: some View {
        ScrollView {
            VStack(alignment: .leading) {
                // 最大RMのグラフ
                VStack(alignment: .leading) {
                    Text("最大RM")
                        .font(.headline)
                        .padding()
                    Chart(sessions, id: \.date) { session in
                        BarMark(
                            x: .value("Date", session.date),
                            y: .value("Max RM", session.maxRM)
                        )
                    }
                    .chartXAxis {
                        AxisMarks(values: .stride(by: .day, count:7)) // 日付の表示間隔を調整
                    }
                    .chartScrollableAxes(.horizontal) // 横スクロールを有効にする
                    .padding([.leading, .trailing, .bottom])
                }

                // 総負荷量のグラフ
                VStack(alignment: .leading) {
                    Text("総負荷量")
                        .font(.headline)
                        .padding()
                    Chart(sessions, id: \.date) { session in
                        BarMark(
                            x: .value("Date", session.date),
                            y: .value("Total Volume", session.totalVolume)
                        )
                    }
                    .chartXAxis {
                        AxisMarks(values: .stride(by: .day, count:7)) // 日付の表示間隔を調整
                    }
                    .chartScrollableAxes(.horizontal) // 横スクロールを有効にする
                    .padding([.leading, .trailing, .bottom])
                }
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        GraphView(sessions: sampleData)
    }

    var sampleData: [TrainingSession] {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
        return [
            TrainingSession(date: formatter.date(from: "2024-05-12 07:37:30 +0000")!, maxRM: 10.0, totalVolume: 0.0),
            TrainingSession(date: formatter.date(from: "2024-06-01 15:00:00 +0000")!, maxRM: 10.5, totalVolume: 105.0),
            TrainingSession(date: formatter.date(from: "2024-06-03 15:00:00 +0000")!, maxRM: 10.0, totalVolume: 100.0)
        ]
    }
}

struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}
Answered by Claude31 in 789888022

All data are shown… but you have to scroll.

Add .chartXVisibleDomain to change the scale and see the full range

                    Chart(sessions, id: \.date) { session in
                        BarMark(
                            x: .value("Date", session.date),
                            y: .value("Max RM", session.maxRM)
                        )
                    }
                    .chartXAxis {
                        AxisMarks(values: .stride(by: .day, count:7)) // 日付の表示間隔を調整
                    }
                    .chartXVisibleDomain(length: 3600 * 24 * 30) // 30 days in this case
                    .chartScrollableAxes(.horizontal) // 横スクロールを有効にする
                    .padding([.leading, .trailing, .bottom])

Note: totalVolume is shown but as it is zero is a zero height bar.

All data are shown… but you have to scroll.

Add .chartXVisibleDomain to change the scale and see the full range

                    Chart(sessions, id: \.date) { session in
                        BarMark(
                            x: .value("Date", session.date),
                            y: .value("Max RM", session.maxRM)
                        )
                    }
                    .chartXAxis {
                        AxisMarks(values: .stride(by: .day, count:7)) // 日付の表示間隔を調整
                    }
                    .chartXVisibleDomain(length: 3600 * 24 * 30) // 30 days in this case
                    .chartScrollableAxes(.horizontal) // 横スクロールを有効にする
                    .padding([.leading, .trailing, .bottom])

Note: totalVolume is shown but as it is zero is a zero height bar.

[i]s it possible to create a continuous graph by displaying only the data with values and not the dates with no values?

No, a continuous scale such as a temporal (Plottable is Date) scale doesn't have that. But you can grab date components such as the day, convert it to a String and use it to create a categorical bar chart.

Categorical bar charts can also scroll.

Handling of dates with no value when creating a date bar chart in Charts
 
 
Q