shape data from core data into plottable format

This is easy using CoreData + SwiftUI.

The code below is for iOS15+ but you can do the same thing with an NSFetchedResultsController or NSFetchRequest / @FetchRequest and then group it. But it will require a bit of effort to stay real time.

Also, the code below is meant to work with the standard Apple code for a CoreData project. The only thing I changed in PersistenceController is setting a random day for the timestamp

newItem.timestamp = Date().addingTimeInterval(60*60*24*Double(Int.random(in: -10...10)))

This is a simple graph

import SwiftUI

@available(iOS 15.0, *)
struct DayChart: View {
    @SectionedFetchRequest(entity: Item.entity(), sectionIdentifier: \.completionDate, sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], predicate: nil, animation: Animation.linear)
    var sections: SectionedFetchResults<String, Item>
    @State var maxCount: Int = 1
    let spacing: CGFloat = 3
    var body: some View {
        VStack{
            GeometryReader{ geo in
                HStack(alignment: .bottom, spacing: spacing){
                    ForEach(sections){section in
                        VStack{
                            Text(section.count.description)
                            Rectangle()
                                .foregroundColor(.blue)
                                .onAppear(){
                                    maxCount = max(maxCount,section.count)
                                    
                                }
                            Text(section.id.description).minimumScaleFactor(0.5)
                            .lineLimit(2)
                        }.frame(width: (geo.size.width/CGFloat(sections.count) - spacing),height: geo.size.height * CGFloat(CGFloat(section.count)/CGFloat(maxCount)))
                    }
                }
            }
        }.padding(.leading, spacing)
    }
}

@available(iOS 15.0, *)
struct DayChart_Previews: PreviewProvider {
    static var previews: some View {
        DayChart().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}
extension Item{
    //This is the variable that determines your section/column/completion date
    @objc
    var completionDate: String{
                    
        if self.timestamp != nil{
            let dateFormatter: DateFormatter = DateFormatter()
            dateFormatter.dateFormat = "dd\nMMM"
            return dateFormatter.string(from: self.timestamp!)
             
        }else{
            return ""
        }
    }
}

enter image description here

Leave a Comment