diff --git a/README.md b/README.md index fab4e4a..04fc747 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Trail running focused Garmin watch DataField (for myself) - average - current - max - - gauge + - histogram - pace - current - average diff --git a/TODO.md b/TODO.md index f58b565..29bc45d 100644 --- a/TODO.md +++ b/TODO.md @@ -2,6 +2,5 @@ - pace/speed based on sport - imperial unit support -- hr gauge => hr zone distribution - track color => color coded by elevation gain/loss (or even vertical speed ?) - https://github.com/loukad/vertlover diff --git a/source/RepaFieldHeartRate.mc b/source/RepaFieldHeartRate.mc index 6385cdc..9c5386f 100644 --- a/source/RepaFieldHeartRate.mc +++ b/source/RepaFieldHeartRate.mc @@ -6,33 +6,34 @@ import Toybox.System; class HeartRate extends WatchUi.Drawable { - hidden var hrZones as Array; - hidden var hrValue as Numeric; - hidden var aColor as Graphics.ColorValue | Number; - hidden var y as Numeric; + hidden var hrHist as Array; + hidden var hrZoneColors as Array; + hidden var hrTicks as Number; + hidden var y as Number; function initialize(params as Dictionary) { Drawable.initialize(params); - hrZones = [100, 120, 140, 160, 180, 200]; - hrValue = 0.0f; - aColor = 0xFF8800; + hrZoneColors = UserProfile.getHeartRateZones(UserProfile.getCurrentSport()); + hrHist = [0, 0, 0, 0, 0, 0, 0]; + hrTicks = 0; + y = 64; if (params.hasKey(:y)) { y = params.get(:y) as Number; } } - function setHRZones(zones as Array) as Void { - hrZones = zones; + function setHRZoneColors(zoneColors as Array) as Void { + hrZoneColors = zoneColors; } - function setHRValue(value as Numeric) as Void { - hrValue = value; + function setHRHist(hist as Array) as Void { + hrHist = hist; } - function setHRColor(color) as Void { - aColor = color; + function setHRTicks(ticks as Number) as Void { + hrTicks = ticks; } function draw(dc as Dc) as Void { @@ -41,16 +42,16 @@ class HeartRate extends WatchUi.Drawable { var width = dc.getWidth(); dc.drawLine(width * .1, 64, width * .9, 64); - var percentage = 0.0f; - var zoneNr = hrZones.size(); - if (hrValue > hrZones[zoneNr - 1]) { - percentage = 1.0f; - } else if (hrValue < hrZones[0]) { - percentage = .0f; - } else { - percentage = (hrValue - hrZones[0]).toFloat() / (hrZones[zoneNr - 1] - hrZones[0]); + if (hrTicks == 0) { + return; + } + + var drawFrom = 0; + for (var i = 0; i < hrHist.size(); i++) { + var drawTo = (drawFrom + width * hrHist[i].toFloat() / hrTicks).toNumber(); + dc.setColor(hrZoneColors[i], Graphics.COLOR_TRANSPARENT); + dc.drawLine(drawFrom, y, drawTo, y); + drawFrom = drawTo; } - dc.setColor(aColor, Graphics.COLOR_TRANSPARENT); - dc.drawLine(width * .1, 64, width * (.1 + .8 * percentage), 64); } } diff --git a/source/RepaFieldView.mc b/source/RepaFieldView.mc index c4d030c..ea60640 100644 --- a/source/RepaFieldView.mc +++ b/source/RepaFieldView.mc @@ -13,6 +13,7 @@ class RepaFieldView extends WatchUi.DataField { hidden var themeColor2 as Numeric; hidden var themeColor3 as Numeric; hidden var hrZones as Array; + hidden var hrHist as Array; hidden var hrZoneColors as Array; hidden var cadenceZones as Array; hidden var cadenceZoneColors as Array; @@ -36,6 +37,7 @@ class RepaFieldView extends WatchUi.DataField { hidden var fHrGraph; // values + hidden var hrTicks as Number; hidden var hrValue as Numeric; hidden var ahrValue as Numeric; hidden var mhrValue as Numeric; @@ -62,6 +64,8 @@ class RepaFieldView extends WatchUi.DataField { ahrValue = 0; mhrValue = 0; hrZones = UserProfile.getHeartRateZones(UserProfile.getCurrentSport()); + hrHist = [0, 0, 0, 0, 0, 0, 0]; + hrTicks = 0; hrZoneColors = [Graphics.COLOR_DK_GRAY, Graphics.COLOR_LT_GRAY, Graphics.COLOR_BLUE, Graphics.COLOR_GREEN, Graphics.COLOR_YELLOW, Graphics.COLOR_RED, Graphics.COLOR_DK_RED]; cadenceZones = [153, 163, 173, 183]; cadenceZoneColors = [Graphics.COLOR_RED, Graphics.COLOR_YELLOW, Graphics.COLOR_GREEN, Graphics.COLOR_BLUE, Graphics.COLOR_PURPLE]; @@ -78,6 +82,19 @@ class RepaFieldView extends WatchUi.DataField { cadence = 0; } + function tickHr(v as Number) { + hrTicks++; + var hrzsize = hrZones.size(); + for (var i = 0; i < hrzsize; i++) { + if (v < hrZones[i]) { + hrHist[i]++; + return; + } + } + // out of range + hrHist[hrzsize]++; + } + function calculateZoneColor(v as Numeric, zones as Array, zoneColors as Array) as Numeric { for (var i = 0; i < zones.size(); i++) { if (v < zones[i]) { @@ -134,6 +151,9 @@ class RepaFieldView extends WatchUi.DataField { fMHr = View.findDrawableById("mhr") as Text; fHrGraph = View.findDrawableById("HeartRate") as HeartRate; + // init fields + fHrGraph.setHRZoneColors(hrZoneColors); + // theme setup fBgOverlay.setColor1(darken(themeColor, 4)); fBgOverlay.setColor2(darken(themeColor, 2)); @@ -147,6 +167,7 @@ class RepaFieldView extends WatchUi.DataField { function compute(info as Activity.Info) as Void { if(info.currentHeartRate != null) { hrValue = info.currentHeartRate as Number; + tickHr(hrValue); } else { hrValue = 0; } @@ -229,9 +250,8 @@ class RepaFieldView extends WatchUi.DataField { fMHr.setColor(darken(calculateZoneColor(mhrValue, hrZones, hrZoneColors), 2)); fMHr.setText(mhrValue.format("%d")); if (fHrGraph != null) { - fHrGraph.setHRColor(hrColor); - fHrGraph.setHRZones(hrZones); - fHrGraph.setHRValue(hrValue); + fHrGraph.setHRHist(hrHist); + fHrGraph.setHRTicks(hrTicks); } // track @@ -267,7 +287,7 @@ class RepaFieldView extends WatchUi.DataField { } if (fTimerSec != null) { fTimerSec.setColor(darken(timerColor, 1.5)); - fTimerSec.setText(trs.format("%02d")); + fTimerSec.setText(":" + trs.format("%02d")); } }