1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-07-23 07:11:52 +02:00
Gadgetbridge/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/SleepChartFragment.java
cpfeiffer 2e267a4c2b Temporary workaround for totally wrong sleep stats
The reason being that we filter samples by activity kind
and then calculate the total sleep time using a delta between two
consecutive sample timestamps. But due to filtering of samples, not
all samples are consecutive. Instead of we have "holes" and add those
to your sleep time.

The data in the db is correct though (it always is), it's just the
display in the app that is wrong.
2015-11-09 23:56:46 +01:00

190 lines
7.3 KiB
Java

package nodomain.freeyourgadget.gadgetbridge.activities.charts;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.BarLineChartBase;
import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.PieChart;
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.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.formatter.ValueFormatter;
import com.github.mikephil.charting.utils.ViewPortHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import nodomain.freeyourgadget.gadgetbridge.R;
import nodomain.freeyourgadget.gadgetbridge.database.DBHandler;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
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.util.DateTimeUtils;
public class SleepChartFragment extends AbstractChartFragment {
protected static final Logger LOG = LoggerFactory.getLogger(ActivitySleepChartFragment.class);
private BarLineChartBase mActivityChart;
private PieChart mSleepAmountChart;
private int mSmartAlarmFrom = -1;
private int mSmartAlarmTo = -1;
private int mTimestampFrom = -1;
private int mSmartAlarmGoneOff = -1;
@Override
protected void refreshInBackground(DBHandler db, GBDevice device) {
List<ActivitySample> samples = getSamples(db, device);
refresh(device, mActivityChart, samples);
refreshSleepAmounts(device, mSleepAmountChart, samples);
}
private void refreshSleepAmounts(GBDevice mGBDevice, PieChart pieChart, List<ActivitySample> samples) {
ActivityAnalysis analysis = new ActivityAnalysis();
ActivityAmounts amounts = analysis.calculateActivityAmounts(samples);
PieData data = new PieData();
List<Entry> entries = new ArrayList<>();
List<Integer> colors = new ArrayList<>();
int index = 0;
long totalSeconds = 0;
for (ActivityAmount amount : amounts.getAmounts()) {
if ((amount.getActivityKind() & ActivityKind.TYPE_SLEEP) != 0) {
long value = amount.getTotalSeconds();
totalSeconds += value;
entries.add(new Entry(value, index++));
colors.add(getColorFor(amount.getActivityKind()));
data.addXValue(amount.getName(getActivity()));
}
}
String totalSleep = DateTimeUtils.formatDurationHoursMinutes(totalSeconds, TimeUnit.SECONDS);
pieChart.setCenterText(totalSleep);
PieDataSet set = new PieDataSet(entries, "");
set.setValueFormatter(new ValueFormatter() {
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
return DateTimeUtils.formatDurationHoursMinutes((long) value, TimeUnit.SECONDS);
}
});
set.setColors(colors);
data.setDataSet(set);
pieChart.setData(data);
pieChart.getLegend().setEnabled(false);
//setupLegend(pieChart);
}
@Override
public String getTitle() {
return getString(R.string.sleepchart_your_sleep);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_sleepchart, container, false);
mActivityChart = (BarLineChartBase) rootView.findViewById(R.id.sleepchart);
mSleepAmountChart = (PieChart) rootView.findViewById(R.id.sleepchart_pie_light_deep);
setupActivityChart();
setupSleepAmountChart();
// refresh immediately instead of use refreshIfVisible(), for perceived performance
refresh();
return rootView;
}
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ChartsHost.REFRESH)) {
// TODO: use LimitLines to visualize smart alarms?
mSmartAlarmFrom = intent.getIntExtra("smartalarm_from", -1);
mSmartAlarmTo = intent.getIntExtra("smartalarm_to", -1);
mTimestampFrom = intent.getIntExtra("recording_base_timestamp", -1);
mSmartAlarmGoneOff = intent.getIntExtra("alarm_gone_off", -1);
refresh();
} else {
super.onReceive(context, intent);
}
}
private void setupSleepAmountChart() {
mSleepAmountChart.setBackgroundColor(BACKGROUND_COLOR);
mSleepAmountChart.setDescriptionColor(DESCRIPTION_COLOR);
mSleepAmountChart.setDescription("");
mSleepAmountChart.setNoDataTextDescription("");
mSleepAmountChart.setNoDataText("");
}
private void setupActivityChart() {
mActivityChart.setBackgroundColor(BACKGROUND_COLOR);
mActivityChart.setDescriptionColor(DESCRIPTION_COLOR);
configureBarLineChartDefaults(mActivityChart);
XAxis x = mActivityChart.getXAxis();
x.setDrawLabels(true);
x.setDrawGridLines(false);
x.setEnabled(true);
x.setTextColor(CHART_TEXT_COLOR);
x.setDrawLimitLinesBehindData(true);
YAxis y = mActivityChart.getAxisLeft();
y.setDrawGridLines(false);
// y.setDrawLabels(false);
// TODO: make fixed max value optional
y.setAxisMaxValue(1f);
y.setDrawTopYLabelEntry(false);
y.setTextColor(CHART_TEXT_COLOR);
// y.setLabelCount(5);
y.setEnabled(true);
YAxis yAxisRight = mActivityChart.getAxisRight();
yAxisRight.setDrawGridLines(false);
yAxisRight.setEnabled(false);
yAxisRight.setDrawLabels(false);
yAxisRight.setDrawTopYLabelEntry(false);
yAxisRight.setTextColor(CHART_TEXT_COLOR);
}
protected void setupLegend(Chart chart) {
List<Integer> legendColors = new ArrayList<>(2);
List<String> legendLabels = new ArrayList<>(2);
legendColors.add(akLightSleep.color);
legendLabels.add(akLightSleep.label);
legendColors.add(akDeepSleep.color);
legendLabels.add(akDeepSleep.label);
chart.getLegend().setCustom(legendColors, legendLabels);
chart.getLegend().setTextColor(LEGEND_TEXT_COLOR);
}
@Override
protected List<ActivitySample> getSamples(DBHandler db, GBDevice device, int tsFrom, int tsTo) {
// temporary fix for totally wrong sleep amounts
// return super.getSleepSamples(db, device, tsFrom, tsTo);
return super.getAllSamples(db, device, tsFrom, tsTo);
}
protected void renderCharts() {
mActivityChart.animateX(ANIM_TIME, Easing.EasingOption.EaseInOutQuart);
mSleepAmountChart.invalidate();
}
}