mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-08 19:27:04 +01:00
Add daily steps progress chart
This commit is contained in:
parent
f487bc7876
commit
8e3f010629
@ -2,6 +2,7 @@ package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@ -16,21 +17,36 @@ import androidx.annotation.ColorInt;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.LegendEntry;
|
||||
import com.github.mikephil.charting.components.LimitLine;
|
||||
import com.github.mikephil.charting.components.XAxis;
|
||||
import com.github.mikephil.charting.components.YAxis;
|
||||
import com.github.mikephil.charting.data.Entry;
|
||||
import com.github.mikephil.charting.data.LineData;
|
||||
import com.github.mikephil.charting.data.LineDataSet;
|
||||
import com.github.mikephil.charting.formatter.ValueFormatter;
|
||||
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
|
||||
public class StepsDailyFragment extends StepsFragment {
|
||||
public class StepsDailyFragment extends StepsFragment<StepsDailyFragment.StepsData> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(BodyEnergyFragment.class);
|
||||
|
||||
private TextView mDateView;
|
||||
@ -38,10 +54,9 @@ public class StepsDailyFragment extends StepsFragment {
|
||||
private TextView steps;
|
||||
private TextView distance;
|
||||
ImageView stepsStreaksButton;
|
||||
private LineChart stepsChart;
|
||||
|
||||
protected int STEPS_GOAL;
|
||||
protected int TOTAL_DAYS = 1;
|
||||
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
@ -62,6 +77,9 @@ public class StepsDailyFragment extends StepsFragment {
|
||||
stepsGauge = rootView.findViewById(R.id.steps_gauge);
|
||||
steps = rootView.findViewById(R.id.steps_count);
|
||||
distance = rootView.findViewById(R.id.steps_distance);
|
||||
stepsChart = rootView.findViewById(R.id.steps_daily_chart);
|
||||
setupStepsChart();
|
||||
|
||||
STEPS_GOAL = GBApplication.getPrefs().getInt(ActivityUser.PREF_USER_STEPS_GOAL, ActivityUser.defaultUserStepsGoal);
|
||||
refresh();
|
||||
|
||||
@ -89,8 +107,16 @@ public class StepsDailyFragment extends StepsFragment {
|
||||
day.setTime(chartsHost.getEndDate());
|
||||
String formattedDate = new SimpleDateFormat("E, MMM dd").format(chartsHost.getEndDate());
|
||||
mDateView.setText(formattedDate);
|
||||
List<StepsDay> stepsDaysData = getMyStepsDaysData(db, day, device);
|
||||
return new StepsDailyFragment.StepsData(stepsDaysData);
|
||||
List<StepsDay> stepsDayList = getMyStepsDaysData(db, day, device);
|
||||
final StepsDay stepsDay;
|
||||
if (stepsDayList.isEmpty()) {
|
||||
LOG.error("Failed to get StepsDay for {}", day);
|
||||
stepsDay = new StepsDay(day, 0, 0);
|
||||
} else {
|
||||
stepsDay = stepsDayList.get(0);
|
||||
}
|
||||
List<? extends ActivitySample> samplesOfDay = getSamplesOfDay(db, day, 0, device);
|
||||
return new StepsDailyFragment.StepsData(stepsDay, samplesOfDay);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -111,13 +137,101 @@ public class StepsDailyFragment extends StepsFragment {
|
||||
|
||||
steps.setText(String.format(String.valueOf(stepsData.todayStepsDay.steps)));
|
||||
distance.setText(getString(R.string.steps_distance_unit, stepsData.todayStepsDay.distance));
|
||||
|
||||
// Chart
|
||||
final List<LegendEntry> legendEntries = new ArrayList<>(1);
|
||||
final LegendEntry stepsEntry = new LegendEntry();
|
||||
stepsEntry.label = getString(R.string.steps);
|
||||
stepsEntry.formColor = getResources().getColor(R.color.steps_color);
|
||||
legendEntries.add(stepsEntry);
|
||||
final LegendEntry goalEntry = new LegendEntry();
|
||||
goalEntry.label = getString(R.string.miband_prefs_fitness_goal);
|
||||
goalEntry.formColor = Color.GRAY;
|
||||
legendEntries.add(goalEntry);
|
||||
stepsChart.getLegend().setTextColor(TEXT_COLOR);
|
||||
stepsChart.getLegend().setCustom(legendEntries);
|
||||
|
||||
final List<Entry> lineEntries = new ArrayList<>();
|
||||
final TimestampTranslation tsTranslation = new TimestampTranslation();
|
||||
int sum = 0;
|
||||
for (final ActivitySample sample : stepsData.samples) {
|
||||
if (sample.getSteps() > 0) {
|
||||
sum += sample.getSteps();
|
||||
}
|
||||
lineEntries.add(new Entry(tsTranslation.shorten(sample.getTimestamp()), sum));
|
||||
}
|
||||
|
||||
stepsChart.getXAxis().setValueFormatter(new SampleXLabelFormatter(tsTranslation));
|
||||
|
||||
if (sum < STEPS_GOAL) {
|
||||
stepsChart.getAxisLeft().setAxisMaximum(STEPS_GOAL);
|
||||
} else {
|
||||
stepsChart.getAxisLeft().resetAxisMaximum();
|
||||
}
|
||||
|
||||
final LineDataSet lineDataSet = new LineDataSet(lineEntries, getString(R.string.steps));
|
||||
lineDataSet.setColor(getResources().getColor(R.color.steps_color));
|
||||
lineDataSet.setDrawCircles(false);
|
||||
lineDataSet.setLineWidth(2f);
|
||||
lineDataSet.setFillAlpha(255);
|
||||
lineDataSet.setDrawCircles(false);
|
||||
lineDataSet.setCircleColor(getResources().getColor(R.color.steps_color));
|
||||
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
lineDataSet.setDrawValues(false);
|
||||
lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
|
||||
lineDataSet.setDrawFilled(true);
|
||||
lineDataSet.setFillAlpha(60);
|
||||
lineDataSet.setFillColor(getResources().getColor(R.color.steps_color ));
|
||||
|
||||
final LimitLine goalLine = new LimitLine(STEPS_GOAL);
|
||||
goalLine.setLineColor(Color.GRAY);
|
||||
goalLine.setLineWidth(1.5f);
|
||||
goalLine.enableDashedLine(10f, 10f, 0f);
|
||||
stepsChart.getAxisLeft().removeAllLimitLines();
|
||||
stepsChart.getAxisLeft().addLimitLine(goalLine);
|
||||
|
||||
final List<ILineDataSet> lineDataSets = new ArrayList<>();
|
||||
lineDataSets.add(lineDataSet);
|
||||
final LineData lineData = new LineData(lineDataSets);
|
||||
stepsChart.setData(lineData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderCharts() {}
|
||||
protected void renderCharts() {
|
||||
stepsChart.invalidate();
|
||||
}
|
||||
|
||||
protected void setupLegend(Chart<?> chart) {}
|
||||
|
||||
private void setupStepsChart() {
|
||||
stepsChart.getDescription().setEnabled(false);
|
||||
stepsChart.setDoubleTapToZoomEnabled(false);
|
||||
|
||||
final XAxis xAxisBottom = stepsChart.getXAxis();
|
||||
xAxisBottom.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
xAxisBottom.setDrawLabels(true);
|
||||
xAxisBottom.setDrawGridLines(false);
|
||||
xAxisBottom.setEnabled(true);
|
||||
xAxisBottom.setDrawLimitLinesBehindData(true);
|
||||
xAxisBottom.setTextColor(CHART_TEXT_COLOR);
|
||||
xAxisBottom.setAxisMinimum(0f);
|
||||
xAxisBottom.setAxisMaximum(86400f);
|
||||
//xAxisBottom.setLabelCount(7, true);
|
||||
|
||||
final YAxis yAxisLeft = stepsChart.getAxisLeft();
|
||||
yAxisLeft.setDrawGridLines(true);
|
||||
yAxisLeft.setAxisMinimum(0);
|
||||
yAxisLeft.setDrawTopYLabelEntry(true);
|
||||
yAxisLeft.setEnabled(true);
|
||||
yAxisLeft.setTextColor(CHART_TEXT_COLOR);
|
||||
|
||||
final YAxis yAxisRight = stepsChart.getAxisRight();
|
||||
yAxisRight.setEnabled(true);
|
||||
yAxisRight.setDrawLabels(false);
|
||||
yAxisRight.setDrawGridLines(false);
|
||||
yAxisRight.setDrawAxisLine(true);
|
||||
}
|
||||
|
||||
Bitmap drawGauge(int width, int barWidth, @ColorInt int filledColor, int value, int maxValue) {
|
||||
int height = width;
|
||||
int barMargin = (int) Math.ceil(barWidth / 2f);
|
||||
@ -170,4 +284,14 @@ public class StepsDailyFragment extends StepsFragment {
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
protected static class StepsData extends ChartsData {
|
||||
StepsDay todayStepsDay;
|
||||
List<? extends ActivitySample> samples;
|
||||
|
||||
public StepsData(final StepsDay todayStepsDay, final List<? extends ActivitySample> samplesOfDay) {
|
||||
this.todayStepsDay = todayStepsDay;
|
||||
this.samples = samplesOfDay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -21,7 +20,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
|
||||
abstract class StepsFragment extends AbstractChartFragment<StepsDailyFragment.StepsData> {
|
||||
abstract class StepsFragment<T extends ChartsData> extends AbstractChartFragment<T> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(StepsDailyFragment.class);
|
||||
|
||||
protected int CHART_TEXT_COLOR;
|
||||
@ -93,7 +92,7 @@ abstract class StepsFragment extends AbstractChartFragment<StepsDailyFragment.St
|
||||
return amounts;
|
||||
}
|
||||
|
||||
private List<? extends ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) {
|
||||
protected List<? extends ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) {
|
||||
int startTs;
|
||||
int endTs;
|
||||
|
||||
@ -126,28 +125,5 @@ abstract class StepsFragment extends AbstractChartFragment<StepsDailyFragment.St
|
||||
}
|
||||
}
|
||||
|
||||
protected static class StepsData extends ChartsData {
|
||||
List<StepsDay> days;
|
||||
long stepsDailyAvg = 0;
|
||||
double distanceDailyAvg = 0;
|
||||
long totalSteps = 0;
|
||||
double totalDistance = 0;
|
||||
StepsDay todayStepsDay;
|
||||
protected StepsData(List<StepsDay> days) {
|
||||
this.days = days;
|
||||
int daysCounter = 0;
|
||||
for(StepsDay day : days) {
|
||||
this.totalSteps += day.steps;
|
||||
this.totalDistance += day.distance;
|
||||
if (day.steps > 0) {
|
||||
daysCounter++;
|
||||
}
|
||||
}
|
||||
if (daysCounter > 0) {
|
||||
this.stepsDailyAvg = this.totalSteps / daysCounter;
|
||||
this.distanceDailyAvg = this.totalDistance / daysCounter;
|
||||
}
|
||||
this.todayStepsDay = days.get(days.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,9 +34,8 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.wena3.protocol.packets.settings.DayStartHourSetting;
|
||||
|
||||
public class StepsPeriodFragment extends StepsFragment {
|
||||
public class StepsPeriodFragment extends StepsFragment<StepsPeriodFragment.StepsData> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(BodyEnergyFragment.class);
|
||||
|
||||
private TextView mDateView;
|
||||
@ -113,7 +112,9 @@ public class StepsPeriodFragment extends StepsFragment {
|
||||
yAxisLeft.setEnabled(true);
|
||||
yAxisLeft.setTextColor(CHART_TEXT_COLOR);
|
||||
yAxisLeft.setAxisMinimum(0f);
|
||||
LimitLine target = new LimitLine(STEPS_GOAL);
|
||||
final LimitLine target = new LimitLine(STEPS_GOAL);
|
||||
target.setLineColor(Color.GRAY);
|
||||
target.enableDashedLine(10f, 10f, 0f);
|
||||
yAxisLeft.addLimitLine(target);
|
||||
|
||||
final YAxis yAxisRight = stepsChart.getAxisRight();
|
||||
@ -138,7 +139,7 @@ public class StepsPeriodFragment extends StepsFragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StepsFragment.StepsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
||||
protected StepsData refreshInBackground(ChartsHost chartsHost, DBHandler db, GBDevice device) {
|
||||
Calendar day = Calendar.getInstance();
|
||||
Date to = new Date((long) this.getTSEnd() * 1000);
|
||||
Date from = DateUtils.addDays(to,-(TOTAL_DAYS - 1));
|
||||
@ -147,11 +148,11 @@ public class StepsPeriodFragment extends StepsFragment {
|
||||
mDateView.setText(fromFormattedDate + " - " + toFormattedDate);
|
||||
day.setTime(to);
|
||||
List<StepsDay> stepsDaysData = getMyStepsDaysData(db, day, device);
|
||||
return new StepsFragment.StepsData(stepsDaysData);
|
||||
return new StepsData(stepsDaysData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateChartsnUIThread(StepsPeriodFragment.StepsData stepsData) {
|
||||
protected void updateChartsnUIThread(StepsData stepsData) {
|
||||
stepsChart.setData(null);
|
||||
|
||||
List<BarEntry> entries = new ArrayList<>();
|
||||
@ -197,4 +198,29 @@ public class StepsPeriodFragment extends StepsFragment {
|
||||
}
|
||||
|
||||
protected void setupLegend(Chart<?> chart) {}
|
||||
|
||||
protected static class StepsData extends ChartsData {
|
||||
List<StepsDay> days;
|
||||
long stepsDailyAvg = 0;
|
||||
double distanceDailyAvg = 0;
|
||||
long totalSteps = 0;
|
||||
double totalDistance = 0;
|
||||
StepsDay todayStepsDay;
|
||||
protected StepsData(List<StepsDay> days) {
|
||||
this.days = days;
|
||||
int daysCounter = 0;
|
||||
for(StepsDay day : days) {
|
||||
this.totalSteps += day.steps;
|
||||
this.totalDistance += day.distance;
|
||||
if (day.steps > 0) {
|
||||
daysCounter++;
|
||||
}
|
||||
}
|
||||
if (daysCounter > 0) {
|
||||
this.stepsDailyAvg = this.totalSteps / daysCounter;
|
||||
this.distanceDailyAvg = this.totalDistance / daysCounter;
|
||||
}
|
||||
this.todayStepsDay = days.get(days.size() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -123,14 +123,15 @@
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/steps_chart_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:text=""
|
||||
android:paddingLeft="20dip"
|
||||
android:textSize="20sp" />
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="250sp">
|
||||
<com.github.mikephil.charting.charts.LineChart
|
||||
android:id="@+id/steps_daily_chart"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="2" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
Loading…
Reference in New Issue
Block a user