Make timestamp to mpandroidchart float x-value explicit

master
cpfeiffer 2016-10-08 11:16:40 +02:00
parent 125c0092cb
commit c2ff05e849
2 changed files with 58 additions and 37 deletions

View File

@ -411,7 +411,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
protected DefaultChartsData<CombinedData> refresh(GBDevice gbDevice, List<? extends ActivitySample> samples) {
// Calendar cal = GregorianCalendar.getInstance();
// cal.clear();
int tsOffset = 0;
TimestampTranslation tsTranslation = new TimestampTranslation();
// Date date;
// String dateStringFrom = "";
// String dateStringTo = "";
@ -435,13 +435,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
for (int i = 0; i < numEntries; i++) {
ActivitySample sample = samples.get(i);
int type = sample.getKind();
int ts;
if (i == 0) {
tsOffset = sample.getTimestamp();
ts = 0;
} else {
ts = sample.getTimestamp() - tsOffset;
}
int ts = tsTranslation.shorten(sample.getTimestamp());
// System.out.println(ts);
// ts = i;
@ -541,7 +535,7 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
combinedData = new CombinedData();
}
IAxisValueFormatter xValueFormatter = new SampleXLabelFormatter(tsOffset);
IAxisValueFormatter xValueFormatter = new SampleXLabelFormatter(tsTranslation);
return new DefaultChartsData(combinedData, xValueFormatter);
}
@ -750,13 +744,13 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
}
protected static class SampleXLabelFormatter implements IAxisValueFormatter {
private final int tsOffset;
private final TimestampTranslation tsTranslation;
SimpleDateFormat annotationDateFormat = new SimpleDateFormat("HH:mm");
// SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy HH:mm");
Calendar cal = GregorianCalendar.getInstance();
public SampleXLabelFormatter(int tsOffset) {
this.tsOffset = tsOffset;
public SampleXLabelFormatter(TimestampTranslation tsTranslation) {
this.tsTranslation = tsTranslation;
}
// 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) {
cal.clear();
int ts = (int) value;
cal.setTimeInMillis((ts + tsOffset) * 1000L);
cal.setTimeInMillis(tsTranslation.toOriginalValue(ts) * 1000L);
Date date = cal.getTime();
String dateString = annotationDateFormat.format(date);
return dateString;
@ -797,4 +791,31 @@ public abstract class AbstractChartFragment extends AbstractGBFragment {
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;
}
}
}

View File

@ -69,13 +69,13 @@ public class LiveActivityFragment extends AbstractChartFragment {
private List<Measurement> heartRateValues;
private LineDataSet mHeartRateSet;
private int mHeartRate;
private long tsOffset = -1;
private TimestampTranslation tsTranslation;
private class Steps {
private int initialSteps;
private int steps;
private long lastTimestamp;
private int lastTimestamp;
private int currentStepsPerMinute;
private int maxStepsPerMinute;
private int lastStepsPerMinute;
@ -97,7 +97,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
return maxStepsPerMinute;
}
public void updateCurrentSteps(int newSteps, long timestamp) {
public void updateCurrentSteps(int newSteps, int timestamp) {
try {
if (steps == 0) {
steps = newSteps;
@ -111,7 +111,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
if (newSteps >= steps) {
int stepsDelta = newSteps - steps;
long timeDelta = timestamp - lastTimestamp;
int timeDelta = timestamp - lastTimestamp;
currentStepsPerMinute = calculateStepsPerMinute(stepsDelta, timeDelta);
if (currentStepsPerMinute > maxStepsPerMinute) {
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) {
return 0; // not walking or not enough data per mills?
}
if (millis <= 0) {
throw new IllegalArgumentException("delta in millis is <= 0 -- time change?");
if (seconds <= 0) {
throw new IllegalArgumentException("delta in seconds is <= 0 -- time change?");
}
long oneMinute = 60 * 1000;
float factor = oneMinute / millis;
int oneMinute = 60 * 1000;
float factor = oneMinute / seconds;
int result = (int) (stepsDelta * factor);
if (result > MAX_STEPS_PER_MINUTE) {
// ignore, return previous value instead
@ -154,15 +154,13 @@ public class LiveActivityFragment extends AbstractChartFragment {
switch (action) {
case DeviceService.ACTION_REALTIME_STEPS: {
int steps = intent.getIntExtra(DeviceService.EXTRA_REALTIME_STEPS, 0);
long timestamp = intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
timestamp = adjust(timestamp);
int timestamp = translateTimestampFrom(intent);
addEntries(steps, timestamp);
break;
}
case DeviceService.ACTION_HEARTRATE_MEASUREMENT: {
int heartRate = intent.getIntExtra(DeviceService.EXTRA_HEART_RATE_VALUE, 0);
long timestamp = intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis());
timestamp = adjust(timestamp);
int timestamp = translateTimestampFrom(intent);
if (isValidHeartRateValue(heartRate)) {
setCurrentHeartRate(heartRate, timestamp);
}
@ -172,15 +170,16 @@ public class LiveActivityFragment extends AbstractChartFragment {
}
};
private long adjust(long timestamp) {
if (tsOffset == -1) {
tsOffset = timestamp;
return 0;
}
return timestamp - tsOffset;
private int translateTimestampFrom(Intent intent) {
return translateTimestamp(intent.getLongExtra(DeviceService.EXTRA_TIMESTAMP, System.currentTimeMillis()));
}
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);
mHeartRate = heartRate;
}
@ -191,7 +190,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
return result;
}
private void addEntries(int steps, long timestamp) {
private void addEntries(int steps, int timestamp) {
mSteps.updateCurrentSteps(steps, timestamp);
if (++maxStepsResetCounter > RESET_COUNT) {
maxStepsResetCounter = 0;
@ -203,7 +202,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
// addEntries();
}
private void addEntries(long timestamp) {
private void addEntries(int timestamp) {
mTotalStepsChart.setSingleEntryYValue(mSteps.getTotalSteps());
YAxis stepsPerMinuteCurrentYAxis = mStepsPerMinuteCurrentChart.getAxisLeft();
int maxStepsPerMinute = mSteps.getMaxStepsPerMinute();
@ -255,6 +254,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
filterLocal.addAction(DeviceService.ACTION_REALTIME_STEPS);
filterLocal.addAction(DeviceService.ACTION_HEARTRATE_MEASUREMENT);
heartRateValues = new ArrayList<>();
tsTranslation = new TimestampTranslation();
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.
*/
private void pulse() {
addEntries(adjust(System.currentTimeMillis()));
addEntries(translateTimestamp(System.currentTimeMillis()));
LineData historyData = (LineData) mStepsPerMinuteHistoryChart.getData();
if (historyData == null) {
@ -333,7 +333,7 @@ public class LiveActivityFragment extends AbstractChartFragment {
GBApplication.deviceService().onEnableRealtimeHeartRateMeasurement(true);
}
private long getPulseIntervalMillis() {
private int getPulseIntervalMillis() {
return 1000;
}