392 lines
15 KiB
Java
392 lines
15 KiB
Java
package info.nightscout.androidaps;
|
|
|
|
import android.app.Activity;
|
|
import android.os.Bundle;
|
|
import android.support.v4.content.res.ResourcesCompat;
|
|
import android.support.v7.app.AppCompatActivity;
|
|
import android.support.v7.widget.PopupMenu;
|
|
import android.text.SpannableString;
|
|
import android.text.style.ForegroundColorSpan;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.widget.Button;
|
|
import android.widget.ImageButton;
|
|
import android.widget.SeekBar;
|
|
import android.widget.TextView;
|
|
|
|
import com.jjoe64.graphview.GraphView;
|
|
import com.squareup.otto.Subscribe;
|
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.util.Calendar;
|
|
|
|
import butterknife.BindView;
|
|
import butterknife.ButterKnife;
|
|
import butterknife.OnClick;
|
|
import butterknife.OnLongClick;
|
|
import info.nightscout.androidaps.data.Profile;
|
|
import info.nightscout.androidaps.events.EventCustomCalculationFinished;
|
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
|
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
|
import info.nightscout.androidaps.plugins.Overview.OverviewFragment;
|
|
import info.nightscout.androidaps.plugins.Overview.OverviewPlugin;
|
|
import info.nightscout.androidaps.plugins.Overview.graphData.GraphData;
|
|
import info.nightscout.utils.DateUtil;
|
|
import info.nightscout.utils.SP;
|
|
|
|
public class HistoryBrowseActivity extends AppCompatActivity {
|
|
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
|
|
|
|
|
|
ImageButton chartButton;
|
|
|
|
boolean showBasal = true;
|
|
boolean showIob, showCob, showDev, showRat;
|
|
|
|
|
|
@BindView(R.id.historybrowse_date)
|
|
Button buttonDate;
|
|
@BindView(R.id.historybrowse_zoom)
|
|
Button buttonZoom;
|
|
@BindView(R.id.historyybrowse_bggraph)
|
|
GraphView bgGraph;
|
|
@BindView(R.id.historybrowse_iobgraph)
|
|
GraphView iobGraph;
|
|
@BindView(R.id.historybrowse_seekBar)
|
|
SeekBar seekBar;
|
|
@BindView(R.id.historybrowse_noprofile)
|
|
TextView noProfile;
|
|
|
|
private int rangeToDisplay = 24; // for graph
|
|
private long start;
|
|
|
|
IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
|
|
|
EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished();
|
|
|
|
public HistoryBrowseActivity() {
|
|
iobCobCalculatorPlugin = new IobCobCalculatorPlugin();
|
|
}
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setContentView(R.layout.activity_historybrowse);
|
|
|
|
ButterKnife.bind(this);
|
|
|
|
bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
|
bgGraph.getGridLabelRenderer().reloadStyles();
|
|
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
|
|
iobGraph.getGridLabelRenderer().reloadStyles();
|
|
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
|
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
|
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
|
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
|
|
|
setupChartMenu();
|
|
|
|
// set start of current day
|
|
Calendar calendar = Calendar.getInstance();
|
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
calendar.set(Calendar.SECOND, 0);
|
|
calendar.set(Calendar.MINUTE, 0);
|
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
start = calendar.getTimeInMillis();
|
|
}
|
|
|
|
@Override
|
|
protected void onResume() {
|
|
super.onResume();
|
|
updateGUI("onResume");
|
|
}
|
|
|
|
|
|
@OnClick(R.id.historybrowse_start)
|
|
void onClickStart() {
|
|
}
|
|
|
|
@OnClick(R.id.historybrowse_left)
|
|
void onClickLeft() {
|
|
start -= rangeToDisplay * 60 * 60 * 1000L;
|
|
updateGUI("left");
|
|
iobCobCalculatorPlugin.clearCache();
|
|
iobCobCalculatorPlugin.runCalculation("onClickLeft", start, true, eventCustomCalculationFinished);
|
|
}
|
|
|
|
@OnClick(R.id.historybrowse_right)
|
|
void onClickRight() {
|
|
start += rangeToDisplay * 60 * 60 * 1000L;
|
|
updateGUI("right");
|
|
iobCobCalculatorPlugin.clearCache();
|
|
iobCobCalculatorPlugin.runCalculation("onClickRight", start, true, eventCustomCalculationFinished);
|
|
}
|
|
|
|
@OnClick(R.id.historybrowse_end)
|
|
void onClickEnd() {
|
|
Calendar calendar = Calendar.getInstance();
|
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
calendar.set(Calendar.SECOND, 0);
|
|
calendar.set(Calendar.MINUTE, 0);
|
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
start = calendar.getTimeInMillis();
|
|
updateGUI("resetToMidnight");
|
|
iobCobCalculatorPlugin.clearCache();
|
|
iobCobCalculatorPlugin.runCalculation("onClickEnd", start, true, eventCustomCalculationFinished);
|
|
}
|
|
|
|
@OnClick(R.id.historybrowse_zoom)
|
|
void onClickZoom() {
|
|
rangeToDisplay += 6;
|
|
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
|
|
updateGUI("rangeChange");
|
|
}
|
|
|
|
@OnLongClick(R.id.historybrowse_zoom)
|
|
boolean onLongClickZoom() {
|
|
Calendar calendar = Calendar.getInstance();
|
|
calendar.setTimeInMillis(start);
|
|
calendar.set(Calendar.MILLISECOND, 0);
|
|
calendar.set(Calendar.SECOND, 0);
|
|
calendar.set(Calendar.MINUTE, 0);
|
|
calendar.set(Calendar.HOUR_OF_DAY, 0);
|
|
start = calendar.getTimeInMillis();
|
|
updateGUI("resetToMidnight");
|
|
iobCobCalculatorPlugin.clearCache();
|
|
iobCobCalculatorPlugin.runCalculation("onLongClickZoom", start, true, eventCustomCalculationFinished);
|
|
return true;
|
|
}
|
|
|
|
@OnClick(R.id.historybrowse_date)
|
|
void onClickDate() {
|
|
}
|
|
|
|
@Subscribe
|
|
public void onStatusEvent(final EventAutosensCalculationFinished e) {
|
|
Activity activity = this;
|
|
if (activity != null && e.cause == eventCustomCalculationFinished) {
|
|
log.debug("EventAutosensCalculationFinished");
|
|
activity.runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
updateGUI("EventAutosensCalculationFinished");
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
void updateGUI(String from) {
|
|
final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
|
|
final Profile profile = MainApp.getConfigBuilder().getProfile();
|
|
|
|
if (profile == null) {
|
|
noProfile.setVisibility(View.VISIBLE);
|
|
return;
|
|
} else {
|
|
noProfile.setVisibility(View.GONE);
|
|
}
|
|
|
|
final String units = profile.getUnits();
|
|
|
|
double lowLineSetting = SP.getDouble("low_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetLow, units));
|
|
double highLineSetting = SP.getDouble("high_mark", Profile.fromMgdlToUnits(OverviewPlugin.bgTargetHigh, units));
|
|
|
|
if (lowLineSetting < 1)
|
|
lowLineSetting = Profile.fromMgdlToUnits(76d, units);
|
|
if (highLineSetting < 1)
|
|
highLineSetting = Profile.fromMgdlToUnits(180d, units);
|
|
|
|
final double lowLine = lowLineSetting;
|
|
final double highLine = highLineSetting;
|
|
|
|
final boolean showPrediction = false;
|
|
|
|
int hoursToFetch;
|
|
final long toTime;
|
|
final long fromTime;
|
|
//if (showPrediction) {
|
|
//int predHours = (int) (Math.ceil(((DetermineBasalResultAMA) finalLastRun.constraintsProcessed).getLatestPredictionsTime() - System.currentTimeMillis()) / (60 * 60 * 1000));
|
|
//predHours = Math.min(2, predHours);
|
|
//predHours = Math.max(0, predHours);
|
|
//hoursToFetch = rangeToDisplay - predHours;
|
|
//toTime = calendar.getTimeInMillis() + 100000; // little bit more to avoid wrong rounding - Graphview specific
|
|
//fromTime = toTime - hoursToFetch * 60 * 60 * 1000L;
|
|
//endTime = toTime + predHours * 60 * 60 * 1000L;
|
|
//} else {
|
|
fromTime = start + 100000;
|
|
toTime = start + rangeToDisplay * 60 * 60 * 1000L;
|
|
//}
|
|
|
|
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
|
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
|
|
|
log.debug("Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime));
|
|
|
|
final long pointer = System.currentTimeMillis();
|
|
|
|
// ------------------ 1st graph
|
|
|
|
final GraphData graphData = new GraphData(bgGraph, IobCobCalculatorPlugin.getPlugin());
|
|
|
|
// **** In range Area ****
|
|
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine);
|
|
|
|
// **** BG ****
|
|
if (showPrediction)
|
|
//graphData.addBgReadings(fromTime, toTime, lowLine, highLine, (DetermineBasalResultAMA) finalLastRun.constraintsProcessed);
|
|
;
|
|
else
|
|
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null);
|
|
|
|
// set manual x bounds to have nice steps
|
|
graphData.formatAxis(fromTime, toTime);
|
|
|
|
// Treatments
|
|
graphData.addTreatments(fromTime, toTime);
|
|
|
|
// add basal data
|
|
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
|
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2d);
|
|
}
|
|
|
|
// **** NOW line ****
|
|
graphData.addNowLine(pointer);
|
|
|
|
// ------------------ 2nd graph
|
|
|
|
final GraphData secondGraphData = new GraphData(iobGraph, iobCobCalculatorPlugin);
|
|
|
|
boolean useIobForScale = false;
|
|
boolean useCobForScale = false;
|
|
boolean useDevForScale = false;
|
|
boolean useRatioForScale = false;
|
|
|
|
if (showIob) {
|
|
useIobForScale = true;
|
|
} else if (showCob) {
|
|
useCobForScale = true;
|
|
} else if (showDev) {
|
|
useDevForScale = true;
|
|
} else if (showRat) {
|
|
useRatioForScale = true;
|
|
}
|
|
|
|
if (showIob)
|
|
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d);
|
|
if (showCob)
|
|
secondGraphData.addCob(fromTime, toTime, useCobForScale, useCobForScale ? 1d : 0.5d);
|
|
if (showDev)
|
|
secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1d);
|
|
if (showRat)
|
|
secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1d);
|
|
|
|
// **** NOW line ****
|
|
// set manual x bounds to have nice steps
|
|
secondGraphData.formatAxis(fromTime, toTime);
|
|
secondGraphData.addNowLine(pointer);
|
|
|
|
// do GUI update
|
|
if (showIob || showCob || showDev || showRat) {
|
|
iobGraph.setVisibility(View.VISIBLE);
|
|
} else {
|
|
iobGraph.setVisibility(View.GONE);
|
|
}
|
|
// finally enforce drawing of graphs
|
|
graphData.performUpdate();
|
|
secondGraphData.performUpdate();
|
|
}
|
|
|
|
private void setupChartMenu() {
|
|
chartButton = (ImageButton) findViewById(R.id.overview_chartMenuButton);
|
|
chartButton.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
MenuItem item;
|
|
CharSequence title;
|
|
SpannableString s;
|
|
PopupMenu popup = new PopupMenu(v.getContext(), v);
|
|
|
|
|
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.BAS.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_basals));
|
|
title = item.getTitle();
|
|
s = new SpannableString(title);
|
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.basal, null)), 0, s.length(), 0);
|
|
item.setTitle(s);
|
|
item.setCheckable(true);
|
|
item.setChecked(showBasal);
|
|
|
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.IOB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_iob));
|
|
title = item.getTitle();
|
|
s = new SpannableString(title);
|
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.iob, null)), 0, s.length(), 0);
|
|
item.setTitle(s);
|
|
item.setCheckable(true);
|
|
item.setChecked(showIob);
|
|
|
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.COB.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_cob));
|
|
title = item.getTitle();
|
|
s = new SpannableString(title);
|
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.cob, null)), 0, s.length(), 0);
|
|
item.setTitle(s);
|
|
item.setCheckable(true);
|
|
item.setChecked(showCob);
|
|
|
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.DEV.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_deviations));
|
|
title = item.getTitle();
|
|
s = new SpannableString(title);
|
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.deviations, null)), 0, s.length(), 0);
|
|
item.setTitle(s);
|
|
item.setCheckable(true);
|
|
item.setChecked(showDev);
|
|
|
|
item = popup.getMenu().add(Menu.NONE, OverviewFragment.CHARTTYPE.SEN.ordinal(), Menu.NONE, MainApp.gs(R.string.overview_show_sensitivity));
|
|
title = item.getTitle();
|
|
s = new SpannableString(title);
|
|
s.setSpan(new ForegroundColorSpan(ResourcesCompat.getColor(getResources(), R.color.ratio, null)), 0, s.length(), 0);
|
|
item.setTitle(s);
|
|
item.setCheckable(true);
|
|
item.setChecked(showRat);
|
|
|
|
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
|
@Override
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
if (item.getItemId() == OverviewFragment.CHARTTYPE.BAS.ordinal()) {
|
|
showBasal = !item.isChecked();
|
|
|
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.IOB.ordinal()) {
|
|
showIob = !item.isChecked();
|
|
|
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.COB.ordinal()) {
|
|
showCob = !item.isChecked();
|
|
|
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.DEV.ordinal()) {
|
|
showDev = !item.isChecked();
|
|
|
|
} else if (item.getItemId() == OverviewFragment.CHARTTYPE.SEN.ordinal()) {
|
|
showRat = !item.isChecked();
|
|
}
|
|
updateGUI("onGraphCheckboxesCheckedChanged");
|
|
return true;
|
|
}
|
|
});
|
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
|
|
popup.setOnDismissListener(new PopupMenu.OnDismissListener() {
|
|
@Override
|
|
public void onDismiss(PopupMenu menu) {
|
|
chartButton.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
|
|
}
|
|
});
|
|
popup.show();
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|