mirror of
https://github.com/dyuri/garmin-repafield.git
synced 2025-12-16 19:24:01 +00:00
#6 summary fields, start/stop
This commit is contained in:
parent
2cbbd4cb4a
commit
f786b96ba6
@ -26,6 +26,12 @@ Trail running focused Garmin watch DataField (for myself)
|
|||||||
- distance
|
- distance
|
||||||
- name
|
- name
|
||||||
|
|
||||||
|
# FIT data
|
||||||
|
|
||||||
|
- grade
|
||||||
|
- GAP
|
||||||
|
- vertical speed
|
||||||
|
|
||||||
# Settings
|
# Settings
|
||||||
|
|
||||||
- 3 theme colors
|
- 3 theme colors
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. -->
|
<!-- This is a generated file. It is highly recommended that you DO NOT edit this file. -->
|
||||||
<iq:manifest version="3" xmlns:iq="http://www.garmin.com/xml/connectiq">
|
<iq:manifest version="3" xmlns:iq="http://www.garmin.com/xml/connectiq">
|
||||||
<iq:application id="d0f125e7-b43a-46ab-927e-87396eda74a0" type="datafield" name="@Strings.AppName" entry="RepaFieldApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.2.0">
|
<iq:application id="d0f125e7-b43a-46ab-927e-87396eda74a0" type="datafield" name="@Strings.AppName" entry="RepaFieldApp" launcherIcon="@Drawables.LauncherIcon" minApiLevel="3.1.0">
|
||||||
<iq:products>
|
<iq:products>
|
||||||
<iq:product id="approachs7042mm"/>
|
<iq:product id="approachs7042mm"/>
|
||||||
<iq:product id="approachs7047mm"/>
|
<iq:product id="approachs7047mm"/>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
<fitContributions>
|
<fitContributions>
|
||||||
|
<!-- grade -->
|
||||||
<fitField id="0"
|
<fitField id="0"
|
||||||
displayInChart="true"
|
displayInChart="true"
|
||||||
sortOrder="0"
|
sortOrder="0"
|
||||||
@ -7,6 +8,31 @@
|
|||||||
dataLabel="@Strings.chartGrade"
|
dataLabel="@Strings.chartGrade"
|
||||||
unitLabel="@Strings.uGrade"
|
unitLabel="@Strings.uGrade"
|
||||||
fillColor="#00FFFF" />
|
fillColor="#00FFFF" />
|
||||||
|
<fitField id="5"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="5"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitMinGrade"
|
||||||
|
unitLabel="@Strings.uGrade" />
|
||||||
|
<fitField id="6"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="6"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitMaxGrade"
|
||||||
|
unitLabel="@Strings.uGrade" />
|
||||||
|
<fitField id="7"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="7"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAGrade"
|
||||||
|
unitLabel="@Strings.uGrade" />
|
||||||
|
<fitField id="8"
|
||||||
|
displayInActivityLaps="true"
|
||||||
|
sortOrder="8"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAGrade"
|
||||||
|
unitLabel="@Strings.uGrade" />
|
||||||
|
<!-- GAP -->
|
||||||
<fitField id="1"
|
<fitField id="1"
|
||||||
displayInChart="true"
|
displayInChart="true"
|
||||||
sortOrder="1"
|
sortOrder="1"
|
||||||
@ -15,6 +41,19 @@
|
|||||||
dataLabel="@Strings.chartGAP"
|
dataLabel="@Strings.chartGAP"
|
||||||
unitLabel="@Strings.uGAP"
|
unitLabel="@Strings.uGAP"
|
||||||
fillColor="#AAFF44" />
|
fillColor="#AAFF44" />
|
||||||
|
<fitField id="3"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="3"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAGAP"
|
||||||
|
unitLabel="@Strings.uGAP" />
|
||||||
|
<fitField id="4"
|
||||||
|
displayInActivityLaps="true"
|
||||||
|
sortOrder="4"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAGAP"
|
||||||
|
unitLabel="@Strings.uGAP" />
|
||||||
|
<!-- vertical speed -->
|
||||||
<fitField id="2"
|
<fitField id="2"
|
||||||
displayInChart="true"
|
displayInChart="true"
|
||||||
sortOrder="2"
|
sortOrder="2"
|
||||||
@ -23,5 +62,28 @@
|
|||||||
dataLabel="@Strings.chartVSpeed"
|
dataLabel="@Strings.chartVSpeed"
|
||||||
unitLabel="@Strings.uVSpeed"
|
unitLabel="@Strings.uVSpeed"
|
||||||
fillColor="#FF8888" />
|
fillColor="#FF8888" />
|
||||||
<!-- TODO average GAP, max/min grade, max/min vspeed -->
|
<fitField id="9"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="9"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitMinVSpeed"
|
||||||
|
unitLabel="@Strings.uVSpeed" />
|
||||||
|
<fitField id="10"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="10"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitMaxVSpeed"
|
||||||
|
unitLabel="@Strings.uVSpeed" />
|
||||||
|
<fitField id="11"
|
||||||
|
displayInActivitySummary="true"
|
||||||
|
sortOrder="11"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAVSpeed"
|
||||||
|
unitLabel="@Strings.uVSpeed" />
|
||||||
|
<fitField id="12"
|
||||||
|
displayInActivityLaps="true"
|
||||||
|
sortOrder="12"
|
||||||
|
precision="2"
|
||||||
|
dataLabel="@Strings.fitAVSpeed"
|
||||||
|
unitLabel="@Strings.uVSpeed" />
|
||||||
</fitContributions>
|
</fitContributions>
|
||||||
|
|||||||
@ -6,6 +6,6 @@
|
|||||||
<property id="hrDisplay" type="number">0</property>
|
<property id="hrDisplay" type="number">0</property>
|
||||||
<property id="speedNotPace" type="boolean">false</property>
|
<property id="speedNotPace" type="boolean">false</property>
|
||||||
<property id="showNextPoint" type="boolean">true</property>
|
<property id="showNextPoint" type="boolean">true</property>
|
||||||
<property id="saveToFit" type="boolean">true</property>
|
<property id="saveToFit" type="boolean">false</property>
|
||||||
<property id="tlFieldData" type="number">1</property>
|
<property id="tlFieldData" type="number">1</property>
|
||||||
</properties>
|
</properties>
|
||||||
|
|||||||
@ -22,4 +22,11 @@
|
|||||||
<string id="chartGrade">Grade</string>
|
<string id="chartGrade">Grade</string>
|
||||||
<string id="chartGAP">Grade Adjusted Pace</string>
|
<string id="chartGAP">Grade Adjusted Pace</string>
|
||||||
<string id="chartVSpeed">Vertical Speed</string>
|
<string id="chartVSpeed">Vertical Speed</string>
|
||||||
|
<string id="fitAGrade">Grade (average)</string>
|
||||||
|
<string id="fitMinGrade">Grade (min)</string>
|
||||||
|
<string id="fitMaxGrade">Grade (max)</string>
|
||||||
|
<string id="fitAGAP">Grade Adjusted Pace (average)</string>
|
||||||
|
<string id="fitAVSpeed">Vertical Speed (average)</string>
|
||||||
|
<string id="fitMinVSpeed">Vertical Speed (min)</string>
|
||||||
|
<string id="fitMaxVSpeed">Vertical Speed (max)</string>
|
||||||
</strings>
|
</strings>
|
||||||
|
|||||||
@ -58,8 +58,9 @@ class Track extends WatchUi.Drawable {
|
|||||||
var h = dc.getHeight();
|
var h = dc.getHeight();
|
||||||
var astart = 150;
|
var astart = 150;
|
||||||
var aend = 390;
|
var aend = 390;
|
||||||
|
var offtrack = _offCourse > 50.0f;
|
||||||
dc.setPenWidth((dc.getWidth() * 0.01).toNumber());
|
dc.setPenWidth((dc.getWidth() * 0.01).toNumber());
|
||||||
dc.setColor(0x555555, Graphics.COLOR_TRANSPARENT);
|
dc.setColor(offtrack ? 0x880000 : 0x555555, Graphics.COLOR_TRANSPARENT);
|
||||||
dc.drawArc(w / 2, h / 2, w / 2 - 2, Graphics.ARC_COUNTER_CLOCKWISE, astart, aend);
|
dc.drawArc(w / 2, h / 2, w / 2 - 2, Graphics.ARC_COUNTER_CLOCKWISE, astart, aend);
|
||||||
|
|
||||||
if (trackPercentage <= 0.0f) {
|
if (trackPercentage <= 0.0f) {
|
||||||
@ -67,7 +68,7 @@ class Track extends WatchUi.Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// color
|
// color
|
||||||
if (_offCourse > 50.0f) {
|
if (offtrack) {
|
||||||
dc.setColor(0xFF0000, Graphics.COLOR_TRANSPARENT);
|
dc.setColor(0xFF0000, Graphics.COLOR_TRANSPARENT);
|
||||||
} else if (trackPercentage < 0.2) {
|
} else if (trackPercentage < 0.2) {
|
||||||
dc.setColor(0x8800FF, Graphics.COLOR_TRANSPARENT);
|
dc.setColor(0x8800FF, Graphics.COLOR_TRANSPARENT);
|
||||||
@ -100,7 +101,7 @@ class Track extends WatchUi.Drawable {
|
|||||||
anext = aend;
|
anext = aend;
|
||||||
}
|
}
|
||||||
dc.setPenWidth((dc.getWidth() * 0.01).toNumber());
|
dc.setPenWidth((dc.getWidth() * 0.01).toNumber());
|
||||||
dc.setColor(0xFFFF00, Graphics.COLOR_TRANSPARENT);
|
dc.setColor(offtrack ? 0xAA0000 : 0xAAAAAA, Graphics.COLOR_TRANSPARENT);
|
||||||
dc.drawArc(w / 2, h / 2, w / 2 - 2, Graphics.ARC_COUNTER_CLOCKWISE, acurrent, anext);
|
dc.drawArc(w / 2, h / 2, w / 2 - 2, Graphics.ARC_COUNTER_CLOCKWISE, acurrent, anext);
|
||||||
|
|
||||||
// next point name
|
// next point name
|
||||||
|
|||||||
@ -16,8 +16,18 @@ const TLF_GAP = 2;
|
|||||||
const TLF_VSPEED = 3;
|
const TLF_VSPEED = 3;
|
||||||
|
|
||||||
const FIT_GRADE_ID = 0;
|
const FIT_GRADE_ID = 0;
|
||||||
|
const FIT_GRADE_SUM_MIN_ID = 5;
|
||||||
|
const FIT_GRADE_SUM_MAX_ID = 6;
|
||||||
|
const FIT_GRADE_SUM_AVG_ID = 7;
|
||||||
|
const FIT_GRADE_LAP_AVG_ID = 8;
|
||||||
const FIT_GAP_ID = 1;
|
const FIT_GAP_ID = 1;
|
||||||
|
const FIT_GAP_SUM_AVG_ID = 3;
|
||||||
|
const FIT_GAP_LAP_AVG_ID = 4;
|
||||||
const FIT_VSPEED_ID = 2;
|
const FIT_VSPEED_ID = 2;
|
||||||
|
const FIT_VSPEED_SUM_MIN_ID = 9;
|
||||||
|
const FIT_VSPEED_SUM_MAX_ID = 10;
|
||||||
|
const FIT_VSPEED_SUM_AVG_ID = 11;
|
||||||
|
const FIT_VSPEED_LAP_AVG_ID = 12;
|
||||||
|
|
||||||
function displayHr(hr as Number, type as Number, zones as Array<Number>) as String {
|
function displayHr(hr as Number, type as Number, zones as Array<Number>) as String {
|
||||||
if (hr == 0) {
|
if (hr == 0) {
|
||||||
@ -86,10 +96,15 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
|
|
||||||
// fit
|
// fit
|
||||||
hidden var fitGrade;
|
hidden var fitGrade;
|
||||||
|
hidden var fitGradeSumAvg;
|
||||||
|
hidden var fitGradeLapAvg;
|
||||||
hidden var fitGAP;
|
hidden var fitGAP;
|
||||||
hidden var fitVSpeed;
|
hidden var fitVSpeed;
|
||||||
|
hidden var fitVSpeedSumAvg;
|
||||||
|
hidden var fitVSpeedLapAvg;
|
||||||
|
|
||||||
// values
|
// values
|
||||||
|
hidden var timerRunning as Boolean = false;
|
||||||
hidden var hrTicks as Number;
|
hidden var hrTicks as Number;
|
||||||
hidden var hrValue as Numeric;
|
hidden var hrValue as Numeric;
|
||||||
hidden var ahrValue as Numeric;
|
hidden var ahrValue as Numeric;
|
||||||
@ -110,10 +125,10 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
hidden var edrop as Number;
|
hidden var edrop as Number;
|
||||||
hidden var cadence as Number;
|
hidden var cadence as Number;
|
||||||
hidden var grade as RollingAverage;
|
hidden var grade as RollingAverage;
|
||||||
hidden var cgrade as Float;
|
hidden var cgrade;
|
||||||
hidden var vspeed as RollingAverage;
|
hidden var vspeed as RollingAverage;
|
||||||
hidden var cvspeed as Float;
|
hidden var cvspeed;
|
||||||
hidden var gap as Float;
|
hidden var cgap;
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
DataField.initialize();
|
DataField.initialize();
|
||||||
@ -155,10 +170,10 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
edrop = 0;
|
edrop = 0;
|
||||||
cadence = 0;
|
cadence = 0;
|
||||||
grade = new RollingAverage(10);
|
grade = new RollingAverage(10);
|
||||||
cgrade = 0.0f;
|
cgrade = null;
|
||||||
vspeed = new RollingAverage(10);
|
vspeed = new RollingAverage(10);
|
||||||
cvspeed = 0.0f;
|
cvspeed = null;
|
||||||
gap = 0.0f;
|
cgap = null;
|
||||||
|
|
||||||
var settings = System.getDeviceSettings();
|
var settings = System.getDeviceSettings();
|
||||||
isDistanceMetric = settings.distanceUnits == System.UNIT_METRIC;
|
isDistanceMetric = settings.distanceUnits == System.UNIT_METRIC;
|
||||||
@ -166,9 +181,14 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
isPaceMetric = settings.paceUnits == System.UNIT_METRIC;
|
isPaceMetric = settings.paceUnits == System.UNIT_METRIC;
|
||||||
|
|
||||||
// fit fields
|
// fit fields
|
||||||
|
// TODO: refator into separate function/class
|
||||||
fitGrade = null;
|
fitGrade = null;
|
||||||
|
fitGradeSumAvg = null;
|
||||||
|
fitGradeLapAvg = null;
|
||||||
fitGAP = null;
|
fitGAP = null;
|
||||||
fitVSpeed = null;
|
fitVSpeed = null;
|
||||||
|
fitVSpeedSumAvg = null;
|
||||||
|
fitVSpeedLapAvg = null;
|
||||||
if (Application.Properties.getValue("saveToFit")) {
|
if (Application.Properties.getValue("saveToFit")) {
|
||||||
fitGrade = DataField.createField(
|
fitGrade = DataField.createField(
|
||||||
"grade",
|
"grade",
|
||||||
@ -179,6 +199,24 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
:units=>"%",
|
:units=>"%",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
fitGradeSumAvg = DataField.createField(
|
||||||
|
"avg_grade",
|
||||||
|
FIT_GRADE_SUM_AVG_ID,
|
||||||
|
FitContributor.DATA_TYPE_FLOAT,
|
||||||
|
{
|
||||||
|
:mesgType=>FitContributor.MESG_TYPE_RECORD,
|
||||||
|
:units=>"%",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
fitGradeLapAvg = DataField.createField(
|
||||||
|
"avg_grade",
|
||||||
|
FIT_GRADE_LAP_AVG_ID,
|
||||||
|
FitContributor.DATA_TYPE_FLOAT,
|
||||||
|
{
|
||||||
|
:mesgType=>FitContributor.MESG_TYPE_RECORD,
|
||||||
|
:units=>"%",
|
||||||
|
}
|
||||||
|
);
|
||||||
fitGAP = DataField.createField(
|
fitGAP = DataField.createField(
|
||||||
"gap",
|
"gap",
|
||||||
FIT_GAP_ID,
|
FIT_GAP_ID,
|
||||||
@ -197,9 +235,58 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
:units=>isElevationMetric ? "m/min" : "ft/min",
|
:units=>isElevationMetric ? "m/min" : "ft/min",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
fitVSpeedSumAvg = DataField.createField(
|
||||||
|
"avg_vspeed",
|
||||||
|
FIT_VSPEED_SUM_AVG_ID,
|
||||||
|
FitContributor.DATA_TYPE_FLOAT,
|
||||||
|
{
|
||||||
|
:mesgType=>FitContributor.MESG_TYPE_RECORD,
|
||||||
|
:units=>isElevationMetric ? "m/min" : "ft/min",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
fitVSpeedLapAvg = DataField.createField(
|
||||||
|
"avg_vspeed",
|
||||||
|
FIT_VSPEED_LAP_AVG_ID,
|
||||||
|
FitContributor.DATA_TYPE_FLOAT,
|
||||||
|
{
|
||||||
|
:mesgType=>FitContributor.MESG_TYPE_RECORD,
|
||||||
|
:units=>isElevationMetric ? "m/min" : "ft/min",
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function onNextMultisportLeg() as Void {
|
||||||
|
grade.reset();
|
||||||
|
vspeed.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerLap() as Void {
|
||||||
|
grade.lapReset();
|
||||||
|
vspeed.lapReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerReset() as Void {
|
||||||
|
grade.reset();
|
||||||
|
vspeed.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerStart() as Void {
|
||||||
|
timerRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerResume() as Void {
|
||||||
|
timerRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerPause() as Void {
|
||||||
|
timerRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onTimerStop() as Void {
|
||||||
|
timerRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
function tickHr(v as Number) {
|
function tickHr(v as Number) {
|
||||||
hrTicks++;
|
hrTicks++;
|
||||||
var hrzsize = hrZones.size();
|
var hrzsize = hrZones.size();
|
||||||
@ -295,7 +382,7 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
function compute(info as Activity.Info) as Void {
|
function compute(info as Activity.Info) as Void {
|
||||||
// update rolling values before updating normal fields
|
// update rolling values before updating normal fields
|
||||||
// only calculate them when some time has passed
|
// only calculate them when some time has passed
|
||||||
if (info.timerTime != null && info.timerTime > 0) {
|
if (info.timerTime != null && info.timerTime > 0 && timerRunning) {
|
||||||
if (info.altitude != null) {
|
if (info.altitude != null) {
|
||||||
var altChange = info.altitude - altitude;
|
var altChange = info.altitude - altitude;
|
||||||
|
|
||||||
@ -305,7 +392,10 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
if (distChange > 0) {
|
if (distChange > 0) {
|
||||||
grade.insert(altChange / distChange);
|
grade.insert(altChange / distChange);
|
||||||
}
|
}
|
||||||
cgrade = grade.get() * 100;
|
var currentGrade = grade.getRolling();
|
||||||
|
if (currentGrade) {
|
||||||
|
cgrade = currentGrade * 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// vspeed - m/min or ft/min
|
// vspeed - m/min or ft/min
|
||||||
@ -316,7 +406,10 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
} else {
|
} else {
|
||||||
vspeed.insert(altChange / (timerChange / 60000.0));
|
vspeed.insert(altChange / (timerChange / 60000.0));
|
||||||
}
|
}
|
||||||
cvspeed = vspeed.get();
|
var currentVSpeed = vspeed.getRolling();
|
||||||
|
if (currentVSpeed != null ) {
|
||||||
|
cvspeed = currentVSpeed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -415,7 +508,9 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
cadence = 0;
|
cadence = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gap = adjustPaceForGrade(pace, cgrade / 100);
|
if (cgrade != null) {
|
||||||
|
cgap = adjustPaceForGrade(pace, cgrade / 100);
|
||||||
|
}
|
||||||
|
|
||||||
// convert units to imperial if needed
|
// convert units to imperial if needed
|
||||||
if (!isDistanceMetric) {
|
if (!isDistanceMetric) {
|
||||||
@ -435,17 +530,30 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fit update
|
// fit update
|
||||||
if (fitGrade != null) {
|
// TODO: refactor into separate function/class
|
||||||
fitGrade.setData(cgrade);
|
if (timerRunning) {
|
||||||
}
|
if (fitGrade != null) {
|
||||||
if (fitGAP != null) {
|
fitGrade.setData(cgrade ? cgrade : 0);
|
||||||
fitGAP.setData(gap);
|
var gradeSumAvg = grade.totalAvg();
|
||||||
}
|
fitGradeSumAvg.setData(gradeSumAvg ? gradeSumAvg : 0);
|
||||||
if (fitVSpeed != null) {
|
var gradeLapAvg = grade.lapAvg();
|
||||||
fitVSpeed.setData(cvspeed);
|
fitGradeLapAvg.setData(gradeLapAvg ? gradeLapAvg : 0);
|
||||||
|
}
|
||||||
|
if (fitGAP != null) {
|
||||||
|
fitGAP.setData(cgap ? cgap : 0);
|
||||||
|
}
|
||||||
|
if (fitVSpeed != null) {
|
||||||
|
fitVSpeed.setData(cvspeed ? cvspeed : 0);
|
||||||
|
var vsSumAvg = grade.totalAvg();
|
||||||
|
fitVSpeedSumAvg.setData(vsSumAvg ? vsSumAvg : 0);
|
||||||
|
var vsLapAvg = grade.lapAvg();
|
||||||
|
fitVSpeedLapAvg.setData(vsLapAvg ? vsLapAvg : 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: onlap - reset lap metrics
|
||||||
|
|
||||||
// Display the value you computed here. This will be called
|
// Display the value you computed here. This will be called
|
||||||
// once a second when the data field is visible.
|
// once a second when the data field is visible.
|
||||||
function onUpdate(dc as Dc) as Void {
|
function onUpdate(dc as Dc) as Void {
|
||||||
@ -559,30 +667,38 @@ class RepaFieldView extends WatchUi.DataField {
|
|||||||
// TLF
|
// TLF
|
||||||
if (fCadence != null) {
|
if (fCadence != null) {
|
||||||
if (tlFieldData == TLF_GRADE) {
|
if (tlFieldData == TLF_GRADE) {
|
||||||
var gradeColor = calculateZoneColor(cgrade, gradeZones, gradeZoneColors);
|
if (cgrade != null) {
|
||||||
fCadence.setColor(gradeColor);
|
var gradeColor = calculateZoneColor(cgrade, gradeZones, gradeZoneColors);
|
||||||
if (cgrade >= 10 || cgrade <= -10) {
|
fCadence.setColor(gradeColor);
|
||||||
fCadence.setText(cgrade.format("%.0f"));
|
if (cgrade >= 10 || cgrade <= -10) {
|
||||||
|
fCadence.setText(cgrade.format("%.0f"));
|
||||||
|
} else {
|
||||||
|
fCadence.setText(cgrade.format("%.1f"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fCadence.setText(cgrade.format("%.1f"));
|
fCadence.setText("-");
|
||||||
}
|
}
|
||||||
} else if (tlFieldData == TLF_GAP) {
|
} else if (tlFieldData == TLF_GAP) {
|
||||||
fCadence.setColor(themeColor2);
|
fCadence.setColor(themeColor2);
|
||||||
if (pace != 0) {
|
if (pace != 0 && cgap != null) {
|
||||||
// TODO color
|
// TODO color
|
||||||
var gapmin = gap.toNumber();
|
var gapmin = cgap.toNumber();
|
||||||
var gapsec = (gap - gapmin) * 60;
|
var gapsec = (cgap - gapmin) * 60;
|
||||||
fCadence.setText(gapmin.format("%d") + ":" + gapsec.format("%02d"));
|
fCadence.setText(gapmin.format("%d") + ":" + gapsec.format("%02d"));
|
||||||
} else {
|
} else {
|
||||||
fCadence.setText("-");
|
fCadence.setText("-");
|
||||||
}
|
}
|
||||||
} else if (tlFieldData == TLF_VSPEED) {
|
} else if (tlFieldData == TLF_VSPEED) {
|
||||||
var vsColor = calculateZoneColor(cvspeed, vsZones, vsZoneColors);
|
if (cvspeed != null) {
|
||||||
fCadence.setColor(vsColor);
|
var vsColor = calculateZoneColor(cvspeed, vsZones, vsZoneColors);
|
||||||
if (cvspeed >= 10 || cvspeed <= -10) {
|
fCadence.setColor(vsColor);
|
||||||
fCadence.setText(cvspeed.format("%.0f"));
|
if (cvspeed >= 10 || cvspeed <= -10) {
|
||||||
|
fCadence.setText(cvspeed.format("%.0f"));
|
||||||
|
} else {
|
||||||
|
fCadence.setText(cvspeed.format("%.1f"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fCadence.setText(cvspeed.format("%.1f"));
|
fCadence.setText("-");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var cadenceColor = calculateZoneColor(cadence, cadenceZones, cadenceZoneColors);
|
var cadenceColor = calculateZoneColor(cadence, cadenceZones, cadenceZoneColors);
|
||||||
|
|||||||
@ -5,21 +5,94 @@ import Toybox.System;
|
|||||||
|
|
||||||
class RollingAverage {
|
class RollingAverage {
|
||||||
hidden var _size as Number;
|
hidden var _size as Number;
|
||||||
hidden var _values as Array<Numeric>;
|
hidden var _safeCount as Number;
|
||||||
|
hidden var _values as Array<Float>;
|
||||||
hidden var _index as Number;
|
hidden var _index as Number;
|
||||||
|
hidden var _last;
|
||||||
|
hidden var _totalSum as Float;
|
||||||
|
hidden var _totalCount as Number;
|
||||||
|
hidden var _totalMin;
|
||||||
|
hidden var _totalMax;
|
||||||
|
hidden var _lapSum;
|
||||||
|
hidden var _lapCount as Number;
|
||||||
|
hidden var _lapMin;
|
||||||
|
hidden var _lapMax;
|
||||||
|
|
||||||
function initialize(size as Number) {
|
function initialize(size as Number) {
|
||||||
_size = size;
|
_size = size;
|
||||||
|
_safeCount = size * 2;
|
||||||
_values = new[size];
|
_values = new[size];
|
||||||
_index = 0;
|
_index = 0;
|
||||||
|
_last = null;
|
||||||
|
|
||||||
|
_totalSum = 0.0;
|
||||||
|
_totalCount = 0;
|
||||||
|
_totalMin = null;
|
||||||
|
_totalMax = null;
|
||||||
|
|
||||||
|
_lapSum = 0.0;
|
||||||
|
_lapCount = 0;
|
||||||
|
_lapMin = null;
|
||||||
|
_lapMax = null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSafeCount(count as Number) {
|
||||||
|
_safeCount = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
function insert(value as Numeric) {
|
function insert(value as Numeric) {
|
||||||
|
// total
|
||||||
|
_totalCount += 1;
|
||||||
|
_totalSum += value;
|
||||||
|
if (_totalMin == null || value < _totalMin) {
|
||||||
|
_totalMin = value;
|
||||||
|
}
|
||||||
|
if (_totalMax == null || value > _totalMax) {
|
||||||
|
_totalMax = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lap
|
||||||
|
_lapCount += 1;
|
||||||
|
_lapSum += value;
|
||||||
|
if (_lapMin == null || value < _lapMin) {
|
||||||
|
_lapMin = value;
|
||||||
|
}
|
||||||
|
if (_lapMax == null || value > _lapMax) {
|
||||||
|
_lapMax = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rolling
|
||||||
_values[_index] = value;
|
_values[_index] = value;
|
||||||
_index = (_index + 1) % _size;
|
_index = (_index + 1) % _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
function get() as Numeric {
|
function totalAvg() { return _totalCount == 0 ? null : _totalSum / _totalCount; }
|
||||||
|
function totalMin() { return _totalMin; }
|
||||||
|
function totalMax() { return _totalMax; }
|
||||||
|
function lapAvg() { return _lapCount == 0 ? null : _lapSum / _lapCount; }
|
||||||
|
function lapMin() { return _lapMin; }
|
||||||
|
function lapMax() { return _lapMax; }
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
_totalSum = 0.0;
|
||||||
|
_totalCount = 0;
|
||||||
|
_totalMin = null;
|
||||||
|
_totalMax = null;
|
||||||
|
lapReset();
|
||||||
|
}
|
||||||
|
|
||||||
|
function lapReset() {
|
||||||
|
_lapSum = 0.0;
|
||||||
|
_lapCount = 0;
|
||||||
|
_lapMin = null;
|
||||||
|
_lapMax = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRolling() {
|
||||||
|
if (_totalCount < _safeCount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
var sum = 0.0;
|
var sum = 0.0;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
for (var i = 0; i < _size; i++) {
|
for (var i = 0; i < _size; i++) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user