Add saved analysis workspace and live dashboard statistics
This commit is contained in:
@@ -1,5 +1,154 @@
|
||||
# Run analysis DSL
|
||||
|
||||
## Account library and live dashboard
|
||||
|
||||
Save an analysis with a name, investigation collection and notes. **Save as new**
|
||||
or **Duplicate** creates an independent query to explore another question.
|
||||
**Pin live analysis** adds it to your personal dashboard, where it can display a
|
||||
plot, summary values or a grouped table. Width and order are saved to your
|
||||
account. All queries and widget requests enforce owner scope, including shared
|
||||
friend profiles. Dashboard widgets refresh on load/focus and every five minutes
|
||||
while visible; each widget retains its own query date range. Relative periods
|
||||
advance with the calendar. Results are recomputed rather than saved as snapshots.
|
||||
|
||||
## Matched effort, reference ranges and persistent deviations
|
||||
|
||||
```text
|
||||
runs
|
||||
during last 12 weeks
|
||||
where pace between 5:20 and 5:40 /km
|
||||
and elevation_per_km <= 10 m/km
|
||||
and has heart_rate
|
||||
summarize weighted_mean(heart_rate) as "Matched-pace HR"
|
||||
by week
|
||||
compare none
|
||||
baseline previous 90 days
|
||||
flag above baseline 1.5 sd min 3 runs sustained 2 buckets
|
||||
chart line
|
||||
```
|
||||
|
||||
The baseline is the stated number of local calendar days immediately **before
|
||||
the query starts**, filtered with the same per-input conditions. It never uses
|
||||
the current cohort. The center uses the selected summary function; its range is
|
||||
center ± threshold × population standard deviation of individual matched
|
||||
inputs. This is a descriptive range, not a confidence interval or a diagnostic
|
||||
threshold. At least ten usable baseline inputs, and nonzero variation, are
|
||||
required. Totals, counts and standard deviations do not receive baseline bands.
|
||||
|
||||
`above`, `below` and `outside` are supported. Flags require the minimum usable
|
||||
inputs in **each** consecutive calendar bucket; missing, insufficient, in-range
|
||||
or opposite-direction buckets reset the streak. Only the bucket completing the
|
||||
streak and following qualifying buckets are marked. The grammar uses `runs` for
|
||||
the minimum count even for laps/segments; the displayed coverage uses the actual
|
||||
source. Segments from one run are correlated observations, so a high segment
|
||||
count does not imply many independent sessions. Calendar grouping is required;
|
||||
trend transforms and group removal/ranking cannot be combined with flags.
|
||||
Terrain, conditions, warm-up and sensor differences can still affect matched
|
||||
effort. Inspect the actual inputs and workload before interpreting a departure.
|
||||
|
||||
## Recording-level exploration
|
||||
|
||||
```text
|
||||
segments
|
||||
during last 12 weeks
|
||||
where pace between 5:20 and 5:40 /km
|
||||
and pace_variability <= 5 %
|
||||
and sensor_coverage >= 80 %
|
||||
and duration >= 4 min
|
||||
summarize weighted_mean(heart_rate)
|
||||
by week
|
||||
compare none
|
||||
chart line
|
||||
```
|
||||
|
||||
`segments` expands persisted five-minute **moving-time** segments; the final
|
||||
partial segment is retained, so filter duration when complete segments matter.
|
||||
The segments accumulate usable moving intervals across pauses/gaps rather than
|
||||
claiming five uninterrupted minutes. Intervals require increasing timestamps
|
||||
with at most ten seconds between recordings, positive plausible movement
|
||||
(0.5–15 m/s), and increasing distance. Missing sensor values are not interpolated.
|
||||
HR is duration weighted. Ascent requires elevation on at least 80% of usable
|
||||
moving intervals; otherwise it is missing. Ascent is the sum of positive raw
|
||||
altitude increments and can be sensitive to noise. Segment dates are the parent
|
||||
run's local start date; selecting one opens that run.
|
||||
|
||||
`laps` expands recorded lap distance, timer duration, HR and persisted GAP. Other
|
||||
sensor/terrain metrics remain missing when the lap does not record them. Neither
|
||||
source loads raw samples during a query. Their `count()` counts inputs; `by run`
|
||||
gives each lap/segment its own row. Run-history metrics and custom rolling
|
||||
calculations require `runs`.
|
||||
|
||||
Additional recording-derived metrics:
|
||||
|
||||
- `pace_variability`: duration-weighted **speed** coefficient of variation (%).
|
||||
- `sensor_coverage`: usable moving time with HR / usable moving time (%), excluding gaps and pauses.
|
||||
- `heart_rate_drift`: percent loss of speed/HR efficiency between moving-time halves. At least four moving minutes and ≥80% HR coverage in each half are required. Positive means lower efficiency later; warm-up and terrain are included.
|
||||
- `gap`: modelled grade-adjusted pace in seconds/km, formatted as min/km.
|
||||
|
||||
New imports calculate these; older activities require `backfill-analysis`.
|
||||
|
||||
## Visualization and named series
|
||||
|
||||
`chart auto|line|bar|area|histogram|box|heatmap|stacked|none` controls presentation.
|
||||
`display overlay` combines series with an axis per unit; `display separate` is
|
||||
the default. Summary labels use JSON double-quoted strings:
|
||||
|
||||
```text
|
||||
summarize sum(distance) as "Weekly distance", count() as "Sessions"
|
||||
reference heart_rate = 150 bpm
|
||||
plot pace vs heart_rate
|
||||
color by elevation_per_km
|
||||
size by distance
|
||||
```
|
||||
|
||||
References require the selected raw metric and compatible units. Scatter color
|
||||
and size require a scatter plot; missing encoding values use midpoint styling.
|
||||
Correlation uses paired per-input values, not grouped summaries.
|
||||
|
||||
Histograms bin **individual input values** using up to 30 equal-width bins;
|
||||
the final bin includes its upper endpoint. Boxes show min, p25, median, p75 and
|
||||
max per group, with no inferred outlier rule. Distribution charts show current
|
||||
inputs, while comparison cards retain the previous cohort. Calendar heatmaps
|
||||
require `by day` and retain every day. Missing data differs from a zero count.
|
||||
Distribution/heatmap overlays are not supported. PNG download exports the plot;
|
||||
CSV exports the raw underlying grouped or per-input values.
|
||||
|
||||
## Named training cohorts
|
||||
|
||||
```text
|
||||
runs
|
||||
during last 12 weeks
|
||||
summarize sum(distance)
|
||||
by week
|
||||
compare none
|
||||
cohort "Lower HR" where heart_rate <= 145 bpm
|
||||
cohort "Higher HR" where heart_rate > 145 bpm
|
||||
chart stacked
|
||||
```
|
||||
|
||||
Up to four named numeric conditions partition inputs in declaration order: the
|
||||
**first matching cohort wins**, avoiding double counting. Unmatched/missing
|
||||
inputs appear in Other / missing. Stacking requires one additive summary
|
||||
(sum/count, distance, duration, elevation or calories), with no comparison,
|
||||
baseline or trend. Thresholds are user-selected; names do not infer physiological zones.
|
||||
|
||||
## Custom rolling calculations and yearly comparisons
|
||||
|
||||
```text
|
||||
let hr_14d = rolling_mean(heart_rate, 14 days)
|
||||
let km_10d = rolling_sum(distance, 10 days)
|
||||
let hr_count = rolling_count(heart_rate, 14 days)
|
||||
compare previous year
|
||||
```
|
||||
|
||||
Rolling functions use complete owner-scoped run history before filters, include
|
||||
the current run, and exclude the exact lower elapsed-time boundary. They accept
|
||||
1–365 days and an earlier metric/calculation. Means are unweighted, sums exclude
|
||||
missing inputs, and counts count usable inputs. Calendar-bucket rolling trends
|
||||
remain separate operations. `compare previous year` uses the same local-date
|
||||
interval one year earlier, clamping leap-day boundaries; time charts align by
|
||||
elapsed days from each period's start.
|
||||
|
||||
Write queries in **Stats**, use **Ctrl+Space** for completion and **Ctrl/Cmd+Enter**
|
||||
to execute. **Format** produces a canonical query. Live validation uses the same
|
||||
parser as execution. Comments occupy their own lines starting with `#`.
|
||||
|
||||
Reference in New Issue
Block a user