Workout details: fix heart rate chart, data categorization, labels

This commit is contained in:
a0z
2025-08-18 00:01:00 +01:00
committed by José Rebelo
parent 95276cb96a
commit 89281fdd6b
6 changed files with 49 additions and 30 deletions
@@ -453,6 +453,7 @@ class WorkoutDetailsFragment : Fragment(), MenuProvider {
isEnabled = false
}
lineChart.data = chart.chartData as LineData?
lineChart.description.isEnabled = false;
lineChart.invalidate()
chartsFragmentHolder.addView(lineChart)
@@ -2,9 +2,11 @@ package nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import nodomain.freeyourgadget.gadgetbridge.activities.workouts.WorkoutValueFormatter;
public abstract class ActivitySummaryEntry {
public abstract class ActivitySummaryEntry implements Cloneable {
private String group;
protected int columnSpan;
@@ -32,4 +34,14 @@ public abstract class ActivitySummaryEntry {
public abstract void populate(final String key,
final LinearLayout linearLayout,
final WorkoutValueFormatter workoutValueFormatter);
@NonNull
@Override
public ActivitySummaryEntry clone() {
try {
return (ActivitySummaryEntry) super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
@@ -14,15 +14,17 @@ object ActivitySummaryGroup {
activitySummaryData.keys
.filterNot { it.startsWith("internal") }
.forEach { key ->
val item = activitySummaryData[key]
var item = activitySummaryData[key]
// Use the group if specified in the entry, otherwise fallback to the default mapping from getDefaultGroup
val groups: List<String> = item.group?.let { listOf(it) } ?: getDefaultGroups(key)
for (groupName in groups) {
for ((index, groupName) in groups.withIndex()) {
if (index > 0) {
item = item.clone();
}
if (groupName == ActivitySummaryEntries.GROUP_OTHER) {
item.columnSpan = 2;
}
// If the group is not defined the default groups, it will be added to the end
val group = activeGroups.getOrPut(groupName) { mutableListOf() }
group.add(Pair.of<String, ActivitySummaryEntry>(key, item))
@@ -54,7 +56,7 @@ object ActivitySummaryGroup {
ActivitySummaryEntries.GROUP_ACTIVITY, listOf<String>(
ActivitySummaryEntries.ACTIVE_SECONDS,
ActivitySummaryEntries.DISTANCE_METERS,
ActivitySummaryEntries.CALORIES_BURNT,
ActivitySummaryEntries.CALORIES_ACTIVE,
ActivitySummaryEntries.HR_AVG,
ActivitySummaryEntries.STEPS,
ActivitySummaryEntries.STRIDE_TOTAL,
@@ -109,11 +111,6 @@ object ActivitySummaryGroup {
ActivitySummaryEntries.PACE_MIN,
ActivitySummaryEntries.PACE_MAX,
"averageSpeed2",
ActivitySummaryEntries.CADENCE_AVG,
ActivitySummaryEntries.CADENCE_MAX,
ActivitySummaryEntries.CADENCE_MIN,
ActivitySummaryEntries.STEP_RATE_AVG,
ActivitySummaryEntries.STEP_RATE_MAX,
)
)
@@ -280,12 +277,18 @@ object ActivitySummaryGroup {
ActivitySummaryEntries.RESPIRATION_MIN,
ActivitySummaryEntries.RESPIRATION_MAX,
ActivitySummaryEntries.ESTIMATED_SWEAT_LOSS,
ActivitySummaryEntries.CALORIES_BURNT,
ActivitySummaryEntries.CALORIES_ACTIVE,
ActivitySummaryEntries.CALORIES_RESTING,
ActivitySummaryEntries.STRIDE_AVG,
ActivitySummaryEntries.STRIDE_MAX,
ActivitySummaryEntries.STRIDE_MIN,
ActivitySummaryEntries.STEP_LENGTH_AVG,
ActivitySummaryEntries.CADENCE_AVG,
ActivitySummaryEntries.CADENCE_MAX,
ActivitySummaryEntries.CADENCE_MIN,
ActivitySummaryEntries.STEP_RATE_AVG,
ActivitySummaryEntries.STEP_RATE_MAX,
)
)
}
@@ -121,6 +121,7 @@ import java.util.Optional;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.activities.HeartRateUtils;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.SpeedYLabelFormatter;
import nodomain.freeyourgadget.gadgetbridge.activities.charts.TimestampTranslation;
import nodomain.freeyourgadget.gadgetbridge.activities.workouts.entries.ActivitySummaryProgressEntry;
@@ -217,14 +218,6 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
handleRecord(record);
}
if (sport != null) {
if (StringUtils.isNullOrEmpty(summary.getName())) {
summary.setName(sport.getName());
}
activityKind = getActivityKind(sport.getSport(), sport.getSubSport());
} else {
activityKind = getActivityKind(session.getSport(), session.getSubSport());
}
final ActivitySummaryData activitySummaryData = updateSummary(summary);
final List<WorkoutChart> charts = new LinkedList<>();
@@ -235,14 +228,16 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
boolean hasSpeedValues = false;
for (int i=0; i<=activityPoints.size()-1; i++) {
ActivityPoint point = activityPoints.get(i);
long time = tsTranslation.shorten((int) point.getTime().getTime());
heartRateDataPoints.add(new Entry(time, point.getHeartRate()));
speedDataPoints.add(new Entry(time, point.getSpeed()));
if (!hasSpeedValues && point.getSpeed() > 0) {
hasSpeedValues = true;
long tsShorten = tsTranslation.shorten((int) point.getTime().getTime());
if (point.getHeartRate() > 0) {
heartRateDataPoints.add(new Entry(tsShorten, point.getHeartRate()));
}
if (point.getLocation() != null) {
elevationDataPoints.add(new Entry(time, (float) point.getLocation().getAltitude()));
elevationDataPoints.add(new Entry(tsShorten, (float) point.getLocation().getAltitude()));
}
speedDataPoints.add(new Entry(tsShorten, point.getSpeed()));
if (!hasSpeedValues && point.getSpeed() > 0) {
hasSpeedValues = true;
}
}
if (!heartRateDataPoints.isEmpty()) {
@@ -378,6 +373,14 @@ public class GarminWorkoutParser implements ActivitySummaryParser {
return summaryData;
}
if (sport != null) {
if (StringUtils.isNullOrEmpty(summary.getName())) {
summary.setName(sport.getName());
}
activityKind = getActivityKind(sport.getSport(), sport.getSubSport());
} else {
activityKind = getActivityKind(session.getSport(), session.getSubSport());
}
final ActivityKind.CycleUnit cycleUnit = ActivityKind.getCycleUnit(activityKind);
final String weightUnit;
+2 -2
View File
@@ -1289,7 +1289,7 @@
<string name="seconds_km">sec/km</string>
<string name="averageStrokeDistance">Average Stroke Distance</string>
<string name="averageHR">Heartrate</string>
<string name="averageKMPaceSeconds">Pace</string>
<string name="averageKMPaceSeconds">Avg Pace</string>
<string name="totalStride">Total stride</string>
<string name="activeSeconds">Active</string>
<string name="caloriesBurnt">Calories</string>
@@ -1390,7 +1390,7 @@
<string name="reminder_no_free_slots_description">The device has no free slots for reminders (total slots: %1$s)</string>
<string name="prefs_reserve_reminder_calendar_summary">Number of calendar events that will be synchronized</string>
<string name="mi2_prefs_do_not_disturb_lift_wrist">Activate display upon lift during Do Not Disturb</string>
<string name="maxHR">Max Heartrate</string>
<string name="maxHR">Max Heart Rate</string>
<string name="spm">steps/min</string>
<string name="minSpeed">Minimum</string>
<string name="averageCadence">Average Cadence</string>
+4 -4
View File
@@ -2534,10 +2534,10 @@
<string name="minPace">Slowest Pace</string>
<string name="maxPace">Fastest Pace</string>
<string name="totalStride">Total stride</string>
<string name="averageHR">Heartrate</string>
<string name="maxHR">Max Heartrate</string>
<string name="minHR">Min Heartrate</string>
<string name="averageKMPaceSeconds">Pace</string>
<string name="averageHR">Avg Heart Rate</string>
<string name="maxHR">Max Heart Rate</string>
<string name="minHR">Min Heart Rate</string>
<string name="averageKMPaceSeconds">Avg Pace</string>
<string name="HeartRateZones">Heart Rate Zones</string>
<string name="hrZoneNa">N/A</string>
<string name="hrZoneWarmUp">Warm-Up</string>