Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions InputMetrics/InputMetrics/Models/DailySummary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,24 @@ struct DailySummary: Codable, FetchableRecord, PersistableRecord {
static let peakMouseSpeed = Column(CodingKeys.peakMouseSpeed)
static let peakWPM = Column(CodingKeys.peakWPM)
}

static func zero(for date: String) -> DailySummary {
DailySummary(date: date, mouseDistancePx: 0, mouseClicksLeft: 0, mouseClicksRight: 0, mouseClicksMiddle: 0, keystrokes: 0, scrollDistanceVertical: 0, scrollDistanceHorizontal: 0)
}
}

extension [DailySummary] {
func fillingMissingDays(from start: Date, to end: Date) -> [DailySummary] {
let calendar = Calendar.current
let formatter = DateHelper.self
let existing = Dictionary(uniqueKeysWithValues: self.map { ($0.date, $0) })
var result: [DailySummary] = []
var current = start
while current <= end {
let key = formatter.string(from: current)
result.append(existing[key] ?? .zero(for: key))
current = calendar.date(byAdding: .day, value: 1, to: current) ?? current
}
return result
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ final class KeyboardStatsViewModel {
}
}

if selectedRange == .week || selectedRange == .month {
chartData = chartData.fillingMissingDays(from: startDate, to: selectedDate)
}

if selectedRange == .year {
chartData = aggregateByWeek(chartData)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ final class MouseStatsViewModel {
}
}

if selectedRange == .week || selectedRange == .month {
chartData = chartData.fillingMissingDays(from: startDate, to: selectedDate)
}

if selectedRange == .year {
chartData = aggregateByWeek(chartData)
}
Expand Down
31 changes: 21 additions & 10 deletions InputMetrics/InputMetrics/Views/ChartView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,31 @@ struct ChartView: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
Chart(data, id: \.date) { item in
let label = formatLabel(from: item.date)
let value = metricValue(for: item)

LineMark(
x: .value("Date", label),
AreaMark(
x: .value("Date", item.date),
y: .value("Value", value)
)
.foregroundStyle(Color.blue)
.foregroundStyle(Color.blue.opacity(0.15))
.interpolationMethod(.catmullRom)

AreaMark(
x: .value("Date", label),
LineMark(
x: .value("Date", item.date),
y: .value("Value", value)
)
.foregroundStyle(Color.blue.opacity(0.1))
.foregroundStyle(Color.blue)
.interpolationMethod(.catmullRom)

PointMark(
x: .value("Date", label),
x: .value("Date", item.date),
y: .value("Value", value)
)
.foregroundStyle(Color.blue)
.symbolSize(30)

if hoveredLabel == label {
RuleMark(x: .value("Date", label))
if hoveredLabel == item.date {
RuleMark(x: .value("Date", item.date))
.foregroundStyle(Color.secondary.opacity(0.3))
.annotation(position: .top, spacing: 4) {
Text(formattedTooltip(value: value))
Expand All @@ -63,6 +62,18 @@ struct ChartView: View {
}
}
}
.chartLegend(.hidden)
.chartXAxis {
AxisMarks { value in
AxisValueLabel {
if let dateStr = value.as(String.self) {
Text(formatLabel(from: dateStr))
}
}
AxisGridLine()
AxisTick()
}
}
.accessibilityElement(children: .ignore)
.accessibilityLabel("\(chartTitle) chart for \(range == .week ? "this week" : range == .month ? "this month" : "this year")")
.chartYAxisLabel(yAxisLabel)
Expand Down