HistoryBrowser refactor
This commit is contained in:
parent
55ecac882d
commit
daa8fa62be
3 changed files with 356 additions and 427 deletions
|
@ -1,378 +0,0 @@
|
|||
package info.nightscout.androidaps.historyBrowser;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
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 androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import com.jjoe64.graphview.GraphView;
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished;
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction;
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment;
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
public class HistoryBrowseActivity extends NoSplashAppCompatActivity {
|
||||
@Inject HasAndroidInjector injector;
|
||||
@Inject AAPSLogger aapsLogger;
|
||||
@Inject RxBusWrapper rxBus;
|
||||
@Inject SP sp;
|
||||
@Inject ResourceHelper resourceHelper;
|
||||
@Inject ProfileFunction profileFunction;
|
||||
@Inject DefaultValueHelper defaultValueHelper;
|
||||
@Inject IobCobStaticCalculatorPlugin iobCobStaticCalculatorPlugin;
|
||||
@Inject ActivePluginProvider activePlugin;
|
||||
@Inject BuildHelper buildHelper;
|
||||
@Inject FabricPrivacy fabricPrivacy;
|
||||
@Inject OverviewMenus overviewMenus;
|
||||
|
||||
private CompositeDisposable disposable = new CompositeDisposable();
|
||||
|
||||
ImageButton chartButton;
|
||||
|
||||
boolean showBasal = true;
|
||||
boolean showIob, showCob, showDev, showRat, showActPrim, showActSec, showDevslope;
|
||||
|
||||
|
||||
Button buttonDate;
|
||||
Button buttonZoom;
|
||||
GraphView bgGraph;
|
||||
GraphView iobGraph;
|
||||
SeekBar seekBar;
|
||||
TextView noProfile;
|
||||
TextView iobCalculationProgressView;
|
||||
|
||||
private int rangeToDisplay = 24; // for graph
|
||||
private long start = 0;
|
||||
|
||||
|
||||
EventCustomCalculationFinished eventCustomCalculationFinished = new EventCustomCalculationFinished();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_historybrowse);
|
||||
|
||||
buttonDate = findViewById(R.id.historybrowse_date);
|
||||
buttonZoom = findViewById(R.id.historybrowse_zoom);
|
||||
bgGraph = findViewById(R.id.historyybrowse_bggraph);
|
||||
iobGraph = findViewById(R.id.historybrowse_iobgraph);
|
||||
seekBar = findViewById(R.id.historybrowse_seekBar);
|
||||
noProfile = findViewById(R.id.historybrowse_noprofile);
|
||||
iobCalculationProgressView = findViewById(R.id.overview_iobcalculationprogess);
|
||||
|
||||
findViewById(R.id.historybrowse_left).setOnClickListener(v -> {
|
||||
start -= T.hours(rangeToDisplay).msecs();
|
||||
updateGUI("onClickLeft");
|
||||
runCalculation("onClickLeft");
|
||||
});
|
||||
|
||||
findViewById(R.id.historybrowse_right).setOnClickListener(v -> {
|
||||
start += T.hours(rangeToDisplay).msecs();
|
||||
updateGUI("onClickRight");
|
||||
runCalculation("onClickRight");
|
||||
});
|
||||
|
||||
findViewById(R.id.historybrowse_end).setOnClickListener(v -> {
|
||||
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("onClickEnd");
|
||||
runCalculation("onClickEnd");
|
||||
});
|
||||
|
||||
findViewById(R.id.historybrowse_zoom).setOnClickListener(v -> {
|
||||
rangeToDisplay += 6;
|
||||
rangeToDisplay = rangeToDisplay > 24 ? 6 : rangeToDisplay;
|
||||
updateGUI("rangeChange");
|
||||
});
|
||||
|
||||
findViewById(R.id.historybrowse_zoom).setOnLongClickListener(v -> {
|
||||
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");
|
||||
runCalculation("onLongClickZoom");
|
||||
return true;
|
||||
});
|
||||
|
||||
findViewById(R.id.historybrowse_date).setOnClickListener(v -> {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date(start));
|
||||
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||
(view, year, monthOfYear, dayOfMonth) -> {
|
||||
Date date = new Date(0);
|
||||
date.setYear(year - 1900);
|
||||
date.setMonth(monthOfYear);
|
||||
date.setDate(dayOfMonth);
|
||||
date.setHours(0);
|
||||
start = date.getTime();
|
||||
updateGUI("onClickDate");
|
||||
runCalculation("onClickDate");
|
||||
},
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
dpd.show(getSupportFragmentManager(), "Datepickerdialog");
|
||||
});
|
||||
|
||||
bgGraph.getGridLabelRenderer().setGridColor(resourceHelper.gc(R.color.graphgrid));
|
||||
bgGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setGridColor(resourceHelper.gc(R.color.graphgrid));
|
||||
iobGraph.getGridLabelRenderer().reloadStyles();
|
||||
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
|
||||
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50);
|
||||
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
|
||||
|
||||
overviewMenus.setupChartMenu(findViewById(R.id.overview_chartMenuButton));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
disposable.clear();
|
||||
iobCobStaticCalculatorPlugin.stopCalculation("onPause");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAutosensCalculationFinished.class)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(event -> {
|
||||
if (event.getCause() == eventCustomCalculationFinished) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, "EventAutosensCalculationFinished");
|
||||
synchronized (HistoryBrowseActivity.this) {
|
||||
updateGUI("EventAutosensCalculationFinished");
|
||||
}
|
||||
}
|
||||
}, fabricPrivacy::logException)
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventIobCalculationProgress.class)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(event -> {
|
||||
if (iobCalculationProgressView != null)
|
||||
iobCalculationProgressView.setText(event.getProgress());
|
||||
}, exception -> fabricPrivacy.logException(exception))
|
||||
);
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventRefreshOverview.class)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(event -> updateGUI("EventRefreshOverview") , fabricPrivacy::logException)
|
||||
);
|
||||
// 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();
|
||||
runCalculation("onResume");
|
||||
SystemClock.sleep(1000);
|
||||
updateGUI("onResume");
|
||||
}
|
||||
|
||||
private void runCalculation(String from) {
|
||||
long end = start + T.hours(rangeToDisplay).msecs();
|
||||
iobCobStaticCalculatorPlugin.stopCalculation(from);
|
||||
iobCobStaticCalculatorPlugin.clearCache();
|
||||
iobCobStaticCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished);
|
||||
}
|
||||
|
||||
void updateGUI(String from) {
|
||||
aapsLogger.debug(LTag.UI, "updateGUI from: " + from);
|
||||
|
||||
if (noProfile == null || buttonDate == null || buttonZoom == null || bgGraph == null || iobGraph == null || seekBar == null)
|
||||
return;
|
||||
|
||||
final PumpInterface pump = activePlugin.getActivePump();
|
||||
final Profile profile = profileFunction.getProfile();
|
||||
|
||||
if (profile == null) {
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
} else {
|
||||
noProfile.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final double lowLine = defaultValueHelper.determineLowLine();
|
||||
final double highLine = defaultValueHelper.determineHighLine();
|
||||
|
||||
buttonDate.setText(DateUtil.dateAndTimeString(start));
|
||||
buttonZoom.setText(String.valueOf(rangeToDisplay));
|
||||
|
||||
final boolean showPrediction = false;
|
||||
|
||||
showBasal = sp.getBoolean("hist_showbasals", true);
|
||||
showIob = sp.getBoolean("hist_showiob", true);
|
||||
showCob = sp.getBoolean("hist_showcob", true);
|
||||
showDev = sp.getBoolean("hist_showdeviations", false);
|
||||
showRat = sp.getBoolean("hist_showratios", false);
|
||||
showActPrim = sp.getBoolean("hist_showactivityprimary", false);
|
||||
showActSec = sp.getBoolean("hist_showactivitysecondary", false);
|
||||
showDevslope = sp.getBoolean("hist_showdevslope", 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 + T.secs(100).msecs();
|
||||
toTime = start + T.hours(rangeToDisplay).msecs();
|
||||
//}
|
||||
|
||||
aapsLogger.debug(LTag.UI, "Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime));
|
||||
|
||||
final long pointer = System.currentTimeMillis();
|
||||
|
||||
// ------------------ 1st graph
|
||||
|
||||
final GraphData graphData = new GraphData(injector, bgGraph, iobCobStaticCalculatorPlugin);
|
||||
|
||||
// **** 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);
|
||||
|
||||
if (showActPrim) {
|
||||
graphData.addActivity(fromTime, toTime, false, 1d);
|
||||
}
|
||||
|
||||
// Treatments
|
||||
graphData.addTreatments(fromTime, toTime);
|
||||
|
||||
// add basal data
|
||||
if (pump.getPumpDescription().isTempBasalCapable && showBasal) {
|
||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.getMaxY() / 1.2d);
|
||||
}
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(pointer);
|
||||
|
||||
// ------------------ 2nd graph
|
||||
|
||||
new Thread(() -> {
|
||||
final GraphData secondGraphData = new GraphData(injector, iobGraph, iobCobStaticCalculatorPlugin);
|
||||
|
||||
boolean useIobForScale = false;
|
||||
boolean useCobForScale = false;
|
||||
boolean useDevForScale = false;
|
||||
boolean useRatioForScale = false;
|
||||
boolean useIAForScale = false;
|
||||
boolean useDSForScale = false;
|
||||
|
||||
if (showIob) {
|
||||
useIobForScale = true;
|
||||
} else if (showCob) {
|
||||
useCobForScale = true;
|
||||
} else if (showDev) {
|
||||
useDevForScale = true;
|
||||
} else if (showRat) {
|
||||
useRatioForScale = true;
|
||||
} else if (showActSec) {
|
||||
useIAForScale = true;
|
||||
} else if (showDevslope) {
|
||||
useDSForScale = true;
|
||||
}
|
||||
|
||||
if (showIob)
|
||||
secondGraphData.addIob(fromTime, toTime, useIobForScale, 1d, showPrediction);
|
||||
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);
|
||||
if (showActSec)
|
||||
secondGraphData.addActivity(fromTime, toTime, useIAForScale, useIAForScale ? 2d : 1d);
|
||||
if (showDevslope)
|
||||
secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1d);
|
||||
|
||||
// **** NOW line ****
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime);
|
||||
secondGraphData.addNowLine(pointer);
|
||||
|
||||
// do GUI update
|
||||
runOnUiThread(() -> {
|
||||
if (showIob || showCob || showDev || showRat || showActSec || showDevslope) {
|
||||
iobGraph.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraph.setVisibility(View.GONE);
|
||||
}
|
||||
// finally enforce drawing of graphs
|
||||
graphData.performUpdate();
|
||||
if (showIob || showCob || showDev || showRat || showActSec || showDevslope)
|
||||
secondGraphData.performUpdate();
|
||||
});
|
||||
}).start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,330 @@
|
|||
package info.nightscout.androidaps.historyBrowser
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.SystemClock
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.jjoe64.graphview.GraphView
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.NoSplashAppCompatActivity
|
||||
import info.nightscout.androidaps.events.EventCustomCalculationFinished
|
||||
import info.nightscout.androidaps.events.EventRefreshOverview
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.general.overview.OverviewMenus
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphData.GraphData
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.activity_historybrowse.*
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class HistoryBrowseActivity : NoSplashAppCompatActivity() {
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||
@Inject lateinit var iobCobStaticCalculatorPlugin: IobCobStaticCalculatorPlugin
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var buildHelper: BuildHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var overviewMenus: OverviewMenus
|
||||
|
||||
private val disposable = CompositeDisposable()
|
||||
|
||||
private val secondaryGraphs = ArrayList<GraphView>()
|
||||
private val secondaryGraphsLabel = ArrayList<TextView>()
|
||||
|
||||
private var axisWidth: Int = 0
|
||||
private var rangeToDisplay = 24 // for graph
|
||||
private var start: Long = 0
|
||||
|
||||
private var eventCustomCalculationFinished = EventCustomCalculationFinished()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_historybrowse)
|
||||
|
||||
historybrowse_left.setOnClickListener {
|
||||
start -= T.hours(rangeToDisplay.toLong()).msecs()
|
||||
updateGUI("onClickLeft")
|
||||
runCalculation("onClickLeft")
|
||||
}
|
||||
historybrowse_right.setOnClickListener {
|
||||
start += T.hours(rangeToDisplay.toLong()).msecs()
|
||||
updateGUI("onClickRight")
|
||||
runCalculation("onClickRight")
|
||||
}
|
||||
historybrowse_end.setOnClickListener {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
updateGUI("onClickEnd")
|
||||
runCalculation("onClickEnd")
|
||||
}
|
||||
historybrowse_zoom.setOnClickListener {
|
||||
rangeToDisplay += 6
|
||||
rangeToDisplay = if (rangeToDisplay > 24) 6 else rangeToDisplay
|
||||
updateGUI("rangeChange")
|
||||
}
|
||||
historybrowse_zoom.setOnLongClickListener {
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = start
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
updateGUI("resetToMidnight")
|
||||
runCalculation("onLongClickZoom")
|
||||
true
|
||||
}
|
||||
|
||||
// create an OnDateSetListener
|
||||
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = start
|
||||
cal.set(Calendar.YEAR, year)
|
||||
cal.set(Calendar.MONTH, monthOfYear)
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||
start = cal.timeInMillis
|
||||
historybrowse_date?.text = DateUtil.dateAndTimeString(start)
|
||||
updateGUI("onClickDate")
|
||||
runCalculation("onClickDate")
|
||||
}
|
||||
|
||||
historybrowse_date.setOnClickListener {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = start
|
||||
DatePickerDialog(this, dateSetListener,
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
|
||||
val dm = DisplayMetrics()
|
||||
windowManager?.defaultDisplay?.getMetrics(dm)
|
||||
|
||||
axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80
|
||||
historybrowse_bggraph?.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
|
||||
historybrowse_bggraph?.gridLabelRenderer?.reloadStyles()
|
||||
historybrowse_bggraph?.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
|
||||
overviewMenus.setupChartMenu(overview_chartMenuButton)
|
||||
prepareGraphs()
|
||||
}
|
||||
|
||||
public override fun onPause() {
|
||||
super.onPause()
|
||||
disposable.clear()
|
||||
iobCobStaticCalculatorPlugin.stopCalculation("onPause")
|
||||
}
|
||||
|
||||
public override fun onResume() {
|
||||
super.onResume()
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventAutosensCalculationFinished::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ event: EventAutosensCalculationFinished ->
|
||||
// catch only events from iobCobStaticCalculatorPlugin
|
||||
if (event.cause === eventCustomCalculationFinished) {
|
||||
aapsLogger.debug(LTag.AUTOSENS, "EventAutosensCalculationFinished")
|
||||
updateGUI("EventAutosensCalculationFinished")
|
||||
}
|
||||
}) { fabricPrivacy::logException }
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventIobCalculationProgress::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({ overview_iobcalculationprogess?.text = it.progress }) { fabricPrivacy::logException }
|
||||
)
|
||||
disposable.add(rxBus
|
||||
.toObservable(EventRefreshOverview::class.java)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe({
|
||||
prepareGraphs()
|
||||
updateGUI("EventRefreshOverview")
|
||||
}) { fabricPrivacy::logException }
|
||||
)
|
||||
// set start of current day
|
||||
val calendar = Calendar.getInstance()
|
||||
calendar.timeInMillis = System.currentTimeMillis()
|
||||
calendar[Calendar.MILLISECOND] = 0
|
||||
calendar[Calendar.SECOND] = 0
|
||||
calendar[Calendar.MINUTE] = 0
|
||||
calendar[Calendar.HOUR_OF_DAY] = 0
|
||||
start = calendar.timeInMillis
|
||||
runCalculation("onResume")
|
||||
SystemClock.sleep(1000)
|
||||
updateGUI("onResume")
|
||||
}
|
||||
|
||||
private fun prepareGraphs() {
|
||||
val numOfGraphs = overviewMenus.setting.size
|
||||
|
||||
if (numOfGraphs != secondaryGraphs.size - 1) {
|
||||
//aapsLogger.debug("New secondary graph count ${numOfGraphs-1}")
|
||||
// rebuild needed
|
||||
secondaryGraphs.clear()
|
||||
secondaryGraphsLabel.clear()
|
||||
history_iobgraph.removeAllViews()
|
||||
for (i in 1 until numOfGraphs) {
|
||||
val label = TextView(this)
|
||||
label.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT).also { it.setMargins(100, 0, 0, -50) }
|
||||
history_iobgraph.addView(label)
|
||||
secondaryGraphsLabel.add(label)
|
||||
val graph = GraphView(this)
|
||||
graph.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resourceHelper.dpToPx(100)).also { it.setMargins(0, 0, 0, resourceHelper.dpToPx(10)) }
|
||||
graph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid)
|
||||
graph.gridLabelRenderer?.reloadStyles()
|
||||
graph.gridLabelRenderer?.isHorizontalLabelsVisible = false
|
||||
graph.gridLabelRenderer?.labelVerticalWidth = axisWidth
|
||||
graph.gridLabelRenderer?.numVerticalLabels = 3
|
||||
graph.viewport.backgroundColor = Color.argb(20, 255, 255, 255) // 8% of gray
|
||||
history_iobgraph.addView(graph)
|
||||
secondaryGraphs.add(graph)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun runCalculation(from: String) {
|
||||
val end = start + T.hours(rangeToDisplay.toLong()).msecs()
|
||||
iobCobStaticCalculatorPlugin.stopCalculation(from)
|
||||
iobCobStaticCalculatorPlugin.clearCache()
|
||||
iobCobStaticCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun updateGUI(from: String) {
|
||||
aapsLogger.debug(LTag.UI, "updateGUI from: $from")
|
||||
val pump = activePlugin.activePump
|
||||
val profile = profileFunction.getProfile()
|
||||
|
||||
historybrowse_noprofile?.visibility = (profile == null).toVisibility()
|
||||
profile ?: return
|
||||
|
||||
val lowLine = defaultValueHelper.determineLowLine()
|
||||
val highLine = defaultValueHelper.determineHighLine()
|
||||
historybrowse_date?.text = DateUtil.dateAndTimeString(start)
|
||||
historybrowse_zoom?.text = rangeToDisplay.toString()
|
||||
|
||||
GlobalScope.launch(Dispatchers.Main) {
|
||||
historybrowse_bggraph ?: return@launch
|
||||
val graphData = GraphData(injector, historybrowse_bggraph, iobCobStaticCalculatorPlugin)
|
||||
val secondaryGraphsData: ArrayList<GraphData> = ArrayList()
|
||||
|
||||
// do preparation in different thread
|
||||
withContext(Dispatchers.Default) {
|
||||
val fromTime: Long = start + T.secs(100).msecs()
|
||||
val toTime: Long = start + T.hours(rangeToDisplay.toLong()).msecs()
|
||||
aapsLogger.debug(LTag.UI, "Period: " + DateUtil.dateAndTimeString(fromTime) + " - " + DateUtil.dateAndTimeString(toTime))
|
||||
val pointer = System.currentTimeMillis()
|
||||
|
||||
// **** In range Area ****
|
||||
graphData.addInRangeArea(fromTime, toTime, lowLine, highLine)
|
||||
|
||||
// **** BG ****
|
||||
graphData.addBgReadings(fromTime, toTime, lowLine, highLine, null)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
graphData.formatAxis(fromTime, toTime)
|
||||
|
||||
// Treatments
|
||||
graphData.addTreatments(fromTime, toTime)
|
||||
if (overviewMenus.setting[0][OverviewMenus.CharType.ACT.ordinal])
|
||||
graphData.addActivity(fromTime, toTime, false, 0.8)
|
||||
|
||||
// add basal data
|
||||
if (pump.pumpDescription.isTempBasalCapable && overviewMenus.setting[0][OverviewMenus.CharType.BAS.ordinal]) {
|
||||
graphData.addBasals(fromTime, toTime, lowLine / graphData.maxY / 1.2)
|
||||
}
|
||||
|
||||
// add target line
|
||||
graphData.addTargetLine(fromTime, toTime, profile, null)
|
||||
|
||||
// **** NOW line ****
|
||||
graphData.addNowLine(pointer)
|
||||
|
||||
// ------------------ 2nd graph
|
||||
for (g in 0 until secondaryGraphs.size) {
|
||||
val secondGraphData = GraphData(injector, secondaryGraphs[g], iobCobStaticCalculatorPlugin)
|
||||
var useIobForScale = false
|
||||
var useCobForScale = false
|
||||
var useDevForScale = false
|
||||
var useRatioForScale = false
|
||||
var useDSForScale = false
|
||||
var useIAForScale = false
|
||||
var useABSForScale = false
|
||||
when {
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] -> useIobForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] -> useCobForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] -> useDevForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] -> useRatioForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] -> useIAForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] -> useABSForScale = true
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] -> useDSForScale = true
|
||||
}
|
||||
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal]) secondGraphData.addIob(fromTime, toTime, useIobForScale, 1.0, overviewMenus.setting[g + 1][OverviewMenus.CharType.PRE.ordinal])
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal]) secondGraphData.addCob(fromTime, toTime, useCobForScale, if (useCobForScale) 1.0 else 0.5)
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal]) secondGraphData.addDeviations(fromTime, toTime, useDevForScale, 1.0)
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal]) secondGraphData.addRatio(fromTime, toTime, useRatioForScale, 1.0)
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal]) secondGraphData.addActivity(fromTime, toTime, useIAForScale, 0.8)
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal]) secondGraphData.addAbsIob(fromTime, toTime, useABSForScale, 1.0)
|
||||
if (overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal] && buildHelper.isDev()) secondGraphData.addDeviationSlope(fromTime, toTime, useDSForScale, 1.0)
|
||||
|
||||
// set manual x bounds to have nice steps
|
||||
secondGraphData.formatAxis(fromTime, toTime)
|
||||
secondGraphData.addNowLine(pointer)
|
||||
secondaryGraphsData.add(secondGraphData)
|
||||
}
|
||||
}
|
||||
// finally enforce drawing of graphs in UI thread
|
||||
graphData.performUpdate()
|
||||
for (g in 0 until secondaryGraphs.size) {
|
||||
secondaryGraphsLabel[g].text = overviewMenus.enabledTypes(g + 1)
|
||||
secondaryGraphs[g].visibility = (
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.IOB.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.COB.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEV.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.SEN.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.ACT.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.ABS.ordinal] ||
|
||||
overviewMenus.setting[g + 1][OverviewMenus.CharType.DEVSLOPE.ordinal]
|
||||
).toVisibility()
|
||||
secondaryGraphsData[g].performUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,11 +61,6 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -77,7 +72,7 @@
|
|||
android:layout_weight="1">
|
||||
|
||||
<com.jjoe64.graphview.GraphView
|
||||
android:id="@+id/historyybrowse_bggraph"
|
||||
android:id="@+id/historybrowse_bggraph"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
|
@ -85,8 +80,8 @@
|
|||
android:id="@+id/overview_chartMenuButton"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:paddingTop="5dp"
|
||||
app:srcCompat="@drawable/ic_arrow_drop_down_white_24dp" />
|
||||
|
||||
|
@ -99,32 +94,14 @@
|
|||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.jjoe64.graphview.GraphView
|
||||
android:id="@+id/historybrowse_iobgraph"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="100dp" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/historybrowse_seekBar"
|
||||
<LinearLayout
|
||||
android:id="@+id/history_iobgraph"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"/>
|
||||
android:orientation="vertical" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</ScrollView>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue