mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2025-02-17 21:06:48 +01:00
Make timestamp to mpandroidchart float x-value explicit
This commit is contained in:
parent
125c0092cb
commit
c2ff05e849
@ -411,7 +411,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
protected DefaultChartsData<CombinedData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
|
protected DefaultChartsData<CombinedData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
|
||||||
// Calendar cal = GregorianCalendar.getInstance();
|
// Calendar cal = GregorianCalendar.getInstance();
|
||||||
// cal.clear();
|
// cal.clear();
|
||||||
int tsOffset = 0;
|
TimestampTranslation tsTranslation = new TimestampTranslation();
|
||||||
// Date date;
|
// Date date;
|
||||||
// String dateStringFrom = "";
|
// String dateStringFrom = "";
|
||||||
// String dateStringTo = "";
|
// String dateStringTo = "";
|
||||||
@ -435,13 +435,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
for (int i = 0; i < numEntries; i++) {
|
for (int i = 0; i < numEntries; i++) {
|
||||||
ActivitySample sample = samples.get(i);
|
ActivitySample sample = samples.get(i);
|
||||||
int type = sample.getKind();
|
int type = sample.getKind();
|
||||||
int ts;
|
int ts = tsTranslation.shorten(sample.getTimestamp());
|
||||||
if (i == 0) {
|
|
||||||
tsOffset = sample.getTimestamp();
|
|
||||||
ts = 0;
|
|
||||||
} else {
|
|
||||||
ts = sample.getTimestamp() - tsOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// System.out.println(ts);
|
// System.out.println(ts);
|
||||||
// ts = i;
|
// ts = i;
|
||||||
@ -541,7 +535,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
combinedData = new CombinedData();
|
combinedData = new CombinedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
IAxisValueFormatter xValueFormatter = new SampleXLabelFormatter(tsOffset);
|
IAxisValueFormatter xValueFormatter = new SampleXLabelFormatter(tsTranslation);
|
||||||
return new DefaultChartsData(combinedData, xValueFormatter);
|
return new DefaultChartsData(combinedData, xValueFormatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,13 +744,13 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static class SampleXLabelFormatter implements IAxisValueFormatter {
|
protected static class SampleXLabelFormatter implements IAxisValueFormatter {
|
||||||
private final int tsOffset;
|
private final TimestampTranslation tsTranslation;
|
||||||
SimpleDateFormat annotationDateFormat = new SimpleDateFormat("HH:mm");
|
SimpleDateFormat annotationDateFormat = new SimpleDateFormat("HH:mm");
|
||||||
// SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
|
// SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
|
||||||
Calendar cal = GregorianCalendar.getInstance();
|
Calendar cal = GregorianCalendar.getInstance();
|
||||||
|
|
||||||
public SampleXLabelFormatter(int tsOffset) {
|
public SampleXLabelFormatter(TimestampTranslation tsTranslation) {
|
||||||
this.tsOffset = tsOffset;
|
this.tsTranslation = tsTranslation;
|
||||||
|
|
||||||
}
|
}
|
||||||
// TODO: this does not work. Cannot use precomputed labels
|
// TODO: this does not work. Cannot use precomputed labels
|
||||||
@ -764,7 +758,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
public String getFormattedValue(float value, AxisBase axis) {
|
public String getFormattedValue(float value, AxisBase axis) {
|
||||||
cal.clear();
|
cal.clear();
|
||||||
int ts = (int) value;
|
int ts = (int) value;
|
||||||
cal.setTimeInMillis((ts + tsOffset) * 1000L);
|
cal.setTimeInMillis(tsTranslation.toOriginalValue(ts) * 1000L);
|
||||||
Date date = cal.getTime();
|
Date date = cal.getTime();
|
||||||
String dateString = annotationDateFormat.format(date);
|
String dateString = annotationDateFormat.format(date);
|
||||||
return dateString;
|
return dateString;
|
||||||
@ -797,4 +791,31 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Awkward class that helps in translating long timestamp
|
||||||
|
* values to float (sic!) values. It basically rebases all
|
||||||
|
* timestamps to a base (the very first) timestamp value.
|
||||||
|
*
|
||||||
|
* It does this so that the large timestamp values can be used
|
||||||
|
* floating point values, where the mantissa is just 24 bits.
|
||||||
|
*/
|
||||||
|
protected static class TimestampTranslation {
|
||||||
|
private int tsOffset = -1;
|
||||||
|
|
||||||
|
public int shorten(int timestamp) {
|
||||||
|
if (tsOffset == -1) {
|
||||||
|
tsOffset = timestamp;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return timestamp - tsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int toOriginalValue(int timestamp) {
|
||||||
|
if (tsOffset == -1) {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
return timestamp + tsOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,13 +69,13 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
private List<Measurement> heartRateValues;
|
private List<Measurement> heartRateValues;
|
||||||
private LineDataSet mHeartRateSet;
|
private LineDataSet mHeartRateSet;
|
||||||
private int mHeartRate;
|
private int mHeartRate;
|
||||||
private long tsOffset = -1;
|
private TimestampTranslation tsTranslation;
|
||||||
|
|
||||||
private class Steps {
|
private class Steps {
|
||||||
private int initialSteps;
|
private int initialSteps;
|
||||||
|
|
||||||
private int steps;
|
private int steps;
|
||||||
private long lastTimestamp;
|
private int lastTimestamp;
|
||||||
private int currentStepsPerMinute;
|
private int currentStepsPerMinute;
|
||||||
private int maxStepsPerMinute;
|
private int maxStepsPerMinute;
|
||||||
private int lastStepsPerMinute;
|
private int lastStepsPerMinute;
|
||||||
@ -97,7 +97,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
return maxStepsPerMinute;
|
return maxStepsPerMinute;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCurrentSteps(int newSteps, long timestamp) {
|
public void updateCurrentSteps(int newSteps, int timestamp) {
|
||||||
try {
|
try {
|
||||||
if (steps == 0) {
|
if (steps == 0) {
|
||||||
steps = newSteps;
|
steps = newSteps;
|
||||||
@ -111,7 +111,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
|
|
||||||
if (newSteps >= steps) {
|
if (newSteps >= steps) {
|
||||||
int stepsDelta = newSteps - steps;
|
int stepsDelta = newSteps - steps;
|
||||||
long timeDelta = timestamp - lastTimestamp;
|
int timeDelta = timestamp - lastTimestamp;
|
||||||
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
|
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
|
||||||
if (currentStepsPerMinute > maxStepsPerMinute) {
|
if (currentStepsPerMinute > maxStepsPerMinute) {
|
||||||
maxStepsPerMinute = currentStepsPerMinute;
|
maxStepsPerMinute = currentStepsPerMinute;
|
||||||
@ -128,16 +128,16 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateStepsPerMinute(int stepsDelta, long millis) {
|
private int calculateStepsPerMinute(int stepsDelta, int seconds) {
|
||||||
if (stepsDelta == 0) {
|
if (stepsDelta == 0) {
|
||||||
return 0; // not walking or not enough data per mills?
|
return 0; // not walking or not enough data per mills?
|
||||||
}
|
}
|
||||||
if (millis <= 0) {
|
if (seconds <= 0) {
|
||||||
throw new IllegalArgumentException("delta in millis is <= 0 -- time change?");
|
throw new IllegalArgumentException("delta in seconds is <= 0 -- time change?");
|
||||||
}
|
}
|
||||||
|
|
||||||
long oneMinute = 60 * 1000;
|
int oneMinute = 60 * 1000;
|
||||||
float factor = oneMinute / millis;
|
float factor = oneMinute / seconds;
|
||||||
int result = (int) (stepsDelta * factor);
|
int result = (int) (stepsDelta * factor);
|
||||||
if (result > MAX_STEPS_PER_MINUTE) {
|
if (result > MAX_STEPS_PER_MINUTE) {
|
||||||
// ignore, return previous value instead
|
// ignore, return previous value instead
|
||||||
@ -154,15 +154,13 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
switch (action) {
|
switch (action) {
|
||||||
case DeviceService.ACTION_REALTIME_STEPS: {
|
case DeviceService.ACTION_REALTIME_STEPS: {
|
||||||
int steps = intent.getIntExtra(DeviceService.EXTRA_REALTIME_STEPS, 0);
|
int steps = intent.getIntExtra(DeviceService.EXTRA_REALTIME_STEPS, 0);
|
||||||
long timestamp = intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
|
int timestamp = translateTimestampFrom(intent);
|
||||||
timestamp = adjust(timestamp);
|
|
||||||
addEntries(steps, timestamp);
|
addEntries(steps, timestamp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DeviceService.ACTION_HEARTRATE_MEASUREMENT: {
|
case DeviceService.ACTION_HEARTRATE_MEASUREMENT: {
|
||||||
int heartRate = intent.getIntExtra(DeviceService.EXTRA_HEART_RATE_VALUE, 0);
|
int heartRate = intent.getIntExtra(DeviceService.EXTRA_HEART_RATE_VALUE, 0);
|
||||||
long timestamp = intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
|
int timestamp = translateTimestampFrom(intent);
|
||||||
timestamp = adjust(timestamp);
|
|
||||||
if (isValidHeartRateValue(heartRate)) {
|
if (isValidHeartRateValue(heartRate)) {
|
||||||
setCurrentHeartRate(heartRate, timestamp);
|
setCurrentHeartRate(heartRate, timestamp);
|
||||||
}
|
}
|
||||||
@ -172,15 +170,16 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private long adjust(long timestamp) {
|
private int translateTimestampFrom(Intent intent) {
|
||||||
if (tsOffset == -1) {
|
return translateTimestamp(intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis()));
|
||||||
tsOffset = timestamp;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return timestamp - tsOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCurrentHeartRate(int heartRate, long timestamp) {
|
private int translateTimestamp(long tsMillis) {
|
||||||
|
int timestamp = (int) (tsMillis / 1000); // translate to seconds
|
||||||
|
return tsTranslation.shorten(timestamp); // and shorten
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentHeartRate(int heartRate, int timestamp) {
|
||||||
addHistoryDataSet(true);
|
addHistoryDataSet(true);
|
||||||
mHeartRate = heartRate;
|
mHeartRate = heartRate;
|
||||||
}
|
}
|
||||||
@ -191,7 +190,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEntries(int steps, long timestamp) {
|
private void addEntries(int steps, int timestamp) {
|
||||||
mSteps.updateCurrentSteps(steps, timestamp);
|
mSteps.updateCurrentSteps(steps, timestamp);
|
||||||
if (++maxStepsResetCounter > RESET_COUNT) {
|
if (++maxStepsResetCounter > RESET_COUNT) {
|
||||||
maxStepsResetCounter = 0;
|
maxStepsResetCounter = 0;
|
||||||
@ -203,7 +202,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
// addEntries();
|
// addEntries();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addEntries(long timestamp) {
|
private void addEntries(int timestamp) {
|
||||||
mTotalStepsChart.setSingleEntryYValue(mSteps.getTotalSteps());
|
mTotalStepsChart.setSingleEntryYValue(mSteps.getTotalSteps());
|
||||||
YAxis stepsPerMinuteCurrentYAxis = mStepsPerMinuteCurrentChart.getAxisLeft();
|
YAxis stepsPerMinuteCurrentYAxis = mStepsPerMinuteCurrentChart.getAxisLeft();
|
||||||
int maxStepsPerMinute = mSteps.getMaxStepsPerMinute();
|
int maxStepsPerMinute = mSteps.getMaxStepsPerMinute();
|
||||||
@ -255,6 +254,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
filterLocal.addAction(DeviceService.ACTION_REALTIME_STEPS);
|
filterLocal.addAction(DeviceService.ACTION_REALTIME_STEPS);
|
||||||
filterLocal.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
|
filterLocal.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
|
||||||
heartRateValues = new ArrayList<>();
|
heartRateValues = new ArrayList<>();
|
||||||
|
tsTranslation = new TimestampTranslation();
|
||||||
|
|
||||||
View rootView = inflater.inflate(R.layout.fragment_live_activity, container, false);
|
View rootView = inflater.inflate(R.layout.fragment_live_activity, container, false);
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
* Called in the UI thread.
|
* Called in the UI thread.
|
||||||
*/
|
*/
|
||||||
private void pulse() {
|
private void pulse() {
|
||||||
addEntries(adjust(System.currentTimeMillis()));
|
addEntries(translateTimestamp(System.currentTimeMillis()));
|
||||||
|
|
||||||
LineData historyData = (LineData) mStepsPerMinuteHistoryChart.getData();
|
LineData historyData = (LineData) mStepsPerMinuteHistoryChart.getData();
|
||||||
if (historyData == null) {
|
if (historyData == null) {
|
||||||
@ -333,7 +333,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
|
|||||||
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(true);
|
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private long getPulseIntervalMillis() {
|
private int getPulseIntervalMillis() {
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user