0

I am having some trouble using the Charts framework in SwiftUI. Everything plots as expected, however the x axis does not show the dates for each point. The Y axis is working and shows the weight values along the Y axis. dateCompleted is of type Date().

             Chart(exerciseMaxRepsArray) { e in
                                    LineMark(x: .value("Date", e.dateCompleted),                                         
                                             y: .value("Reps", e.reps)                                             
                                    )}

I've tried to use dateFormatter and plot it as a string, i've tried to specify

LineMark(x: .value("Date", e.dateCompleted, unit: .day),                                         
         y: .value("Reps", e.reps))}                                                                            

But nothing is working to show the date values. I've ensured that the dates are populated and that the frame is large enough so they're not being cut out. Any help would be greatly appreciated. Thanks!!!

This is what the graph looks like in the simulator: simulator screen

EDITED :

GroupBox(label: Text("Daily Max Reps"){
 Chart(exerciseMaxRepsArray) { e in
    LineMark(x: .value("Date", e.dateCompleted, unit: .day),
 y: .value("Reps", e.reps)
 ) } 
.chartYAxisLabel(position: .trailing, alignment: .center) {
   Text("Reps")
 }
.chartXAxisLabel(position: .bottom, alignment: .center) {
 Text("Date")
}
.padding()
 } .groupBoxStyle(BackgroundGroupBoxStyle()) 

EDIT :

//
//  ExerciseDetailView.swift
//  WorkoutTrackerTrial
//
//  Created by Rachel Scott on 12/7/22.
//

import SwiftUI
import Charts


struct ExerciseDetailView: View {
    
    @FetchRequest var exercisesets: FetchedResults<ExerciseSet>
    
    var exercise: String

    init(exercise: String) {
        self.exercise = exercise
        self._exercisesets = FetchRequest(
            entity: ExerciseSet.entity(),
            sortDescriptors: [],
            predicate: NSPredicate(format: "exercisename == %@", exercise as any CVarArg)
        )
    }
        
    var exerciseMaxRepsArray: [ExerciseSet] {
        var seenDates: Set<Date> = []
        return exercisesets
            .sorted { $0.reps > $1.reps } // you can skip this line if already sorted by weight in the @fetchrequest
            .filter { seenDates.insert($0.dateCompleted.startOfDay).inserted }
            .sorted { $0.dateCompleted < $1.dateCompleted }
    }
    
    var body: some View {
        
        if #available(iOS 16.0, *) {
            ZStack{
                CustomColor.backgroundColor.edgesIgnoringSafeArea(.all)
                // for weights on that day, return from largest to smallest and use highest from that day
                
                VStack {
                    Text(exercise)
                        .font(Font.custom("Montserrat-SemiBold", size: 24))
                        .foregroundColor(CustomColor.darkGreen)
                        .background(CustomColor.backgroundColor)

                        GroupBox(label: Text("Daily Max Reps")
                            .font(Font.custom("Montserrat-SemiBold", size: 18))
                            .foregroundColor(CustomColor.darkGreen)) {
                                
                                
                                Chart(exerciseMaxRepsArray) { e in
                                    LineMark(x: .value("Date", e.dateCompleted, unit: .day),
                                             y: .value("Reps", e.reps)
                                             
                                    ).foregroundStyle(CustomColor.lightGreen)
                                }
                                .chartYAxisLabel(position: .trailing, alignment: .center) {
                                    Text("Reps")
                                        .font(Font.custom("Montserrat-Medium", size: 16))
                                        .foregroundColor(CustomColor.darkGreen)
                                }
                                .chartXAxisLabel(position: .bottom, alignment: .center) {
                                    Text("Date")
                                        .font(Font.custom("Montserrat-Medium", size: 16))
                                        .foregroundColor(CustomColor.darkGreen)
                                }
                                .padding()
                            } .groupBoxStyle(BackgroundGroupBoxStyle()) //.background(CustomColor.backgroundColor)
                    }
                    
                }
                
                
            }
        }
    }
    




Rachel
  • 51
  • 1
  • 7
  • your second piece of code looks correct (using `unit: .day`). Do you use a custom `.chartXAxis`?? Show your complete code, maybe then I can help. – ChrisR Jan 06 '23 at 16:48
  • @ChrisR Thank you, I have updated my post will more of my code. I am using .chartXAxisLabel – Rachel Jan 06 '23 at 17:02

1 Answers1

0

It works fine with me, might me something in the model data code?

Here is my working example:

enter image description here

struct Exercise: Identifiable {
    let id = UUID()
    var dateCompleted: Date
    var reps: Int
}


struct ContentView: View {
    
    private var exerciseMaxRepsArray: [Exercise] = []

    init() { // init dummy data
        for i in 0 ..< 10 {
            let date = Calendar.current.date(byAdding: .day, value: i, to: .now) ?? .now
            let rep = Int.random(in: 1...10)
            exerciseMaxRepsArray.append(
                Exercise(dateCompleted: date, reps: rep)
            )
        }
    }

    var body: some View {
        
        GroupBox(label: Text("Daily Max Reps")) {
            Chart(exerciseMaxRepsArray) { e in
                LineMark(x: .value("Date", e.dateCompleted, unit: .day),
                         y: .value("Reps", e.reps)
                ) }
            .chartYAxisLabel(position: .trailing, alignment: .center) {
                Text("Reps")
            }
            .chartXAxisLabel(position: .bottom, alignment: .center) {
                Text("Date")
            }
            .padding()
        }
    }
}
ChrisR
  • 9,523
  • 1
  • 8
  • 26
  • I see, thank you for trying! I edited my question with some more code. I am using the exercisesets to create a new array that only contains the maximum on each day (so there is only one entry per day). Do you think that could be why I am having this issue? Something about the date getting messed up? – Rachel Jan 06 '23 at 18:11
  • 1
    it all looks fine. try debug printing your array before it goes in the chart. maybe you find something – ChrisR Jan 06 '23 at 18:35