Skip to main content

Series, route and views

stats() answers with numbers. When you want the samples themselves, or the line the activity followed, or data shaped for a screen, there are three more ways in, kept apart from the numbers.

Series: the measured values over time​

series holds each recorded channel as its samples, on the activity's clock. A gap is null, never a zero. Any section has one too, holding only its own samples.

import { readFileSync } from 'node:fs';
import { minutes } from '@pond-ts/fit';
import { readActivity } from '@pond-ts/fit/files';

const run = readActivity(readFileSync('interval-run.fit'));

const hr = run.series.heartRate!;
console.log(hr.length, 'samples, in', hr.unit);
const p = hr.at(600)!;
console.log(p.elapsed.format(), p.value?.format());

const rep = run.section({ elapsed: { from: minutes(10), to: minutes(11) } });
console.log(rep.series.heartRate!.length, run.series.power);
3084 samples, in bpm
10:00 135 bpm
61 null

A channel the activity didn't record is null, and so is every channel when the samples carry no timestamps. speed is worked out from distance and time between samples rather than recorded, and distance is metres from the start on the activity's own distance axis.

The way down to pond is one explicit call: toTimeSeries() gives a pond TimeSeries with one value column.

const ts = hr.toTimeSeries();
console.log(ts.length, ts.at(0)!.get('value'));
3084 88

Route: the line on the map​

route is the line the activity followed and the box around it; null with no GPS.

const route = run.route!;
console.log(route.points.length, route.cleaned);
console.log(route.bounds.southWest, route.bounds.northEast);
3084 false
[ 44.11861647851765, 6.980010671541095 ] [ 44.1213786508888, 7.043941542506218 ]

Views: shaped for a chart or a map​

@pond-ts/fit/views turns an activity into what a screen draws, so the activity itself stays free of any one screen's needs.

chartData gives one pond series with a column per metric, keyed by time, or by distance with x: 'distance'. Either goes straight into @pond-ts/charts.

import { chartData, mapData } from '@pond-ts/fit/views';

const byTime = chartData(run, { metrics: ['heartRate', 'pace'] });
console.log(byTime.metrics, byTime.series.length);

const byDistance = chartData(run, { x: 'distance', metrics: ['heartRate'] });
console.log(byDistance.series.length);
[ 'heartRate', 'pace' ] 3084
3084

mapData gives the route's line at the detail a map needs: every point, a thumbnail line, or a tolerance in metres.

console.log(
mapData(route).points.length,
mapData(route, { detail: 'thumbnail' }).points.length,
);
3084 17