mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Workout details: disable elevation chart if all points are zero
This commit is contained in:
+124
-55
@@ -10,6 +10,8 @@ import static nodomain.freeyourgadget.gadgetbridge.model.ActivitySummaryEntries.
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.github.mikephil.charting.charts.ScatterChart;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
@@ -47,21 +49,34 @@ public class DefaultWorkoutCharts {
|
||||
final List<Entry> elevationDataPoints = new ArrayList<>();
|
||||
boolean hasSpeedValues = false;
|
||||
boolean hasCadenceValues = false;
|
||||
boolean hasElevationValues = false;
|
||||
final Accumulator cadenceAccumulator = new Accumulator();
|
||||
|
||||
for (int i = 0; i <= activityPoints.size() - 1; i++) {
|
||||
final ActivityPoint point = activityPoints.get(i);
|
||||
final long tsShorten = tsTranslation.shorten((int) point.getTime().getTime());
|
||||
|
||||
// HR
|
||||
if (point.getHeartRate() > 0) {
|
||||
heartRateDataPoints.add(new Entry(tsShorten, point.getHeartRate()));
|
||||
}
|
||||
|
||||
// Elevation
|
||||
if (point.getLocation() != null && point.getLocation().getAltitude() != GPSCoordinate.UNKNOWN_ALTITUDE) {
|
||||
elevationDataPoints.add(new Entry(tsShorten, (float) point.getLocation().getAltitude()));
|
||||
if (point.getLocation().getAltitude() != 0) {
|
||||
// Some devices provide all points at zero
|
||||
hasElevationValues = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Speed
|
||||
speedDataPoints.add(new Entry(tsShorten, point.getSpeed()));
|
||||
if (!hasSpeedValues && point.getSpeed() > 0) {
|
||||
hasSpeedValues = true;
|
||||
}
|
||||
|
||||
// Cadence
|
||||
cadenceDataPoints.add(new Entry(tsShorten, point.getCadence()));
|
||||
if (!hasCadenceValues && point.getCadence() > 0) {
|
||||
cadenceAccumulator.add(point.getCadence());
|
||||
@@ -70,68 +85,122 @@ public class DefaultWorkoutCharts {
|
||||
}
|
||||
|
||||
if (!heartRateDataPoints.isEmpty()) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.heart_rate), getUnitString(context, UNIT_BPM));
|
||||
final LineDataSet dataset = createLineDataSet(context, heartRateDataPoints, label, context.getResources().getColor(R.color.chart_line_heart_rate));
|
||||
ValueFormatter integerFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
charts.add(new WorkoutChart("heart_rate", context.getString(R.string.heart_rate), ActivitySummaryEntries.GROUP_HEART_RATE, new LineData(dataset), integerFormatter, getUnitString(context, UNIT_BPM)));
|
||||
charts.add(createHeartRateChart(context, heartRateDataPoints));
|
||||
}
|
||||
|
||||
if (hasSpeedValues && !speedDataPoints.isEmpty()) {
|
||||
if (ActivityKind.isPaceActivity(activityKind)) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Pace), getUnitString(context, UNIT_MINUTES_PER_KM));
|
||||
final LineDataSet dataset = createLineDataSet(context, speedDataPoints, label, context.getResources().getColor(R.color.chart_line_speed));
|
||||
charts.add(new WorkoutChart("pace", context.getString(R.string.Pace), ActivitySummaryEntries.GROUP_SPEED, new LineData(dataset), new SpeedYLabelFormatter(UNIT_SECONDS_PER_KM), getUnitString(context, UNIT_MINUTES_PER_KM)));
|
||||
} else {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Speed), getUnitString(context, UNIT_KMPH));
|
||||
final LineDataSet dataset = createLineDataSet(context, speedDataPoints, label, context.getResources().getColor(R.color.chart_line_speed));
|
||||
charts.add(new WorkoutChart("speed", context.getString(R.string.Speed), ActivitySummaryEntries.GROUP_SPEED, new LineData(dataset), new SpeedYLabelFormatter(UNIT_METERS_PER_SECOND), getUnitString(context, UNIT_KMPH)));
|
||||
}
|
||||
charts.add(createSpeedChart(context, activityKind, speedDataPoints));
|
||||
}
|
||||
|
||||
if (hasCadenceValues && !cadenceDataPoints.isEmpty()) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.workout_cadence), getUnitString(context, getCadenceUnit(cycleUnit)));
|
||||
final ScatterDataSet dataset = createScatterDataSet(context, cadenceDataPoints, label, context.getResources().getColor(R.color.chart_cadence_circle));
|
||||
final ValueFormatter integerFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
float xAxisMaximum = Math.max((float) (cadenceAccumulator.getMax() + 30), (float) cadenceAccumulator.getAverage() * 2);
|
||||
charts.add(new WorkoutChart(
|
||||
"cadence",
|
||||
context.getString(R.string.workout_cadence),
|
||||
ActivitySummaryEntries.GROUP_CADENCE,
|
||||
new ScatterData(dataset),
|
||||
integerFormatter,
|
||||
getUnitString(context, UNIT_SPM),
|
||||
lineChart -> {
|
||||
YAxis yAxisLeft = lineChart.getAxisLeft();
|
||||
yAxisLeft.setAxisMinimum(0);
|
||||
yAxisLeft.setAxisMaximum(xAxisMaximum);
|
||||
YAxis yAxisRight = lineChart.getAxisRight();
|
||||
yAxisRight.setAxisMinimum(0);
|
||||
yAxisRight.setAxisMaximum(xAxisMaximum);
|
||||
return kotlin.Unit.INSTANCE;
|
||||
}
|
||||
)
|
||||
);
|
||||
charts.add(createCadenceChart(context, cycleUnit, cadenceDataPoints, cadenceAccumulator));
|
||||
}
|
||||
|
||||
if (!elevationDataPoints.isEmpty()) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Elevation), getUnitString(context, UNIT_METERS));
|
||||
LineDataSet dataset = createLineDataSet(context, elevationDataPoints, label, context.getResources().getColor(R.color.chart_line_elevation));
|
||||
charts.add(new WorkoutChart("elevation", context.getString(R.string.Elevation), ActivitySummaryEntries.GROUP_ELEVATION, new LineData(dataset), null, getUnitString(context, UNIT_METERS)));
|
||||
if (hasElevationValues && !elevationDataPoints.isEmpty()) {
|
||||
charts.add(createElevationChart(context, elevationDataPoints));
|
||||
}
|
||||
|
||||
return charts;
|
||||
}
|
||||
|
||||
private static WorkoutChart createElevationChart(final Context context,
|
||||
final List<Entry> elevationDataPoints) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Elevation), getUnitString(context, UNIT_METERS));
|
||||
final LineDataSet dataset = createLineDataSet(context, elevationDataPoints, label, ContextCompat.getColor(context, R.color.chart_line_elevation));
|
||||
return new WorkoutChart(
|
||||
"elevation",
|
||||
context.getString(R.string.Elevation),
|
||||
ActivitySummaryEntries.GROUP_ELEVATION,
|
||||
new LineData(dataset),
|
||||
null,
|
||||
getUnitString(context, UNIT_METERS)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createHeartRateChart(final Context context,
|
||||
final List<Entry> heartRateDataPoints) {
|
||||
final String label = String.format("%s(%s)", context.getString(R.string.heart_rate), getUnitString(context, UNIT_BPM));
|
||||
final LineDataSet dataset = createLineDataSet(context, heartRateDataPoints, label, ContextCompat.getColor(context, R.color.chart_line_heart_rate));
|
||||
final ValueFormatter integerFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
return new WorkoutChart(
|
||||
"heart_rate",
|
||||
context.getString(R.string.heart_rate),
|
||||
ActivitySummaryEntries.GROUP_HEART_RATE,
|
||||
new LineData(dataset),
|
||||
integerFormatter,
|
||||
getUnitString(context, UNIT_BPM)
|
||||
);
|
||||
}
|
||||
|
||||
private static WorkoutChart createSpeedChart(final Context context,
|
||||
final ActivityKind activityKind,
|
||||
final List<Entry> speedDataPoints) {
|
||||
if (ActivityKind.isPaceActivity(activityKind)) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Pace), getUnitString(context, UNIT_MINUTES_PER_KM));
|
||||
final LineDataSet dataset = createLineDataSet(context, speedDataPoints, label, ContextCompat.getColor(context, R.color.chart_line_speed));
|
||||
return new WorkoutChart(
|
||||
"pace",
|
||||
context.getString(R.string.Pace),
|
||||
ActivitySummaryEntries.GROUP_SPEED,
|
||||
new LineData(dataset),
|
||||
new SpeedYLabelFormatter(UNIT_SECONDS_PER_KM),
|
||||
getUnitString(context, UNIT_MINUTES_PER_KM)
|
||||
);
|
||||
} else {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.Speed), getUnitString(context, UNIT_KMPH));
|
||||
final LineDataSet dataset = createLineDataSet(context, speedDataPoints, label, ContextCompat.getColor(context, R.color.chart_line_speed));
|
||||
return new WorkoutChart(
|
||||
"speed",
|
||||
context.getString(R.string.Speed),
|
||||
ActivitySummaryEntries.GROUP_SPEED,
|
||||
new LineData(dataset),
|
||||
new SpeedYLabelFormatter(UNIT_METERS_PER_SECOND),
|
||||
getUnitString(context, UNIT_KMPH)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static WorkoutChart createCadenceChart(final Context context,
|
||||
final ActivityKind.CycleUnit cycleUnit,
|
||||
final List<Entry> cadenceDataPoints,
|
||||
final Accumulator cadenceAccumulator) {
|
||||
final String label = String.format("%s (%s)", context.getString(R.string.workout_cadence), getUnitString(context, getCadenceUnit(cycleUnit)));
|
||||
final ScatterDataSet dataset = createScatterDataSet(context, cadenceDataPoints, label, ContextCompat.getColor(context, R.color.chart_cadence_circle));
|
||||
final ValueFormatter integerFormatter = new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.valueOf((int) value);
|
||||
}
|
||||
};
|
||||
float xAxisMaximum = Math.max(
|
||||
(float) (cadenceAccumulator.getMax() + 30),
|
||||
(float) cadenceAccumulator.getAverage() * 2
|
||||
);
|
||||
|
||||
return new WorkoutChart(
|
||||
"cadence",
|
||||
context.getString(R.string.workout_cadence),
|
||||
ActivitySummaryEntries.GROUP_CADENCE,
|
||||
new ScatterData(dataset),
|
||||
integerFormatter,
|
||||
getUnitString(context, UNIT_SPM),
|
||||
lineChart -> {
|
||||
YAxis yAxisLeft = lineChart.getAxisLeft();
|
||||
yAxisLeft.setAxisMinimum(0);
|
||||
yAxisLeft.setAxisMaximum(xAxisMaximum);
|
||||
YAxis yAxisRight = lineChart.getAxisRight();
|
||||
yAxisRight.setAxisMinimum(0);
|
||||
yAxisRight.setAxisMaximum(xAxisMaximum);
|
||||
return kotlin.Unit.INSTANCE;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public static String getUnitString(final Context context, final String unit) {
|
||||
final int resId = context.getResources().getIdentifier(unit, "string", context.getPackageName());
|
||||
if (resId != 0) {
|
||||
@@ -141,9 +210,9 @@ public class DefaultWorkoutCharts {
|
||||
}
|
||||
|
||||
public static LineDataSet createLineDataSet(final Context context,
|
||||
final List<Entry> entities,
|
||||
final String label,
|
||||
final int color) {
|
||||
final List<Entry> entities,
|
||||
final String label,
|
||||
final int color) {
|
||||
final LineDataSet dataSet = new LineDataSet(entities, label);
|
||||
dataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
|
||||
dataSet.setCubicIntensity(0.05f);
|
||||
@@ -159,9 +228,9 @@ public class DefaultWorkoutCharts {
|
||||
}
|
||||
|
||||
public static ScatterDataSet createScatterDataSet(final Context context,
|
||||
final List<Entry> entities,
|
||||
final String label,
|
||||
final int color) {
|
||||
final List<Entry> entities,
|
||||
final String label,
|
||||
final int color) {
|
||||
final ScatterDataSet dataSet = new ScatterDataSet(entities, label);
|
||||
dataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);
|
||||
dataSet.setColor(color);
|
||||
|
||||
Reference in New Issue
Block a user