diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-23 11:18:06 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-23 11:18:06 +0200 |
| commit | f7264b8f594859c1430bd13e765db03002842d38 (patch) | |
| tree | b4cb9e008b8ba8567ead0a6263b69deb8a8b2f8d /web/templates.templ | |
| parent | 53615a05708ff852af42905e2b5ced66ba70c43d (diff) | |
Add normalized difficulty versus moving duration to analytics
Extend analytics with a second scatter plotting Cotacol per 100 km against
moving hours, keep speed versus Cotacol as first chart, render both
canvases from shared points, open ride detail in a new tab on dot click,
and keep all website copy in English.
Diffstat (limited to 'web/templates.templ')
| -rw-r--r-- | web/templates.templ | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/web/templates.templ b/web/templates.templ index 0660d07..9be2daf 100644 --- a/web/templates.templ +++ b/web/templates.templ @@ -100,7 +100,7 @@ templ AnalyticsPage(data AnalyticsPageData) { templ AnalyticsContent(data AnalyticsPageData) { <p class="eyebrow">Analytics</p> <h1>Ride analytics</h1> - <p class="lead">One point per ride: average speed on the x axis, Cotacol per 100 km on the y axis.</p> + <p class="lead">One point per ride — first chart: average speed vs. Cotacol per 100 km; second chart: normalized difficulty (Cotacol per 100 km) vs. moving duration.</p> <section class="panel analytics-filters-panel"> <form id="analytics-filters" class="ride-filters" method="get" action="/analytics" aria-label="Analytics filters"> <div class="section-heading"> @@ -130,6 +130,24 @@ templ AnalyticsContent(data AnalyticsPageData) { <output id="analytics-hover" class="analytics-hover" aria-live="polite">Hover a point to inspect a ride.</output> } </section> + <section class="panel analytics-panel"> + <div class="section-heading"> + <div><p class="eyebrow">Chart</p><h2>Normalized difficulty vs moving duration</h2></div> + if len(data.Points) > 0 { + <span class="section-count" data-analytics-duration-count>{ formatRideCount(len(data.Points)) }</span> + } + </div> + if len(data.Points) == 0 { + if data.Filter.Active { + <div class="empty">No rides match the selected filters. <a href={ templ.URL(data.Filter.ResetURL) }>Clear filters.</a></div> + } else { + <div class="empty">No eligible rides yet. <a href="/sync">Import rides to see the chart.</a></div> + } + } else { + <div class="analytics-chart"><canvas id="analytics-duration-chart" tabindex="0" role="img" aria-label="Scatter plot of normalized difficulty against moving duration"></canvas></div> + <output id="analytics-duration-hover" class="analytics-hover" aria-live="polite">Hover a point to inspect a ride.</output> + } + </section> @templ.JSONScript("analytics-points", data.Points) <script type="module" src="/static/ride-filters.js"></script> <script type="module" src="/static/analytics.js"></script> |
