feat: trend and trend break charts - #853
Conversation
298594e to
61d08db
Compare
61d08db to
b9f8f3f
Compare
jovandeginste
left a comment
There was a problem hiding this comment.
I have a few remarks, mostly just notices for later; however, I do have a request regarding the nested struct - would be nice if that was doable.
|
OK, this should do it :-) |
jovandeginste
left a comment
There was a problem hiding this comment.
Thank you! Switching back to "trend break" does not seem to work in the statistics page, but that can be fixed later...
There was a problem hiding this comment.
🟡 Changes recommended
It introduces a potentially expensive full preload of all route segments on the statistics page and exposes raw internal error strings from a new profile-config endpoint.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR enhances the statistics and route-segment charts by adding selectable trend periods, optional trend-break visualization, and a new personal trend chart based on route segment performance, plus some chart UI cleanup.
Changes:
- Added a workout type filter and a new “personal trend” route-segment chart to the user statistics page.
- Implemented trend period selection, trend-break detection toggles, and zoom reset controls for route segment charts.
- Introduced persisted route-segment chart preferences in the user profile (trend period + trend-break detection), plus new EN/NL translations.
File summaries
| File | Description |
|---|---|
| views/user/statistics.templ | Adds workout type selector and personal route-segment trend chart, passes workout-type to chart components. |
| views/user/statistics_templ.go | Generated output reflecting statistics.templ updates. |
| views/route_segments/show_stats.templ | Switches to user-filtered matches and adds trend config props (period, break detection, config update route). |
| views/route_segments/show_stats_templ.go | Generated output reflecting show_stats.templ updates. |
| translations/en.yaml | Adds new strings for trend period / trend break UI. |
| translations/nl.yaml | Adds new strings for trend period / trend break UI (Dutch). |
| pkg/database/statistics.go | Updates default statistics “since/per” keys to the new literal values (e.g., 1 year, month). |
| pkg/database/route_segments.go | Adds RouteSegmentMatchesForUserID helper; GetRouteSegments preloads matches+workouts. |
| pkg/database/route_segment_test.go | Adds unit test coverage for RouteSegmentMatchesForUserID. |
| pkg/database/profile.go | Adds persisted RouteSegmentConfig (trend period + trend break detection) with validation and defaults. |
| pkg/app/users_handlers.go | Initializes new route segment config defaults on user registration. |
| pkg/app/self_handlers.go | Adds endpoint to update route segment config preferences from the frontend. |
| pkg/app/handlers.go | Statistics handler now fetches route segments and passes them into the statistics template. |
| frontend/src/views/user/statistics.js | Changes stats charts to line charts, adds workout-type filtering, and introduces ApexCharts-based personal trend chart with trend-break support. |
| frontend/src/views/route_segments/show_stats.ts | Replaces trendline plugin with custom trend/trend-break logic, adds trend period + trend-break controls, and enables zoom/pan. |
Review details
Files not reviewed (2)
- views/route_segments/show_stats_templ.go: Generated file
- views/user/statistics_templ.go: Generated file
- Files reviewed: 13/15 changed files
- Comments generated: 4
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| routeSegments, err := database.GetRouteSegments(a.db) | ||
| if err != nil { | ||
| return a.redirectWithError(c, a.Reverse("dashboard"), err) | ||
| } |
| if err := c.Request().ParseForm(); err != nil { | ||
| return c.String(http.StatusInternalServerError, err.Error()) | ||
| } |
| for _, m := range s.RouteSegmentMatchesForUserID(currentUser.ID) { | ||
| routeSegmentTrendData = append(routeSegmentTrendData, routeSegmentTrendStatDataPoint{ | ||
| Date: m.Workout.Date.Format(time.RFC3339), | ||
| Speed: helpers.HumanSpeed(ctx, m.AverageSpeed()), | ||
| Type: m.Workout.Type.String(), | ||
| }) |
| if err := u.Profile.Save(a.db); err != nil { | ||
| return c.String(http.StatusInternalServerError, err.Error()) | ||
| } |
|
@pixelspark can you fix the conflict? I'm not sure how doable the suggestion is from copilot regarding the server-side filtering; wdyt? |
This PR cleans up the charts a bit and improves the trends feature:
(I've made it a bit less tall now)