From 2be2c9254c7ba8d848dd55ae92ae5a1d60c4ed4a Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Sat, 3 Oct 2020 16:40:58 +0300 Subject: [PATCH] Add freeride to zone types --- README.md | 1 - src/Intensity.ts | 15 +++++++++ src/ZoneType.ts | 21 +++++++++++++ src/index.ts | 2 +- src/stats/zoneDistribution.ts | 47 ++++++++--------------------- test/__snapshots__/cli.test.ts.snap | 5 +++ 6 files changed, 54 insertions(+), 37 deletions(-) create mode 100644 src/ZoneType.ts diff --git a/README.md b/README.md index caffb52..8b000f1 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,3 @@ - Unsupported params: message duration & y-position - More restricted syntax for text (with quotes) - Support for tags -- Include free-ride to zone types diff --git a/src/Intensity.ts b/src/Intensity.ts index bbde910..78eaf10 100644 --- a/src/Intensity.ts +++ b/src/Intensity.ts @@ -1,7 +1,10 @@ +import { intensityValueToZoneType, ZoneType } from "./ZoneType"; + export interface Intensity { readonly value: number; readonly start: number; readonly end: number; + readonly zone: ZoneType; } export class ConstantIntensity implements Intensity { @@ -18,6 +21,10 @@ export class ConstantIntensity implements Intensity { get end() { return this._value; } + + get zone() { + return intensityValueToZoneType(this._value); + } } export class RangeIntensity implements Intensity { @@ -34,6 +41,10 @@ export class RangeIntensity implements Intensity { get end() { return this._end; } + + get zone() { + return intensityValueToZoneType(this.value); + } } export class FreeIntensity implements Intensity { @@ -48,4 +59,8 @@ export class FreeIntensity implements Intensity { get end() { return 0; } + + get zone() { + return "free" as ZoneType; + } } diff --git a/src/ZoneType.ts b/src/ZoneType.ts new file mode 100644 index 0000000..e948c53 --- /dev/null +++ b/src/ZoneType.ts @@ -0,0 +1,21 @@ +export type ZoneType = "Z1" | "Z2" | "Z3" | "Z4" | "Z5" | "Z6" | "free"; + +// Intensity ranges based on https://zwiftinsider.com/power-zone-colors/ +export const intensityValueToZoneType = (intensity: number): ZoneType => { + if (intensity >= 1.18) { + return "Z6"; + } + if (intensity >= 1.05) { + return "Z5"; + } + if (intensity >= 0.9) { + return "Z4"; + } + if (intensity >= 0.75) { + return "Z3"; + } + if (intensity >= 0.6) { + return "Z2"; + } + return "Z1"; +}; diff --git a/src/index.ts b/src/index.ts index 0f5718c..733a032 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,9 +7,9 @@ export { parseCliOptions } from "./parseCliOptions"; export { Workout, Interval, Comment } from "./ast"; export { Duration } from "./Duration"; export { Intensity, ConstantIntensity, RangeIntensity, FreeIntensity } from "./Intensity"; +export { ZoneType } from "./ZoneType"; // utils export { totalDuration } from "./stats/totalDuration"; -export { intensityToZoneIndex, ZoneIndex } from "./stats/zoneDistribution"; export { maximumIntensity } from "./stats/maximumIntensity"; export { chunkRangeIntervals } from "./utils/chunkRangeIntervals"; diff --git a/src/stats/zoneDistribution.ts b/src/stats/zoneDistribution.ts index 2bc67d5..5e68741 100644 --- a/src/stats/zoneDistribution.ts +++ b/src/stats/zoneDistribution.ts @@ -1,50 +1,27 @@ import { Interval } from "../ast"; import { Duration } from "../Duration"; -import { Intensity } from "../Intensity"; +import { intensityValueToZoneType, ZoneType } from "../ZoneType"; import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers"; type NumericZoneDuration = { name: string; duration: number }; type ZoneDuration = { name: string; duration: Duration }; -export type ZoneIndex = 0 | 1 | 2 | 3 | 4 | 5; -const emptyZones = (): NumericZoneDuration[] => [ - { name: "Z1: Recovery", duration: 0 }, - { name: "Z2: Endurance", duration: 0 }, - { name: "Z3: Tempo", duration: 0 }, - { name: "Z4: Threshold", duration: 0 }, - { name: "Z5: VO2 Max", duration: 0 }, - { name: "Z6: Anaerobic", duration: 0 }, -]; - -// Intensity ranges based on https://zwiftinsider.com/power-zone-colors/ -const zoneIndex = (intensity: number): ZoneIndex => { - if (intensity >= 1.18) { - return 5; - } - if (intensity >= 1.05) { - return 4; - } - if (intensity >= 0.9) { - return 3; - } - if (intensity >= 0.75) { - return 2; - } - if (intensity >= 0.6) { - return 1; - } - return 0; -}; - -// For external use (consumes Intensity interface instead of plain number) -export const intensityToZoneIndex = (intensity: Intensity): ZoneIndex => zoneIndex(intensity.value); +const emptyZones = (): Record => ({ + Z1: { name: "Z1: Recovery", duration: 0 }, + Z2: { name: "Z2: Endurance", duration: 0 }, + Z3: { name: "Z3: Tempo", duration: 0 }, + Z4: { name: "Z4: Threshold", duration: 0 }, + Z5: { name: "Z5: VO2 Max", duration: 0 }, + Z6: { name: "Z6: Anaerobic", duration: 0 }, + free: { name: "Freeride", duration: 0 }, +}); export const zoneDistribution = (intervals: Interval[]): ZoneDuration[] => { const zones = emptyZones(); intervalsToIntensityNumbers(intervals).forEach((intensity) => { - zones[zoneIndex(intensity)].duration++; + zones[intensityValueToZoneType(intensity)].duration++; }); - return zones.map(({ duration, ...rest }) => ({ duration: new Duration(duration), ...rest })); + return Object.values(zones).map(({ duration, ...rest }) => ({ duration: new Duration(duration), ...rest })); }; diff --git a/test/__snapshots__/cli.test.ts.snap b/test/__snapshots__/cli.test.ts.snap index 9596e3b..211ddd1 100644 --- a/test/__snapshots__/cli.test.ts.snap +++ b/test/__snapshots__/cli.test.ts.snap @@ -254,6 +254,7 @@ Zone Distribution: 1 min - Z4: Threshold 3 min - Z5: VO2 Max 0 min - Z6: Anaerobic + 0 min - Freeride " `; @@ -273,6 +274,7 @@ Zone Distribution: 0 min - Z4: Threshold 0 min - Z5: VO2 Max 3 min - Z6: Anaerobic + 0 min - Freeride " `; @@ -292,6 +294,7 @@ Zone Distribution: 0 min - Z4: Threshold 3 min - Z5: VO2 Max 2 min - Z6: Anaerobic + 0 min - Freeride " `; @@ -311,6 +314,7 @@ Zone Distribution: 37 min - Z4: Threshold 1 min - Z5: VO2 Max 0 min - Z6: Anaerobic + 0 min - Freeride " `; @@ -330,5 +334,6 @@ Zone Distribution: 24 min - Z4: Threshold 0 min - Z5: VO2 Max 0 min - Z6: Anaerobic + 0 min - Freeride " `;