add more train stats per driver
This commit is contained in:
90
src/app.js
90
src/app.js
@@ -18,7 +18,7 @@ import { renderEventManagerMarkup } from "./event_manager_view.js";
|
||||
import { renderEventManagerView } from "./event_manager_controller.js";
|
||||
import { createDefaultAmmcConfigHelper, getManagedWsUrlHelper, loadAmmcConfigFromBackendHelper, saveAmmcConfigToBackendHelper, refreshAmmcStatusHelper, startManagedAmmcHelper, stopManagedAmmcHelper, applyPersistedStateHelper, hydrateFromBackendHelper, scheduleBackendSyncHelper, syncStateToBackendHelper, pingBackendHelper, checkAppVersionHelper, startAppVersionPollingHelper, startOverlaySyncHelper, startOverlayRotationHelper, startOverlayLiveRefreshHelper, ensureAudioContextHelper, playPassingBeepHelper, playFinishSirenHelper, playLeaderCueHelper, playStartCueHelper, playBestLapCueHelper, pushOverlayEventHelper, getSpeechVoicesHelper, speakTextHelper, announcePassingHelper, announceRaceStartedHelper, announceRaceFinishedHelper, handleSessionTimerTickHelper, tickClockHelper } from "./runtime_services.js";
|
||||
import { connectDecoderHelper, disconnectDecoderHelper, processDecoderMessageHelper } from "./decoder_runtime.js";
|
||||
import { normalizeTrainingState as normalizeTrainingStateLogic, syncTrainingLedger as syncTrainingLedgerLogic, buildDriverTrainingStats as buildDriverTrainingStatsLogic, buildDriverTimingChannelStats as buildDriverTimingChannelStatsLogic, buildDriverActivePracticeStats as buildDriverActivePracticeStatsLogic, buildTrainingRecommendation as buildTrainingRecommendationLogic, getTrainingGoalProgress as getTrainingGoalProgressLogic, getNextTrainingMilestone as getNextTrainingMilestoneLogic } from "./training_logic.js";
|
||||
import { normalizeTrainingState as normalizeTrainingStateLogic, syncTrainingLedger as syncTrainingLedgerLogic, buildDriverTrainingStats as buildDriverTrainingStatsLogic, buildDriverTimingChannelStats as buildDriverTimingChannelStatsLogic, buildDriverActivePracticeStats as buildDriverActivePracticeStatsLogic, buildTrainingRecommendation as buildTrainingRecommendationLogic, getTrainingGoalProgress as getTrainingGoalProgressLogic, getNextTrainingMilestone as getNextTrainingMilestoneLogic, buildTrainingPaceBuckets as buildTrainingPaceBucketsLogic, buildTrainingWeekdayStats as buildTrainingWeekdayStatsLogic, buildTrainingStintAnalysis as buildTrainingStintAnalysisLogic, buildTrainingMarkerComparisons as buildTrainingMarkerComparisonsLogic } from "./training_logic.js";
|
||||
import { renderTrainingView } from "./training_views.js";
|
||||
import { importDriversCsv, importCarsCsv } from "./csv_import.js";
|
||||
|
||||
@@ -293,7 +293,7 @@ const buildDriverActivePracticeStats = (trainingState, driverId, nowTs = Date.no
|
||||
const buildTrainingRecommendation = (stats) => buildTrainingRecommendationLogic(stats);
|
||||
const getTrainingGoalProgress = (goal, stats) => getTrainingGoalProgressLogic(goal, stats);
|
||||
const getNextTrainingMilestone = (stats) => getNextTrainingMilestoneLogic(stats);
|
||||
const renderTraining = () => renderTrainingView({ state, dom, t, escapeHtml, formatLap, formatRaceClock, uid, saveState, renderView, normalizeTrainingState, syncTrainingLedger, buildDriverTrainingStats, buildDriverTimingChannelStats: buildDriverTimingChannelStatsLogic, buildDriverActivePracticeStats, buildTrainingRecommendation, getTrainingGoalProgress, getNextTrainingMilestone, getSelectedDriverId: () => selectedTrainingDriverId, setSelectedDriverId: (value) => { selectedTrainingDriverId = value; updateViewUrl("training", value, selectedTrainingClassId); }, getSelectedClassId: () => selectedTrainingClassId, setSelectedClassId: (value) => { selectedTrainingClassId = value; updateViewUrl("training", selectedTrainingDriverId, value); } });
|
||||
const renderTraining = () => renderTrainingView({ state, dom, t, escapeHtml, formatLap, formatRaceClock, uid, saveState, renderView, normalizeTrainingState, syncTrainingLedger, buildDriverTrainingStats, buildDriverTimingChannelStats: buildDriverTimingChannelStatsLogic, buildDriverActivePracticeStats, buildTrainingRecommendation, getTrainingGoalProgress, getNextTrainingMilestone, buildTrainingPaceBuckets: buildTrainingPaceBucketsLogic, buildTrainingWeekdayStats: buildTrainingWeekdayStatsLogic, buildTrainingStintAnalysis: buildTrainingStintAnalysisLogic, buildTrainingMarkerComparisons: buildTrainingMarkerComparisonsLogic, getSelectedDriverId: () => selectedTrainingDriverId, setSelectedDriverId: (value) => { selectedTrainingDriverId = value; updateViewUrl("training", value, selectedTrainingClassId); }, getSelectedClassId: () => selectedTrainingClassId, setSelectedClassId: (value) => { selectedTrainingClassId = value; updateViewUrl("training", selectedTrainingDriverId, value); } });
|
||||
const applyCompetitorCorrection = (session, row, options = {}) => {
|
||||
const result = applyCompetitorCorrectionLogic(session, row, options, { ensureSessionResult, uid, t, formatLap, saveState });
|
||||
if (!options.reset && ((Number(options.timeMsDelta || 0) > 0) || (Number(options.lapDelta || 0) < 0))) {
|
||||
@@ -445,6 +445,45 @@ const TRANSLATIONS = {
|
||||
"training.history": "Träningshistorik per dag",
|
||||
"training.detailed_stats": "Mer statistik",
|
||||
"training.detailed_stats_hint": "Snitt, varvserie, mellantider, depåstopp och historik per träningsdag.",
|
||||
"training.extra_stats": "Extra statistik",
|
||||
"training.extra_stats_hint": "Tempo per 30 minuter, setupändringar och djupare stintanalys.",
|
||||
"training.pace_30_title": "Tempo per aktivt 30-minutersblock",
|
||||
"training.pace_30_hint": "Visar bara block med körning. Tempot är ett trimmat snitt så enstaka krascher inte styr hela blocket.",
|
||||
"training.no_pace_data": "Det finns inte tillräckligt med varv för en tempokarta ännu.",
|
||||
"training.weekday_pace": "Tempo per veckodag",
|
||||
"training.weekday_hint": "Visas först efter minst tre träningsdagar och använder bara dagar med körning.",
|
||||
"training.weekday_needs_days": "Minst tre träningsdagar behövs för en meningsfull jämförelse.",
|
||||
"training.add_marker": "Markera en biländring",
|
||||
"training.add_marker_hint": "Markeringen sparas nu för vald förare och klass. Systemet jämför 30 minuter före och efter.",
|
||||
"training.marker_type": "Typ av ändring",
|
||||
"training.marker_setup": "Ny setup",
|
||||
"training.marker_tires": "Bytte däck",
|
||||
"training.marker_suspension": "Ändrade dämpare",
|
||||
"training.marker_car": "Bytte bil",
|
||||
"training.marker_note": "Egen notering",
|
||||
"training.marker_description": "Beskrivning",
|
||||
"training.marker_placeholder": "Till exempel mjukare framfjädrar",
|
||||
"training.mark_now": "Markera ändring nu",
|
||||
"training.no_markers": "Inga setupmarkörer finns i den här klassen.",
|
||||
"training.marker_collecting": "Samlar underlag ({before} före / {after} efter)",
|
||||
"training.marker_improved": "{lap} snabbare efter ändringen",
|
||||
"training.marker_slower": "{lap} långsammare efter ändringen",
|
||||
"training.stint": "Stint",
|
||||
"training.start": "Start",
|
||||
"training.trimmed_pace": "Normaltempo",
|
||||
"training.race_pace_10": "Race pace 10",
|
||||
"training.mistakes": "Misstag",
|
||||
"training.start_end": "Start/slut",
|
||||
"training.insufficient_data": "För lite data",
|
||||
"training.no_stints": "Inga stintar finns ännu.",
|
||||
"training.stint_faster": "{lap} snabbare",
|
||||
"training.stint_slower": "{lap} långsammare",
|
||||
"training.stint_same": "Oförändrat",
|
||||
"training.stint_analysis": "Stintanalys",
|
||||
"training.stint_analysis_hint": "En paus över två minuter startar en ny stint. Kortare stintar visas men rankas inte.",
|
||||
"training.best_stint": "Bästa stint {stint}: {laps} varv, {pace}",
|
||||
"training.show_all_stints": "Visa alla {count} stintar",
|
||||
"training.stats_method": "Normaltempo använder trimmat snitt. Misstag är varv mer än 15% långsammare än stintens median. Minst 3 varv krävs för konsekvens och 10 för Race pace 10.",
|
||||
"training.split_passings": "Mellantidspasseringar",
|
||||
"training.best_split": "Bästa mellantid",
|
||||
"training.average_split": "Snitt mellantid",
|
||||
@@ -1398,6 +1437,10 @@ const TRANSLATIONS = {
|
||||
"guide.training_14": "14. En personlig profil och mobillänk kan innehålla flera klasser, men 2WD/4WD-statistik, stints, varvtider och rekommendationer visas alltid separat per vald klass.",
|
||||
"guide.training_15": "15. Utvecklingskortet jämför de senaste 30 giltiga varven med de föregående 30 inom samma klass. Positivt värde betyder snabbare snittempo eller mindre spridning; för litet underlag visas som insamling i stället för en osäker trend.",
|
||||
"guide.training_16": "16. Achievements och klubbens framstegsfeed lyfter träningspass, varvmål, jämn körning och fullföljda femminutersstints. Feedens ordning följer senaste aktivitet och är inte en ranking mellan förare.",
|
||||
"guide.training_17": "17. Öppna Extra statistik för tempo per aktivt 30-minutersblock. Tomma tider döljs och tempot använder trimmat snitt så enstaka krascher inte förvränger jämförelsen.",
|
||||
"guide.training_18": "18. Före en biländring väljer du Ny setup, däck, dämpare, bil eller egen notering och klickar Markera ändring nu. Markören sparas endast för vald personlig profil och klass.",
|
||||
"guide.training_19": "19. När det finns minst tre giltiga varv inom 30 minuter både före och efter markören visas förbättringen automatiskt. Jämför bara pass med liknande bana och förhållanden.",
|
||||
"guide.training_20": "20. Stintanalysen använder glapp över två minuter som gräns. Normaltempo är trimmat snitt, misstag är varv över 15 procent långsammare än stintens median och Race pace 10 kräver tio sammanhängande varv.",
|
||||
"overlay.title": "Overlay",
|
||||
"overlay.subtitle": "Extern leaderboard-skärm",
|
||||
"overlay.no_active": "Ingen aktiv session vald.",
|
||||
@@ -1603,6 +1646,45 @@ const TRANSLATIONS = {
|
||||
"training.history": "Daily practice history",
|
||||
"training.detailed_stats": "More statistics",
|
||||
"training.detailed_stats_hint": "Averages, lap streak, split timing, pit stops, and daily practice history.",
|
||||
"training.extra_stats": "Extra statistics",
|
||||
"training.extra_stats_hint": "30-minute pace, setup changes, and deeper stint analysis.",
|
||||
"training.pace_30_title": "Pace per active 30-minute block",
|
||||
"training.pace_30_hint": "Only blocks with driving are shown. Pace uses a trimmed average so isolated crashes do not control the block.",
|
||||
"training.no_pace_data": "There are not enough laps for a pace map yet.",
|
||||
"training.weekday_pace": "Pace by weekday",
|
||||
"training.weekday_hint": "Shown after at least three practice days and includes only days with driving.",
|
||||
"training.weekday_needs_days": "At least three practice days are required for a meaningful comparison.",
|
||||
"training.add_marker": "Mark a car change",
|
||||
"training.add_marker_hint": "The marker is saved now for the selected driver and class. The system compares 30 minutes before and after.",
|
||||
"training.marker_type": "Change type",
|
||||
"training.marker_setup": "New setup",
|
||||
"training.marker_tires": "Changed tires",
|
||||
"training.marker_suspension": "Changed suspension",
|
||||
"training.marker_car": "Changed car",
|
||||
"training.marker_note": "Custom note",
|
||||
"training.marker_description": "Description",
|
||||
"training.marker_placeholder": "For example softer front springs",
|
||||
"training.mark_now": "Mark change now",
|
||||
"training.no_markers": "There are no setup markers in this class.",
|
||||
"training.marker_collecting": "Collecting data ({before} before / {after} after)",
|
||||
"training.marker_improved": "{lap} faster after the change",
|
||||
"training.marker_slower": "{lap} slower after the change",
|
||||
"training.stint": "Stint",
|
||||
"training.start": "Start",
|
||||
"training.trimmed_pace": "Normal pace",
|
||||
"training.race_pace_10": "Race pace 10",
|
||||
"training.mistakes": "Mistakes",
|
||||
"training.start_end": "Start/end",
|
||||
"training.insufficient_data": "Not enough data",
|
||||
"training.no_stints": "No stints are available yet.",
|
||||
"training.stint_faster": "{lap} faster",
|
||||
"training.stint_slower": "{lap} slower",
|
||||
"training.stint_same": "Unchanged",
|
||||
"training.stint_analysis": "Stint analysis",
|
||||
"training.stint_analysis_hint": "A break longer than two minutes starts a new stint. Shorter stints are shown but not ranked.",
|
||||
"training.best_stint": "Best stint {stint}: {laps} laps, {pace}",
|
||||
"training.show_all_stints": "Show all {count} stints",
|
||||
"training.stats_method": "Normal pace uses a trimmed average. A mistake is a lap over 15% slower than the stint median. At least 3 laps are required for consistency and 10 for Race pace 10.",
|
||||
"training.split_passings": "Split passings",
|
||||
"training.best_split": "Best split",
|
||||
"training.average_split": "Average split",
|
||||
@@ -2556,6 +2638,10 @@ const TRANSLATIONS = {
|
||||
"guide.training_14": "14. One personal profile and mobile link can contain several classes, but 2WD/4WD statistics, stints, lap times, and recommendations are always shown separately for the selected class.",
|
||||
"guide.training_15": "15. The development card compares the latest 30 valid laps with the preceding 30 in the same class. A positive value means faster average pace or a smaller spread; insufficient data is shown as collecting rather than an unreliable trend.",
|
||||
"guide.training_16": "16. Achievements and the club progress feed recognize practice sessions, lap milestones, controlled driving, and completed five-minute stints. The feed follows recent activity and is not a ranking between drivers.",
|
||||
"guide.training_17": "17. Open Extra statistics for pace per active 30-minute block. Empty periods are hidden and pace uses a trimmed average so isolated crashes do not distort the comparison.",
|
||||
"guide.training_18": "18. Before changing the car, select New setup, tires, suspension, car, or a custom note and click Mark change now. The marker is stored only for the selected personal profile and class.",
|
||||
"guide.training_19": "19. Once at least three valid laps exist within 30 minutes both before and after the marker, the change is compared automatically. Only compare runs with similar track conditions.",
|
||||
"guide.training_20": "20. Stint analysis uses gaps longer than two minutes as boundaries. Normal pace is a trimmed average, mistakes are laps over 15 percent slower than the stint median, and Race pace 10 requires ten consecutive laps.",
|
||||
"overlay.title": "Overlay",
|
||||
"overlay.subtitle": "External leaderboard screen",
|
||||
"overlay.no_active": "No active session selected.",
|
||||
|
||||
Reference in New Issue
Block a user