Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add settings toggles for chart series (#1297) #2054

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
});
}
}

if (PreferencesUtils.isKey(R.string.stats_rate_key, key)) {
boolean reportSpeed = PreferencesUtils.isReportSpeed(activityTypeLocalized);
if (reportSpeed != viewBinding.chartView.getReportSpeed()) {
Expand All @@ -99,6 +100,21 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
});
}
}

if (PreferencesUtils.isKey(R.string.chart_display_elevation_key, key)) {
viewBinding.chartView.setShowElevation(PreferencesUtils.shouldShowElevation());
refreshChart();
}

if (PreferencesUtils.isKey(R.string.chart_display_pace_or_speed_key, key)) {
viewBinding.chartView.setShowPaceOrSpeed(PreferencesUtils.shouldShowPaceOrSpeed());
refreshChart();
}

if (PreferencesUtils.isKey(R.string.chart_display_heart_rate_key, key)) {
viewBinding.chartView.setShowHeartRate(PreferencesUtils.shouldShowHeartRate());
refreshChart();
}
}
};

Expand Down Expand Up @@ -273,4 +289,13 @@ private void runOnUiThread(Runnable runnable) {
fragmentActivity.runOnUiThread(runnable);
}
}

private void refreshChart() {
runOnUiThread(() -> {
if (isResumed()) {
viewBinding.chartView.invalidate();
viewBinding.chartView.requestLayout();
}
});
}
}
82 changes: 63 additions & 19 deletions src/main/java/de/dennisguse/opentracks/chart/ChartView.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ public class ChartView extends View {
}

private final List<ChartValueSeries> seriesList = new LinkedList<>();
private final ChartValueSeries elevationSeries;
private final ChartValueSeries speedSeries;
private final ChartValueSeries paceSeries;
private final ChartValueSeries heartRateSeries;

private final LinkedList<ChartPoint> chartPoints = new LinkedList<>();
private final List<Marker> markers = new LinkedList<>();
Expand Down Expand Up @@ -123,6 +125,7 @@ public class ChartView extends View {
private boolean chartByDistance = false;
private UnitSystem unitSystem = UnitSystem.defaultUnitSystem();
private boolean reportSpeed = true;
private boolean showPaceOrSpeed = true;
private boolean showPointer = false;

private final GestureDetectorCompat detectorScrollFlingTab = new GestureDetectorCompat(getContext(), new GestureDetector.SimpleOnGestureListener() {
Expand Down Expand Up @@ -176,17 +179,17 @@ public ChartView(Context context, AttributeSet attributeSet) {
int fontSizeSmall = ThemeUtils.getFontSizeSmallInPx(context);
int fontSizeMedium = ThemeUtils.getFontSizeMediumInPx(context);

seriesList.add(new ChartValueSeries(context,
Integer.MIN_VALUE,
Integer.MAX_VALUE,
new int[]{5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000},
R.string.description_altitude_metric,
R.string.description_altitude_imperial,
R.string.description_altitude_imperial,
R.color.chart_altitude_fill,
R.color.chart_altitude_border,
fontSizeSmall,
fontSizeMedium) {
elevationSeries = new ChartValueSeries(context,
Integer.MIN_VALUE,
Integer.MAX_VALUE,
new int[]{5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000},
R.string.description_altitude_metric,
R.string.description_altitude_imperial,
R.string.description_altitude_imperial,
R.color.chart_altitude_fill,
R.color.chart_altitude_border,
fontSizeSmall,
fontSizeMedium) {
@Override
protected Double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
return chartPoint.altitude();
Expand All @@ -196,7 +199,8 @@ protected Double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
protected boolean drawIfChartPointHasNoData() {
return false;
}
});
};
seriesList.add(elevationSeries);

speedSeries = new ChartValueSeries(context,
0,
Expand Down Expand Up @@ -244,10 +248,15 @@ protected boolean drawIfChartPointHasNoData() {
};
seriesList.add(paceSeries);

seriesList.add(new ChartValueSeries(context,
heartRateSeries = new ChartValueSeries(context,
0,
Integer.MAX_VALUE,
new int[]{25, 50},
// For Zone 5 cardio, the 25 value should result in nice visuals, as the values
// will range from ~70 - ~180 (around 4.5 intervals).
// For Zone 1 cardio, the 15 value should result in nice visuals, as the values
// will range from ~70 - ~120 (around 3.5 intervals)
// The fallback of 50 should give appropriate visuals for values outside this range.
new int[]{15, 25, 50},
R.string.description_sensor_heart_rate,
R.string.description_sensor_heart_rate,
R.string.description_sensor_heart_rate,
Expand All @@ -264,7 +273,8 @@ protected Double extractDataFromChartPoint(@NonNull ChartPoint chartPoint) {
protected boolean drawIfChartPointHasNoData() {
return false;
}
});
};
seriesList.add(heartRateSeries);

seriesList.add(new ChartValueSeries(context,
0,
Expand Down Expand Up @@ -343,9 +353,15 @@ protected boolean drawIfChartPointHasNoData() {
setClickable(true);
updateDimensions();

// either speedSeries or paceSeries should be enabled.
speedSeries.setEnabled(reportSpeed);
paceSeries.setEnabled(!reportSpeed);
// Either speedSeries or paceSeries should be enabled, if one is shown.
if (showPaceOrSpeed) {
speedSeries.setEnabled(reportSpeed);
paceSeries.setEnabled(!reportSpeed);
}

// Defaults for our chart series.
heartRateSeries.setEnabled(true);
elevationSeries.setEnabled(true);
}

@Override
Expand Down Expand Up @@ -379,6 +395,12 @@ public void setReportSpeed(boolean value) {
}

public boolean applyReportSpeed() {
if (!showPaceOrSpeed) {
paceSeries.setEnabled(false);
speedSeries.setEnabled(false);
return true;
}

if (reportSpeed) {
if (!speedSeries.isEnabled()) {
speedSeries.setEnabled(true);
Expand All @@ -396,6 +418,20 @@ public boolean applyReportSpeed() {
return false;
}

void setShowElevation(boolean value) {
elevationSeries.setEnabled(value);
}
void setShowPaceOrSpeed(boolean value) {
showPaceOrSpeed = value;

// we want to make sure we show whatever version the user has
// selected when we turn this back on.
applyReportSpeed();
}
void setShowHeartRate(boolean value) {
heartRateSeries.setEnabled(value);
}

public void setShowPointer(boolean value) {
showPointer = value;
}
Expand Down Expand Up @@ -644,10 +680,18 @@ private record TitleDimensions(
*/
private void drawSeriesTitles(Canvas canvas) {
Iterator<TitlePosition> tpI = titleDimensions.titlePositions.iterator();

for (ChartValueSeries chartValueSeries : seriesList) {
if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(chartValueSeries)) {
String title = getContext().getString(chartValueSeries.getTitleId(unitSystem));
Paint paint = chartValueSeries.getTitlePaint();

// It is possible for the titlePositions to become empty temporarily, while switching between
// chart screens quickly.
if (!tpI.hasNext()) {
return;
}

TitlePosition tp = tpI.next();
int y = topBorder - spacer - (titleDimensions.lineCount - tp.line) * (titleDimensions.lineHeight + spacer);
canvas.drawText(title, tp.xPos + getScrollX(), y, paint);
Expand Down Expand Up @@ -774,7 +818,7 @@ private void drawYAxis(Canvas canvas) {

//TODO
int markerXPosition = x - spacer;
int index = titleDimensions.titlePositions.size() - 1; // index only onver the visible chart series
int index = titleDimensions.titlePositions.size() - 1; // index only over the visible chart series
final int lastDrawn2ndLineMarkerIndex = getYmarkerCountOn1stLine();
for (int i = seriesList.size()-1; i>=0 ;--i) { // draw markers from the last series to achieve right alignment
ChartValueSeries chartValueSeries = seriesList.get(i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,21 @@ public static boolean shouldUseFullscreen() {
return getBoolean(R.string.stats_fullscreen_while_recording_key, DEFAULT);
}

public static boolean shouldShowElevation() {
final boolean DEFAULT = resources.getBoolean(R.bool.chart_display_elevation_default);
return getBoolean(R.string.chart_display_elevation_key, DEFAULT);
}

public static boolean shouldShowPaceOrSpeed() {
final boolean DEFAULT = resources.getBoolean(R.bool.chart_display_pace_or_speed_default);
return getBoolean(R.string.chart_display_pace_or_speed_key, DEFAULT);
}

public static boolean shouldShowHeartRate() {
final boolean DEFAULT = resources.getBoolean(R.bool.chart_display_heart_rate_default);
return getBoolean(R.string.chart_display_heart_rate_key, DEFAULT);
}

public static boolean shouldUseDynamicColors() {
final boolean DEFAULT = resources.getBoolean(R.bool.settings_ui_dynamic_colors_default);
return getBoolean(R.string.settings_ui_dynamic_colors_key, DEFAULT);
Expand Down
31 changes: 23 additions & 8 deletions src/main/res/values/settings.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Do not translate anything in this file directly. -->
<string name="stats_show_on_lockscreen_while_recording_key" translatable="false">trackdetail_show_on_lockscreen_while_recording</string>
<bool name="stats_show_on_lockscreen_while_recording_default" translatable="false">false</bool>

<string name="stats_keep_screen_on_while_recording_key" translatable="false">trackdetail_keep_screen_on_while_recording</string>
<bool name="stats_keep_screen_on_while_recording_default" translatable="false">false</bool>

<string name="stats_fullscreen_while_recording_key" translatable="false">trackdetail_fullscreen_while_recording</string>
<bool name="stats_fullscreen_while_recording_default" translatable="false">false</bool>

<!-- Main settings -->
<string name="settings_defaults_key" translatable="false">settingsDefaults</string>
Expand Down Expand Up @@ -279,9 +271,32 @@
<string name="show_introduction_screen_key" translatable="false">showIntroduction</string>
<bool name="show_introduction_screen_default">true</bool>

<!-- User Interface Settings -->

<string name="settings_ui_dynamic_colors_key" translatable="false">uiDynamicColors</string>
<bool name="settings_ui_dynamic_colors_default" translatable="false">false</bool>

<!-- Recording Settings -->
<string name="stats_show_on_lockscreen_while_recording_key" translatable="false">trackdetail_show_on_lockscreen_while_recording</string>
<bool name="stats_show_on_lockscreen_while_recording_default" translatable="false">false</bool>

<string name="stats_keep_screen_on_while_recording_key" translatable="false">trackdetail_keep_screen_on_while_recording</string>
<bool name="stats_keep_screen_on_while_recording_default" translatable="false">false</bool>

<string name="stats_fullscreen_while_recording_key" translatable="false">trackdetail_fullscreen_while_recording</string>
<bool name="stats_fullscreen_while_recording_default" translatable="false">false</bool>

<!-- Chart Settings -->
<string name="chart_display_elevation_key" translatable="false">chart_display_elevation</string>
<bool name="chart_display_elevation_default" translatable="false">true</bool>

<string name="chart_display_pace_or_speed_key" translatable="false">chart_display_pace_or_speed</string>
<bool name="chart_display_pace_or_speed_default" translatable="false">true</bool>

<string name="chart_display_heart_rate_key" translatable="false">chart_display_heart_rate</string>
<bool name="chart_display_heart_rate_default" translatable="false">true</bool>


<!-- androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode() -->
<string name="locale_key" translatable="false">localeKey</string>

Expand Down
5 changes: 5 additions & 0 deletions src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ limitations under the License.
<!-- Settings Chart -->
<string name="settings_chart_by_distance">By distance</string>
<string name="settings_chart_by_time">By time</string>
<string name="settings_charts_title">Charts</string>
<string name="settings_chart_display_elevation_title">Display elevation</string>
<string name="settings_chart_display_pace_or_speed_title">Display pace or speed</string>
<string name="settings_chart_display_heart_rate_title">Display heart rate</string>

<!-- Settings Recording -->
<string name="settings_recording_title">Recording</string>
<string name="settings_theme_switch_restart">Theme changes may require a manual restart.</string>
Expand Down
19 changes: 19 additions & 0 deletions src/main/res/xml/settings_user_interface.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,23 @@
android:title="@string/settings_recording_fullscreen_on_while_recording_title" />
</PreferenceCategory>

<PreferenceCategory app:title="@string/settings_charts_title">
<SwitchPreferenceCompat
android:icon="@drawable/ic_activity_climbing_24dp"
android:defaultValue="@bool/chart_display_elevation_default"
android:key="@string/chart_display_elevation_key"
android:title="@string/settings_chart_display_elevation_title" />

<SwitchPreferenceCompat
android:icon="@drawable/ic_activity_snowboarding_24dp"
android:defaultValue="@bool/chart_display_pace_or_speed_default"
android:key="@string/chart_display_pace_or_speed_key"
android:title="@string/settings_chart_display_pace_or_speed_title" />

<SwitchPreferenceCompat
android:icon="@drawable/ic_activity_workout_24dp"
android:defaultValue="@bool/chart_display_heart_rate_default"
android:key="@string/chart_display_heart_rate_key"
android:title="@string/settings_chart_display_heart_rate_title" />
</PreferenceCategory>
</PreferenceScreen>
Loading