部分数据有跳过日期,如下数据。
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)
是否可以通过仅显示有值的数据而不显示没有值的日期来创建连续图表? 我想创建一个仅包含日期和值的条形图。
源码如下
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()
}
}
}
进行了以下修改,并且可以正常工作。
//
// ContentView.swift
// GraphSample
//
// Created by 齋藤卓馬 on 2024/06/09.
//
import SwiftUI
import Charts
import Foundation
struct YearMonthDay: Plottable, Hashable {
init?(primitivePlottable: String) {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
guard let date = formatter.date(from: primitivePlottable) else {
return nil
}
let calendar = Calendar.current
self.year = calendar.component(.year, from: date)
self.month = calendar.component(.month, from: date)
self.day = calendar.component(.day, from: date)
}
let year: Int
let month: Int
let day: Int
init(date: Date) {
let calendar = Calendar.current
self.year = calendar.component(.year, from: date)
self.month = calendar.component(.month, from: date)
self.day = calendar.component(.day, from: date)
}
var primitivePlottable: String {
let dateComponents = DateComponents(year: year, month: month, day: day)
let date = Calendar.current.date(from: dateComponents)!
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter.string(from: date)
}
}
struct TrainingSession {
var date: YearMonthDay
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.primitivePlottable),
y: .value("Max RM", session.maxRM)
)
}
.chartXAxis {
AxisMarks(values: .automatic) { value in
AxisValueLabel {
Text(value.as(YearMonthDay.self)?.primitivePlottable ?? "")
}
}
}
.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.primitivePlottable),
y: .value("Total Volume", session.totalVolume)
)
}
.chartXAxis {
AxisMarks(values: .automatic) { value in
AxisValueLabel {
Text(value.as(YearMonthDay.self)?.primitivePlottable ?? "")
}
}
}
.chartScrollableAxes(.horizontal)
.padding([.leading, .trailing, .bottom])
}
}
}
}
}
struct ContentView: View {
var body: some View {
NavigationView {
ScrollView(.horizontal) {
HStack {
GraphView(sessions: sampleData)
.frame(width: UIScreen.main.bounds.width) // 画面の幅に合わせる
}
}
.navigationTitle("Training Data")
}
}
var sampleData: [TrainingSession] {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
return [
TrainingSession(date: YearMonthDay(date: formatter.date(from: "2024-05-12 07:37:30 +0000")!), maxRM: 10.0, totalVolume: 0.0),
TrainingSession(date: YearMonthDay(date: formatter.date(from: "2024-06-01 15:00:00 +0000")!), maxRM: 10.5, totalVolume: 105.0),
TrainingSession(date: YearMonthDay(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()
}
}
}