mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Refactor sleep chart fragments
This commit is contained in:
+5
@@ -55,6 +55,11 @@ public class CaloriesPeriodFragment extends CaloriesFragment<CaloriesPeriodFragm
|
||||
protected int BACKGROUND_COLOR;
|
||||
protected int DESCRIPTION_COLOR;
|
||||
|
||||
@Override
|
||||
protected boolean isSingleDay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static CaloriesPeriodFragment newInstance(int totalDays) {
|
||||
CaloriesPeriodFragment fragmentFirst = new CaloriesPeriodFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
+5
@@ -70,6 +70,11 @@ public class HeartRatePeriodFragment extends AbstractChartFragment<HeartRatePeri
|
||||
private LineChart hrLineChart;
|
||||
private int TOTAL_DAYS;
|
||||
|
||||
@Override
|
||||
protected boolean isSingleDay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static HeartRatePeriodFragment newInstance(int totalDays) {
|
||||
HeartRatePeriodFragment fragmentFirst = new HeartRatePeriodFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
+5
@@ -43,6 +43,11 @@ public class RespiratoryRatePeriodFragment extends RespiratoryRateFragment<Respi
|
||||
private TextView awakeAvg;
|
||||
private LineChart respiratoryRateChart;
|
||||
|
||||
@Override
|
||||
protected boolean isSingleDay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static RespiratoryRatePeriodFragment newInstance (int totalDays) {
|
||||
RespiratoryRatePeriodFragment fragmentFirst = new RespiratoryRatePeriodFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
+11
-48
@@ -45,7 +45,13 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@@ -59,12 +65,13 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.SleepScoreSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.service.devices.sony.wena3.protocol.packets.notification.defines.LedColor;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.Prefs;
|
||||
|
||||
|
||||
public class DaySleepChartFragment extends AbstractActivityChartFragment<DaySleepChartFragment.MyChartsData> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(DaySleepChartFragment.class);
|
||||
public class SleepDailyFragment extends SleepFragment<SleepDailyFragment.MyChartsData> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(SleepDailyFragment.class);
|
||||
|
||||
private LineChart mActivityChart;
|
||||
private ImageView sleepStagesGauge;
|
||||
@@ -134,8 +141,6 @@ public class DaySleepChartFragment extends AbstractActivityChartFragment<DaySlee
|
||||
return new MyChartsData(mySleepChartsData, chartsData, hrData.getLeft(), hrData.getMiddle(), hrData.getRight(), intensityData.getLeft(), intensityData.getMiddle(), intensityData.getRight());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private MySleepChartsData refreshSleepAmounts(GBDevice mGBDevice, List<? extends ActivitySample> samples, List<? extends SleepScoreSample> sleepScoreSamples) {
|
||||
SleepAnalysis sleepAnalysis = new SleepAnalysis();
|
||||
List<SleepSession> sleepSessions = sleepAnalysis.calculateSleepSessions(samples);
|
||||
@@ -364,15 +369,7 @@ public class DaySleepChartFragment extends AbstractActivityChartFragment<DaySlee
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public boolean supportsSleepScore() {
|
||||
final GBDevice device = getChartsHost().getDevice();
|
||||
return device.getDeviceCoordinator().supportsSleepScore(device);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return getString(R.string.sleepchart_your_sleep);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
@@ -457,30 +454,7 @@ public class DaySleepChartFragment extends AbstractActivityChartFragment<DaySlee
|
||||
|
||||
@Override
|
||||
protected void setupLegend(Chart<?> chart) {
|
||||
List<LegendEntry> legendEntries = new ArrayList<>(4);
|
||||
LegendEntry lightSleepEntry = new LegendEntry();
|
||||
lightSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_light);
|
||||
lightSleepEntry.formColor = akLightSleep.color;
|
||||
legendEntries.add(lightSleepEntry);
|
||||
|
||||
LegendEntry deepSleepEntry = new LegendEntry();
|
||||
deepSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_deep);
|
||||
deepSleepEntry.formColor = akDeepSleep.color;
|
||||
legendEntries.add(deepSleepEntry);
|
||||
|
||||
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry remSleepEntry = new LegendEntry();
|
||||
remSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_rem);
|
||||
remSleepEntry.formColor = akRemSleep.color;
|
||||
legendEntries.add(remSleepEntry);
|
||||
}
|
||||
|
||||
if (supportsAwakeSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry awakeSleepEntry = new LegendEntry();
|
||||
awakeSleepEntry.label = getActivity().getString(R.string.abstract_chart_fragment_kind_awake_sleep);
|
||||
awakeSleepEntry.formColor = akAwakeSleep.color;
|
||||
legendEntries.add(awakeSleepEntry);
|
||||
}
|
||||
List<LegendEntry> legendEntries = super.createLegendEntries(chart);
|
||||
|
||||
if (supportsHeartrate(getChartsHost().getDevice())) {
|
||||
LegendEntry hrEntry = new LegendEntry();
|
||||
@@ -498,17 +472,6 @@ public class DaySleepChartFragment extends AbstractActivityChartFragment<DaySlee
|
||||
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
// Temporary fix for totally wrong sleep amounts.
|
||||
return super.getAllSamples(db, device, tsFrom, tsTo);
|
||||
}
|
||||
|
||||
protected List<SleepScoreSample> getSleepScoreSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
TimeSampleProvider<? extends SleepScoreSample> provider = device.getDeviceCoordinator().getSleepScoreProvider(device, db.getDaoSession());
|
||||
return (List<SleepScoreSample>) provider.getAllSamples(tsFrom * 1000L, tsTo * 1000L);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderCharts() {
|
||||
mActivityChart.animateX(ANIM_TIME, Easing.EaseInOutQuart);
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.components.LegendEntry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.SleepScoreSample;
|
||||
|
||||
abstract class SleepFragment<D extends ChartsData> extends AbstractActivityChartFragment<D> {
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return getString(R.string.sleepchart_your_sleep);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<? extends ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
return super.getAllSamples(db, device, tsFrom, tsTo);
|
||||
}
|
||||
|
||||
public boolean supportsSleepScore() {
|
||||
final GBDevice device = getChartsHost().getDevice();
|
||||
return device.getDeviceCoordinator().supportsSleepScore(device);
|
||||
}
|
||||
|
||||
protected List<SleepScoreSample> getSleepScoreSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
|
||||
TimeSampleProvider<? extends SleepScoreSample> provider = device.getDeviceCoordinator().getSleepScoreProvider(device, db.getDaoSession());
|
||||
return (List<SleepScoreSample>) provider.getAllSamples(tsFrom * 1000L, tsTo * 1000L);
|
||||
}
|
||||
|
||||
protected List<SleepScoreSample> getSleepScoreSamples(DBHandler db, GBDevice device, Calendar day) {
|
||||
int startTs;
|
||||
int endTs;
|
||||
|
||||
day = (Calendar) day.clone(); // do not modify the caller's argument
|
||||
day.set(Calendar.HOUR_OF_DAY, 0);
|
||||
day.set(Calendar.MINUTE, 0);
|
||||
day.set(Calendar.SECOND, 0);
|
||||
day.add(Calendar.HOUR, 0);
|
||||
startTs = (int) (day.getTimeInMillis() / 1000);
|
||||
endTs = startTs + 24 * 60 * 60 - 1;
|
||||
|
||||
TimeSampleProvider<? extends SleepScoreSample> provider = device.getDeviceCoordinator().getSleepScoreProvider(device, db.getDaoSession());
|
||||
return (List<SleepScoreSample>) provider.getAllSamples(startTs * 1000L, endTs * 1000L);
|
||||
}
|
||||
|
||||
protected List<LegendEntry> createLegendEntries(Chart<?> chart) {
|
||||
List<LegendEntry> legendEntries = new ArrayList<>(4);
|
||||
LegendEntry lightSleepEntry = new LegendEntry();
|
||||
lightSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_light);
|
||||
lightSleepEntry.formColor = akLightSleep.color;
|
||||
legendEntries.add(lightSleepEntry);
|
||||
|
||||
LegendEntry deepSleepEntry = new LegendEntry();
|
||||
deepSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_deep);
|
||||
deepSleepEntry.formColor = akDeepSleep.color;
|
||||
legendEntries.add(deepSleepEntry);
|
||||
|
||||
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry remSleepEntry = new LegendEntry();
|
||||
remSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_rem);
|
||||
remSleepEntry.formColor = akRemSleep.color;
|
||||
legendEntries.add(remSleepEntry);
|
||||
}
|
||||
|
||||
if (supportsAwakeSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry awakeSleepEntry = new LegendEntry();
|
||||
awakeSleepEntry.label = getActivity().getString(R.string.abstract_chart_fragment_kind_awake_sleep);
|
||||
awakeSleepEntry.formColor = akAwakeSleep.color;
|
||||
legendEntries.add(awakeSleepEntry);
|
||||
}
|
||||
|
||||
return legendEntries;
|
||||
}
|
||||
}
|
||||
+272
-50
@@ -17,6 +17,8 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
package nodomain.freeyourgadget.gadgetbridge.activities.charts;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Color;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -25,24 +27,35 @@ import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.github.mikephil.charting.charts.BarChart;
|
||||
import com.github.mikephil.charting.charts.Chart;
|
||||
import com.github.mikephil.charting.charts.LineChart;
|
||||
import com.github.mikephil.charting.components.Legend;
|
||||
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.BarData;
|
||||
import com.github.mikephil.charting.data.BarDataSet;
|
||||
import com.github.mikephil.charting.data.BarEntry;
|
||||
import com.github.mikephil.charting.data.ChartData;
|
||||
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 nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
|
||||
import nodomain.freeyourgadget.gadgetbridge.devices.TimeSampleProvider;
|
||||
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
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.concurrent.TimeUnit;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
@@ -50,11 +63,17 @@ import nodomain.freeyourgadget.gadgetbridge.R;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmount;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityAmounts;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivitySample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.ActivityUser;
|
||||
import nodomain.freeyourgadget.gadgetbridge.model.SleepScoreSample;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.LimitedQueue;
|
||||
|
||||
public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
public class SleepPeriodFragment extends SleepFragment<SleepPeriodFragment.MyChartsData> {
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(SleepPeriodFragment.class);
|
||||
|
||||
protected int TOTAL_DAYS = getRangeDays();
|
||||
protected int TOTAL_DAYS_FOR_AVERAGE = 0;
|
||||
private TextView awakeSleepTimeText;
|
||||
private LinearLayout awakeSleepTimeTextWrapper;
|
||||
private TextView remSleepTimeText;
|
||||
@@ -67,11 +86,16 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
private LineChart sleepScoreChart;
|
||||
|
||||
private TextView mBalanceView;
|
||||
protected Locale mLocale;
|
||||
protected int mTargetValue = 0;
|
||||
|
||||
protected BarChart mWeekChart;
|
||||
private final int mOffsetHours = getOffsetHours();
|
||||
|
||||
protected boolean SHOW_BALANCE;
|
||||
|
||||
public static WeekSleepChartFragment newInstance ( int totalDays ) {
|
||||
WeekSleepChartFragment fragmentFirst = new WeekSleepChartFragment();
|
||||
public static SleepPeriodFragment newInstance(int totalDays) {
|
||||
SleepPeriodFragment fragmentFirst = new SleepPeriodFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt("totalDays", totalDays);
|
||||
fragmentFirst.setArguments(args);
|
||||
@@ -167,7 +191,38 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
}
|
||||
|
||||
protected void setupWeekChart() {
|
||||
super.setupWeekChart();
|
||||
mWeekChart.setBackgroundColor(BACKGROUND_COLOR);
|
||||
mWeekChart.getDescription().setTextColor(DESCRIPTION_COLOR);
|
||||
mWeekChart.getDescription().setText("");
|
||||
mWeekChart.setFitBars(true);
|
||||
|
||||
configureBarLineChartDefaults(mWeekChart);
|
||||
|
||||
XAxis x = mWeekChart.getXAxis();
|
||||
x.setDrawLabels(true);
|
||||
x.setDrawGridLines(false);
|
||||
x.setEnabled(true);
|
||||
x.setTextColor(CHART_TEXT_COLOR);
|
||||
x.setDrawLimitLinesBehindData(true);
|
||||
x.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
|
||||
YAxis y = mWeekChart.getAxisLeft();
|
||||
y.setDrawGridLines(false);
|
||||
y.setDrawTopYLabelEntry(false);
|
||||
y.setTextColor(CHART_TEXT_COLOR);
|
||||
y.setDrawZeroLine(true);
|
||||
y.setSpaceBottom(0);
|
||||
y.setAxisMinimum(0);
|
||||
y.setValueFormatter(getYAxisFormatter());
|
||||
y.setEnabled(true);
|
||||
|
||||
YAxis yAxisRight = mWeekChart.getAxisRight();
|
||||
yAxisRight.setDrawGridLines(false);
|
||||
yAxisRight.setEnabled(false);
|
||||
yAxisRight.setDrawLabels(false);
|
||||
yAxisRight.setDrawTopYLabelEntry(false);
|
||||
yAxisRight.setTextColor(CHART_TEXT_COLOR);
|
||||
|
||||
if (TOTAL_DAYS > 7) {
|
||||
mWeekChart.setRenderer(new AngledLabelsChartRenderer(mWeekChart, mWeekChart.getAnimator(), mWeekChart.getViewPortHandler()));
|
||||
} else {
|
||||
@@ -236,6 +291,129 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return new MyChartsData(weekBeforeData);
|
||||
}
|
||||
|
||||
protected WeekChartsData<BarData> refreshWeekBeforeData(DBHandler db, BarChart barChart, Calendar day, GBDevice device) {
|
||||
day = (Calendar) day.clone(); // do not modify the caller's argument
|
||||
day.add(Calendar.DATE, -TOTAL_DAYS + 1);
|
||||
List<BarEntry> entries = new ArrayList<>();
|
||||
ArrayList<String> labels = new ArrayList<String>();
|
||||
|
||||
long balance = 0;
|
||||
long daily_balance = 0;
|
||||
TOTAL_DAYS_FOR_AVERAGE=0;
|
||||
List<Entry> sleepScoreEntities = new ArrayList<>();
|
||||
final List<ILineDataSet> sleepScoreDataSets = new ArrayList<>();
|
||||
for (int counter = 0; counter < TOTAL_DAYS; counter++) {
|
||||
// Sleep stages
|
||||
ActivityAmounts amounts = getActivityAmountsForDay(db, day, device);
|
||||
daily_balance=calculateBalance(amounts);
|
||||
if (daily_balance > 0) {
|
||||
TOTAL_DAYS_FOR_AVERAGE++;
|
||||
}
|
||||
balance += daily_balance;
|
||||
entries.add(new BarEntry(counter, getTotalsForActivityAmounts(amounts)));
|
||||
labels.add(getWeeksChartsLabel(day));
|
||||
// Sleep score
|
||||
if (supportsSleepScore()) {
|
||||
List<? extends SleepScoreSample> sleepScoreSamples = getSleepScoreSamples(db, device, day);
|
||||
if (!sleepScoreSamples.isEmpty() && sleepScoreSamples.get(0).getSleepScore() > 0) {
|
||||
sleepScoreEntities.add(new Entry(counter, sleepScoreSamples.get(0).getSleepScore()));
|
||||
} else {
|
||||
if (!sleepScoreEntities.isEmpty()) {
|
||||
List<Entry> clone = new ArrayList<>(sleepScoreEntities.size());
|
||||
clone.addAll(sleepScoreEntities);
|
||||
sleepScoreDataSets.add(createSleepScoreDataSet(clone));
|
||||
sleepScoreEntities.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
day.add(Calendar.DATE, 1);
|
||||
}
|
||||
if (!sleepScoreEntities.isEmpty()) {
|
||||
sleepScoreDataSets.add(createSleepScoreDataSet(sleepScoreEntities));
|
||||
}
|
||||
final LineData sleepScoreLineData = new LineData(sleepScoreDataSets);
|
||||
sleepScoreLineData.setHighlightEnabled(false);
|
||||
|
||||
BarDataSet set = new BarDataSet(entries, "");
|
||||
set.setColors(getColors());
|
||||
set.setValueFormatter(getBarValueFormatter());
|
||||
|
||||
BarData barData = new BarData(set);
|
||||
barData.setValueTextColor(Color.GRAY); //prevent tearing other graph elements with the black text. Another approach would be to hide the values cmpletely with data.setDrawValues(false);
|
||||
barData.setValueTextSize(10f);
|
||||
|
||||
barChart.getAxisLeft().setAxisMaximum(Math.max(set.getYMax(), mTargetValue) + 60);
|
||||
|
||||
LimitLine target = new LimitLine(mTargetValue);
|
||||
target.setLineWidth(1.5f);
|
||||
target.enableDashedLine(15f, 10f, 0f);
|
||||
target.setLineColor(getResources().getColor(R.color.chart_deep_sleep_dark));
|
||||
barChart.getAxisLeft().removeAllLimitLines();
|
||||
barChart.getAxisLeft().addLimitLine(target);
|
||||
|
||||
float average = 0;
|
||||
if (TOTAL_DAYS_FOR_AVERAGE > 0) {
|
||||
average = Math.abs(balance / TOTAL_DAYS_FOR_AVERAGE);
|
||||
}
|
||||
LimitLine average_line = new LimitLine(average);
|
||||
average_line.setLineWidth(1.5f);
|
||||
average_line.enableDashedLine(15f, 10f, 0f);
|
||||
average_line.setLabel(getString(R.string.average, getAverage(average)));
|
||||
|
||||
if (average > (mTargetValue)) {
|
||||
average_line.setLineColor(Color.GREEN);
|
||||
average_line.setTextColor(Color.GREEN);
|
||||
}
|
||||
else {
|
||||
average_line.setLineColor(Color.RED);
|
||||
average_line.setTextColor(Color.RED);
|
||||
}
|
||||
if (average > 0) {
|
||||
if (GBApplication.getPrefs().getBoolean("charts_show_average", true)) {
|
||||
barChart.getAxisLeft().addLimitLine(average_line);
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsSleepScore()) {
|
||||
return new WeekChartsData(barData, new PreformattedXIndexLabelFormatter(labels), getBalanceMessage(balance, mTargetValue), sleepScoreLineData);
|
||||
}
|
||||
return new WeekChartsData(barData, new PreformattedXIndexLabelFormatter(labels), getBalanceMessage(balance, mTargetValue));
|
||||
}
|
||||
|
||||
protected String getWeeksChartsLabel(Calendar day){
|
||||
if (TOTAL_DAYS > 7) {
|
||||
//month, show day date
|
||||
return String.valueOf(day.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
else{
|
||||
//week, show short day name
|
||||
return day.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, mLocale);
|
||||
}
|
||||
}
|
||||
|
||||
protected LineDataSet createSleepScoreDataSet(final List<Entry> values) {
|
||||
final LineDataSet lineDataSet = new LineDataSet(values, getString(R.string.sleep_score));
|
||||
lineDataSet.setColor(getResources().getColor(R.color.chart_light_sleep_light));
|
||||
lineDataSet.setDrawCircles(false);
|
||||
lineDataSet.setLineWidth(2f);
|
||||
lineDataSet.setFillAlpha(255);
|
||||
lineDataSet.setCircleRadius(5f);
|
||||
lineDataSet.setDrawCircles(true);
|
||||
lineDataSet.setDrawCircleHole(true);
|
||||
lineDataSet.setCircleColor(getResources().getColor(R.color.chart_light_sleep_light));
|
||||
lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
|
||||
lineDataSet.setDrawValues(true);
|
||||
lineDataSet.setValueTextSize(10f);
|
||||
lineDataSet.setValueTextColor(CHART_TEXT_COLOR);
|
||||
lineDataSet.setValueFormatter(new ValueFormatter() {
|
||||
@Override
|
||||
public String getFormattedValue(float value) {
|
||||
return String.format(Locale.ROOT, "%d", (int) value);
|
||||
}
|
||||
});
|
||||
return lineDataSet;
|
||||
};
|
||||
|
||||
private void setupSleepScoreChart() {
|
||||
final XAxis xAxisBottom = sleepScoreChart.getXAxis();
|
||||
xAxisBottom.setPosition(XAxis.XAxisPosition.BOTTOM);
|
||||
@@ -287,23 +465,19 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String getPieDescription(int targetValue) {
|
||||
return getString(R.string.weeksleepchart_today_sleep_description, DateTimeUtils.formatDurationHoursMinutes(targetValue, TimeUnit.MINUTES));
|
||||
}
|
||||
|
||||
@Override
|
||||
int getGoal() {
|
||||
return GBApplication.getPrefs().getInt(ActivityUser.PREF_USER_SLEEP_DURATION, 8) * 60;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getOffsetHours() {
|
||||
return -12;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected long calculateBalance(ActivityAmounts activityAmounts) {
|
||||
long balance = 0;
|
||||
|
||||
@@ -317,7 +491,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return (int) (balance / 60);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBalanceMessage(long balance, int targetValue) {
|
||||
if (balance > 0) {
|
||||
final long totalBalance = balance - ((long)targetValue * TOTAL_DAYS_FOR_AVERAGE);
|
||||
@@ -329,7 +502,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return getString(R.string.no_data);
|
||||
}
|
||||
|
||||
@Override
|
||||
float[] getTotalsForActivityAmounts(ActivityAmounts activityAmounts) {
|
||||
long totalSecondsDeepSleep = 0;
|
||||
long totalSecondsLightSleep = 0;
|
||||
@@ -362,12 +534,10 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return activityAmountsTotals;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String formatPieValue(long value) {
|
||||
return DateTimeUtils.formatDurationHoursMinutes(value, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
String[] getPieLabels() {
|
||||
String[] labels = {
|
||||
getString(R.string.abstract_chart_fragment_kind_deep_sleep),
|
||||
@@ -382,7 +552,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return labels;
|
||||
}
|
||||
|
||||
@Override
|
||||
ValueFormatter getPieValueFormatter() {
|
||||
return new ValueFormatter() {
|
||||
@Override
|
||||
@@ -392,7 +561,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
ValueFormatter getBarValueFormatter() {
|
||||
return new ValueFormatter() {
|
||||
@Override
|
||||
@@ -402,7 +570,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
ValueFormatter getYAxisFormatter() {
|
||||
return new ValueFormatter() {
|
||||
@Override
|
||||
@@ -412,7 +579,6 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
int[] getColors() {
|
||||
int[] colors = {akDeepSleep.color, akLightSleep.color};
|
||||
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||
@@ -426,33 +592,9 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
|
||||
@Override
|
||||
protected void setupLegend(Chart<?> chart) {
|
||||
List<LegendEntry> legendEntries = new ArrayList<>(2);
|
||||
|
||||
LegendEntry lightSleepEntry = new LegendEntry();
|
||||
lightSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_light);
|
||||
lightSleepEntry.formColor = akLightSleep.color;
|
||||
legendEntries.add(lightSleepEntry);
|
||||
|
||||
LegendEntry deepSleepEntry = new LegendEntry();
|
||||
deepSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_deep);
|
||||
deepSleepEntry.formColor = akDeepSleep.color;
|
||||
legendEntries.add(deepSleepEntry);
|
||||
|
||||
if (supportsRemSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry remSleepEntry = new LegendEntry();
|
||||
remSleepEntry.label = getActivity().getString(R.string.sleep_colored_stats_rem);
|
||||
remSleepEntry.formColor = akRemSleep.color;
|
||||
legendEntries.add(remSleepEntry);
|
||||
}
|
||||
|
||||
if (supportsAwakeSleep(getChartsHost().getDevice())) {
|
||||
LegendEntry awakeSleepEntry = new LegendEntry();
|
||||
awakeSleepEntry.label = getActivity().getString(R.string.abstract_chart_fragment_kind_awake_sleep);
|
||||
awakeSleepEntry.formColor = akAwakeSleep.color;
|
||||
legendEntries.add(awakeSleepEntry);
|
||||
}
|
||||
|
||||
List<LegendEntry> legendEntries = super.createLegendEntries(chart);
|
||||
chart.getLegend().setCustom(legendEntries);
|
||||
|
||||
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
|
||||
chart.getLegend().setWordWrapEnabled(true);
|
||||
chart.getLegend().setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
|
||||
@@ -462,17 +604,97 @@ public class WeekSleepChartFragment extends AbstractWeekChartFragment {
|
||||
return DateTimeUtils.formatDurationHoursMinutes(value, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
String getAverage(float value) {
|
||||
return getHM((long)value);
|
||||
}
|
||||
|
||||
protected static class MyChartsData extends ChartsData {
|
||||
private final WeekChartsData<BarData> weekBeforeData;
|
||||
|
||||
MyChartsData(WeekChartsData<BarData> weekBeforeData) {
|
||||
this.weekBeforeData = weekBeforeData;
|
||||
}
|
||||
|
||||
WeekChartsData<BarData> getWeekBeforeData() {
|
||||
return weekBeforeData;
|
||||
}
|
||||
}
|
||||
|
||||
protected ActivityAmounts getActivityAmountsForDay(DBHandler db, Calendar day, GBDevice device) {
|
||||
|
||||
LimitedQueue<Integer, ActivityAmounts> activityAmountCache = null;
|
||||
ActivityAmounts amounts = null;
|
||||
|
||||
Activity activity = getActivity();
|
||||
int key = (int) (day.getTimeInMillis() / 1000) + (mOffsetHours * 3600);
|
||||
if (activity != null) {
|
||||
activityAmountCache = ((ActivityChartsActivity) activity).mActivityAmountCache;
|
||||
amounts = activityAmountCache.lookup(key);
|
||||
}
|
||||
|
||||
if (amounts == null) {
|
||||
ActivityAnalysis analysis = new ActivityAnalysis();
|
||||
amounts = analysis.calculateActivityAmounts(getSamplesOfDay(db, day, mOffsetHours, device));
|
||||
if (activityAmountCache != null) {
|
||||
activityAmountCache.add(key, amounts);
|
||||
}
|
||||
}
|
||||
|
||||
return amounts;
|
||||
}
|
||||
|
||||
private List<? extends ActivitySample> getSamplesOfDay(DBHandler db, Calendar day, int offsetHours, GBDevice device) {
|
||||
int startTs;
|
||||
int endTs;
|
||||
|
||||
day = (Calendar) day.clone(); // do not modify the caller's argument
|
||||
day.set(Calendar.HOUR_OF_DAY, 0);
|
||||
day.set(Calendar.MINUTE, 0);
|
||||
day.set(Calendar.SECOND, 0);
|
||||
day.add(Calendar.HOUR, offsetHours);
|
||||
|
||||
startTs = (int) (day.getTimeInMillis() / 1000);
|
||||
endTs = startTs + 24 * 60 * 60 - 1;
|
||||
|
||||
return getSamples(db, device, startTs, endTs);
|
||||
}
|
||||
|
||||
private int getRangeDays(){
|
||||
if (GBApplication.getPrefs().getBoolean("charts_range", true)) {
|
||||
return 30;}
|
||||
else{
|
||||
return 7;
|
||||
}
|
||||
}
|
||||
|
||||
protected class WeekChartsData<T extends ChartData<?>> extends DefaultChartsData<T> {
|
||||
private final String balanceMessage;
|
||||
private LineData sleepScoresLineData;
|
||||
|
||||
public WeekChartsData(T data, PreformattedXIndexLabelFormatter xIndexLabelFormatter, String balanceMessage) {
|
||||
super(data, xIndexLabelFormatter);
|
||||
this.balanceMessage = balanceMessage;
|
||||
}
|
||||
|
||||
public WeekChartsData(T data, PreformattedXIndexLabelFormatter xIndexLabelFormatter, String balanceMessage, LineData sleepScores) {
|
||||
super(data, xIndexLabelFormatter);
|
||||
this.balanceMessage = balanceMessage;
|
||||
this.sleepScoresLineData = sleepScores;
|
||||
}
|
||||
|
||||
public String getBalanceMessage() {
|
||||
return balanceMessage;
|
||||
}
|
||||
|
||||
public LineData getSleepScoreData() { return sleepScoresLineData; }
|
||||
}
|
||||
|
||||
private static class MySleepWeeklyData {
|
||||
private long totalAwake;
|
||||
private long totalRem;
|
||||
private long totalDeep;
|
||||
private long totalLight;
|
||||
private int totalDaysForAverage;
|
||||
private final long totalAwake;
|
||||
private final long totalRem;
|
||||
private final long totalDeep;
|
||||
private final long totalLight;
|
||||
private final int totalDaysForAverage;
|
||||
|
||||
public MySleepWeeklyData(long totalAwake, long totalRem, long totalDeep, long totalLight) {
|
||||
this.totalDeep = totalDeep;
|
||||
+5
@@ -57,6 +57,11 @@ public class StepsPeriodFragment extends StepsFragment<StepsPeriodFragment.Steps
|
||||
protected int BACKGROUND_COLOR;
|
||||
protected int DESCRIPTION_COLOR;
|
||||
|
||||
@Override
|
||||
protected boolean isSingleDay() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static StepsPeriodFragment newInstance(int totalDays) {
|
||||
StepsPeriodFragment fragmentFirst = new StepsPeriodFragment();
|
||||
Bundle args = new Bundle();
|
||||
|
||||
-3
@@ -4,10 +4,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.DaySleepChartFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.WeekSleepChartFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.HeartRatePeriodFragment;
|
||||
|
||||
public class HeartRateFragmentAdapter extends NestedFragmentAdapter {
|
||||
|
||||
+6
-6
@@ -6,8 +6,8 @@ import androidx.fragment.app.FragmentManager;
|
||||
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.AbstractGBFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.DaySleepChartFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.WeekSleepChartFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.SleepDailyFragment;
|
||||
import nodomain.freeyourgadget.gadgetbridge.activities.charts.SleepPeriodFragment;
|
||||
|
||||
public class SleepFragmentAdapter extends NestedFragmentAdapter {
|
||||
public SleepFragmentAdapter(AbstractGBFragment fragment, FragmentManager childFragmentManager) {
|
||||
@@ -19,12 +19,12 @@ public class SleepFragmentAdapter extends NestedFragmentAdapter {
|
||||
public Fragment createFragment(int position) {
|
||||
switch (position) {
|
||||
case 0:
|
||||
return new DaySleepChartFragment();
|
||||
return new SleepDailyFragment();
|
||||
case 1:
|
||||
return WeekSleepChartFragment.newInstance(7);
|
||||
return SleepPeriodFragment.newInstance(7);
|
||||
case 2:
|
||||
return WeekSleepChartFragment.newInstance(30);
|
||||
return SleepPeriodFragment.newInstance(30);
|
||||
}
|
||||
return new DaySleepChartFragment();
|
||||
return new SleepDailyFragment();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user