add ActiveWorkoutSession logic, refactor Home, add additional sample data, add isDebug
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// ActivityLog.swift
|
||||
// WorkoutsPlus
|
||||
//
|
||||
// Created by Felix Förtsch on 09.09.24.
|
||||
//
|
||||
// https://www.artemnovichkov.com/blog/github-contribution-graph-swift-charts
|
||||
// https://github.com/artemnovichkov/awesome-swift-charts
|
||||
|
||||
import SwiftUI
|
||||
import Charts
|
||||
|
||||
struct ActivityLog: View {
|
||||
@State var activities: [Activity] = Activity.generate()
|
||||
|
||||
var body: some View {
|
||||
Chart(activities) { contribution in
|
||||
RectangleMark(
|
||||
xStart: .value("Start week", contribution.date, unit: .weekOfYear),
|
||||
xEnd: .value("End week", contribution.date, unit: .weekOfYear),
|
||||
yStart: .value("Start weekday", weekday(for: contribution.date)),
|
||||
yEnd: .value("End weekday", weekday(for: contribution.date) + 1)
|
||||
)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 4).inset(by: 2))
|
||||
.foregroundStyle(by: .value("Count", contribution.count))
|
||||
}
|
||||
.chartPlotStyle { content in
|
||||
content
|
||||
.aspectRatio(aspectRatio, contentMode: .fit)
|
||||
}
|
||||
.chartForegroundStyleScale(range: Gradient(colors: colors))
|
||||
.chartXAxis {
|
||||
AxisMarks(position: .top, values: .stride(by: .month)) {
|
||||
AxisValueLabel(format: .dateTime.month())
|
||||
.foregroundStyle(Color(.label))
|
||||
}
|
||||
}
|
||||
.chartYAxis {
|
||||
AxisMarks(position: .leading, values: [1, 3, 5]) { value in
|
||||
if let value = value.as(Int.self) {
|
||||
AxisValueLabel {
|
||||
// Symbols from Calendar.current starting with Monday
|
||||
// Text(shortWeekdaySymbols[value - 1])
|
||||
}
|
||||
.foregroundStyle(Color(.label))
|
||||
}
|
||||
}
|
||||
}
|
||||
.chartYScale(domain: .automatic(includesZero: false, reversed: true))
|
||||
.chartLegend {
|
||||
HStack(spacing: 4) {
|
||||
Text("Less")
|
||||
ForEach(legendColors, id: \.self) { color in
|
||||
color
|
||||
.frame(width: 10, height: 10)
|
||||
.cornerRadius(2)
|
||||
}
|
||||
Text("More")
|
||||
}
|
||||
.padding(4)
|
||||
.foregroundStyle(Color(.label))
|
||||
.font(.caption2)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private func weekday(for date: Date) -> Int {
|
||||
let weekday = Calendar.current.component(.weekday, from: date)
|
||||
let adjustedWeekday = (weekday == 1) ? 7 : (weekday - 1)
|
||||
return adjustedWeekday
|
||||
}
|
||||
|
||||
private var aspectRatio: Double {
|
||||
if activities.isEmpty {
|
||||
return 1
|
||||
}
|
||||
let firstDate = activities.first!.date
|
||||
let lastDate = activities.last!.date
|
||||
let firstWeek = Calendar.current.component(.weekOfYear, from: firstDate)
|
||||
let lastWeek = Calendar.current.component(.weekOfYear, from: lastDate)
|
||||
return Double(lastWeek - firstWeek + 1) / 7
|
||||
}
|
||||
|
||||
private var colors: [Color] {
|
||||
(0...10).map { index in
|
||||
if index == 0 {
|
||||
return Color(.systemGray5)
|
||||
}
|
||||
return Color(.systemGreen).opacity(Double(index) / 10)
|
||||
}
|
||||
}
|
||||
|
||||
private var legendColors: [Color] {
|
||||
Array(stride(from: 0, to: colors.count, by: 2).map { colors[$0] })
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ActivityLog()
|
||||
}
|
||||
|
||||
struct Activity: Identifiable {
|
||||
|
||||
let date: Date
|
||||
let count: Int
|
||||
|
||||
var id: Date {
|
||||
date
|
||||
}
|
||||
}
|
||||
|
||||
extension Activity {
|
||||
|
||||
static func generate() -> [Activity] {
|
||||
var contributions: [Activity] = []
|
||||
let toDate = Date.now
|
||||
let fromDate = Calendar.current.date(byAdding: .day, value: -60, to: toDate)!
|
||||
|
||||
var currentDate = fromDate
|
||||
while currentDate <= toDate {
|
||||
let contribution = Activity(date: currentDate, count: .random(in: 0...10))
|
||||
contributions.append(contribution)
|
||||
currentDate = Calendar.current.date(byAdding: .day, value: 1, to: currentDate)!
|
||||
}
|
||||
|
||||
return contributions
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user