Merge pull request #1292 from Andries-Smit/new-profile-editor
profile editor add DIA and Target Chart
This commit is contained in:
commit
064642339e
13 changed files with 251 additions and 49 deletions
|
@ -18,10 +18,11 @@ class ActivityGraph : GraphView {
|
||||||
|
|
||||||
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
|
||||||
fun show(insulin: Insulin) {
|
fun show(insulin: Insulin, diaSample: Double? = null) {
|
||||||
removeAllSeries()
|
removeAllSeries()
|
||||||
|
val dia = diaSample ?: insulin.dia
|
||||||
mSecondScale = null
|
mSecondScale = null
|
||||||
val hours = floor(insulin.dia + 1).toLong()
|
val hours = floor(dia + 1).toLong()
|
||||||
val bolus = Bolus(
|
val bolus = Bolus(
|
||||||
timestamp = 0,
|
timestamp = 0,
|
||||||
amount = 1.0,
|
amount = 1.0,
|
||||||
|
@ -31,7 +32,7 @@ class ActivityGraph : GraphView {
|
||||||
val iobArray: MutableList<DataPoint> = ArrayList()
|
val iobArray: MutableList<DataPoint> = ArrayList()
|
||||||
var time: Long = 0
|
var time: Long = 0
|
||||||
while (time <= T.hours(hours).msecs()) {
|
while (time <= T.hours(hours).msecs()) {
|
||||||
val iob = insulin.iobCalcForTreatment(bolus, time, insulin.dia)
|
val iob = insulin.iobCalcForTreatment(bolus, time, dia)
|
||||||
activityArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.activityContrib))
|
activityArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.activityContrib))
|
||||||
iobArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.iobContrib))
|
iobArray.add(DataPoint(T.msecs(time).mins().toDouble(), iob.iobContrib))
|
||||||
time += T.mins(5).msecs()
|
time += T.mins(5).msecs()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.profile.local
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
@ -20,7 +21,6 @@ import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
|
||||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.shared.logging.AAPSLogger
|
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||||
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
|
||||||
|
@ -31,8 +31,10 @@ import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.ui.SpinnerHelper
|
import info.nightscout.androidaps.utils.ui.SpinnerHelper
|
||||||
import info.nightscout.androidaps.utils.ui.TimeListEdit
|
import info.nightscout.androidaps.utils.ui.TimeListEdit
|
||||||
import info.nightscout.shared.SafeParse
|
import info.nightscout.shared.SafeParse
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxkotlin.plusAssign
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
|
import java.math.RoundingMode
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -61,6 +63,8 @@ class LocalProfileFragment : DaggerFragment() {
|
||||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||||
binding.icGraph.show(ProfileSealed.Pure(it))
|
binding.icGraph.show(ProfileSealed.Pure(it))
|
||||||
binding.isfGraph.show(ProfileSealed.Pure(it))
|
binding.isfGraph.show(ProfileSealed.Pure(it))
|
||||||
|
binding.targetGraph.show(ProfileSealed.Pure(it))
|
||||||
|
binding.insulinGraph.show(activePlugin.activeInsulin, SafeParse.stringToDouble(binding.dia.text))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,14 +134,22 @@ class LocalProfileFragment : DaggerFragment() {
|
||||||
binding.name.addTextChangedListener(textWatch)
|
binding.name.addTextChangedListener(textWatch)
|
||||||
binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, null, textWatch)
|
binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, null, textWatch)
|
||||||
binding.dia.tag = "LP_DIA"
|
binding.dia.tag = "LP_DIA"
|
||||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic_holder, "IC", rh.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
|
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic_holder, "IC", rh.gs(R.string.ic_long_label), currentProfile.ic, null, doubleArrayOf(hardLimits.minIC(), hardLimits.maxIC()), null, 0.1, DecimalFormat ("0.0"), save)
|
||||||
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", rh.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, pumpDescription.basalMaximumRate, 0.01, DecimalFormat("0.00"), save)
|
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal_holder, "BASAL", rh.gs(R.string.basal_long_label) + ": " + sumLabel(), currentProfile.basal, null, doubleArrayOf(pumpDescription.basalMinimumRate, pumpDescription.basalMaximumRate), null, 0.01, DecimalFormat("0.00"), save)
|
||||||
if (units == Constants.MGDL) {
|
if (units == Constants.MGDL) {
|
||||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf_holder, "ISF", rh.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
|
val isfRange = doubleArrayOf(HardLimits.MIN_ISF, HardLimits.MAX_ISF)
|
||||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", rh.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1], 1.0, DecimalFormat("0"), save)
|
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf_holder, "ISF", rh.gs(R.string.isf_long_label), currentProfile.isf, null, isfRange , null, 1.0, DecimalFormat("0"), save)
|
||||||
|
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target_holder, "TARGET", rh.gs(R.string.target_long_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_MIN_BG, HardLimits.VERY_HARD_LIMIT_TARGET_BG, 1.0, DecimalFormat("0"), save)
|
||||||
} else {
|
} else {
|
||||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf_holder, "ISF", rh.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL), Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL), 0.1, DecimalFormat("0.0"), save)
|
val isfRange = doubleArrayOf(roundUp(Profile.fromMgdlToUnits(HardLimits.MIN_ISF, GlucoseUnit.MMOL)),
|
||||||
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", rh.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], GlucoseUnit.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1], GlucoseUnit.MMOL), 0.1, DecimalFormat("0.0"), save)
|
roundDown(Profile.fromMgdlToUnits(HardLimits.MAX_ISF, GlucoseUnit.MMOL)))
|
||||||
|
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf_holder, "ISF", rh.gs(R.string.isf_long_label), currentProfile.isf, null,isfRange , null, 0.1, DecimalFormat("0.0"), save)
|
||||||
|
val range1 = doubleArrayOf(roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[0], GlucoseUnit.MMOL)),
|
||||||
|
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MIN_BG[1], GlucoseUnit.MMOL)))
|
||||||
|
val range2 = doubleArrayOf(roundUp(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[0], GlucoseUnit.MMOL)),
|
||||||
|
roundDown(Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_MAX_BG[1], GlucoseUnit.MMOL)))
|
||||||
|
Log.i("TimeListEdit", "build: range1" + range1[0] + " " + range1[1] + " range2" + range2[0] + " " + range2[1])
|
||||||
|
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target_holder, "TARGET", rh.gs(R.string.target_long_label), currentProfile.targetLow, currentProfile.targetHigh, range1 , range2, 0.1, DecimalFormat("0.0"), save)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spinner
|
// Spinner
|
||||||
|
@ -175,6 +187,8 @@ class LocalProfileFragment : DaggerFragment() {
|
||||||
binding.basalGraph.show(ProfileSealed.Pure(it))
|
binding.basalGraph.show(ProfileSealed.Pure(it))
|
||||||
binding.icGraph.show(ProfileSealed.Pure(it))
|
binding.icGraph.show(ProfileSealed.Pure(it))
|
||||||
binding.isfGraph.show(ProfileSealed.Pure(it))
|
binding.isfGraph.show(ProfileSealed.Pure(it))
|
||||||
|
binding.targetGraph.show(ProfileSealed.Pure(it))
|
||||||
|
binding.insulinGraph.show(activePlugin.activeInsulin, SafeParse.stringToDouble(binding.dia.text))
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.profileAdd.setOnClickListener {
|
binding.profileAdd.setOnClickListener {
|
||||||
|
@ -265,6 +279,14 @@ class LocalProfileFragment : DaggerFragment() {
|
||||||
updateGUI()
|
updateGUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun roundUp(number: Double): Double {
|
||||||
|
return number.toBigDecimal().setScale(1, RoundingMode.UP).toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun roundDown(number: Double): Double {
|
||||||
|
return number.toBigDecimal().setScale(1, RoundingMode.DOWN).toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateGUI() {
|
private fun updateGUI() {
|
||||||
if (_binding == null) return
|
if (_binding == null) return
|
||||||
val isValid = localProfilePlugin.isValidEditState(activity)
|
val isValid = localProfilePlugin.isValidEditState(activity)
|
||||||
|
|
|
@ -57,6 +57,8 @@ public class TimeListEdit {
|
||||||
private final double step;
|
private final double step;
|
||||||
private final double min;
|
private final double min;
|
||||||
private final double max;
|
private final double max;
|
||||||
|
private final double min2;
|
||||||
|
private final double max2;
|
||||||
private final NumberFormat formatter;
|
private final NumberFormat formatter;
|
||||||
private final Runnable save;
|
private final Runnable save;
|
||||||
private LinearLayout layout;
|
private LinearLayout layout;
|
||||||
|
@ -68,7 +70,7 @@ public class TimeListEdit {
|
||||||
Context context,
|
Context context,
|
||||||
AAPSLogger aapsLogger,
|
AAPSLogger aapsLogger,
|
||||||
DateUtil dateUtil,
|
DateUtil dateUtil,
|
||||||
View view, int resLayoutId, String tagPrefix, String label, JSONArray data1, JSONArray data2, double min, double max, double step, NumberFormat formatter, Runnable save) {
|
View view, int resLayoutId, String tagPrefix, String label, JSONArray data1, JSONArray data2, double[] range1, double[] range2, double step, NumberFormat formatter, Runnable save) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.aapsLogger = aapsLogger;
|
this.aapsLogger = aapsLogger;
|
||||||
this.dateUtil = dateUtil;
|
this.dateUtil = dateUtil;
|
||||||
|
@ -79,8 +81,10 @@ public class TimeListEdit {
|
||||||
this.data1 = data1;
|
this.data1 = data1;
|
||||||
this.data2 = data2;
|
this.data2 = data2;
|
||||||
this.step = step;
|
this.step = step;
|
||||||
this.min = min;
|
this.min = range1[0];
|
||||||
this.max = max;
|
this.max = range1[1];
|
||||||
|
this.min2 = range2 != null ? range2[0] : 0;
|
||||||
|
this.max2 = range2 != null ? range2[1] : 0;
|
||||||
this.formatter = formatter;
|
this.formatter = formatter;
|
||||||
this.save = save;
|
this.save = save;
|
||||||
buildView();
|
buildView();
|
||||||
|
@ -177,7 +181,13 @@ public class TimeListEdit {
|
||||||
numberPickers1[position].setTextWatcher(new TextWatcher() {
|
numberPickers1[position].setTextWatcher(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
editItem(position, secondFromMidnight(position), SafeParse.stringToDouble(numberPickers1[position].getText()), value2(position));
|
Double value1 = SafeParse.stringToDouble(numberPickers1[position].getText());
|
||||||
|
Double value2 = value2(position);
|
||||||
|
if (data2 != null && value1 > value2) {
|
||||||
|
value2 = value1;
|
||||||
|
numberPickers2[position].setValue(value2);
|
||||||
|
}
|
||||||
|
editItem(position, secondFromMidnight(position), value1, value2);
|
||||||
callSave();
|
callSave();
|
||||||
log();
|
log();
|
||||||
}
|
}
|
||||||
|
@ -197,7 +207,13 @@ public class TimeListEdit {
|
||||||
numberPickers2[position].setTextWatcher(new TextWatcher() {
|
numberPickers2[position].setTextWatcher(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
editItem(position, secondFromMidnight(position), value1(position), SafeParse.stringToDouble(numberPickers2[position].getText()));
|
Double value1 = value1(position);
|
||||||
|
Double value2 = SafeParse.stringToDouble(numberPickers2[position].getText());
|
||||||
|
if (data2 != null && value2 < value1) {
|
||||||
|
value1 = value2;
|
||||||
|
numberPickers1[position].setValue(value1);
|
||||||
|
}
|
||||||
|
editItem(position, secondFromMidnight(position), value1, value2);
|
||||||
callSave();
|
callSave();
|
||||||
log();
|
log();
|
||||||
}
|
}
|
||||||
|
@ -246,7 +262,7 @@ public class TimeListEdit {
|
||||||
fillSpinner(timeSpinner, secondFromMidnight(i), previous, next);
|
fillSpinner(timeSpinner, secondFromMidnight(i), previous, next);
|
||||||
|
|
||||||
editText1.setParams(value1(i), min, max, step, formatter, false, null);
|
editText1.setParams(value1(i), min, max, step, formatter, false, null);
|
||||||
editText2.setParams(value2(i), min, max, step, formatter, false, null);
|
editText2.setParams(value2(i), min2, max2, step, formatter, false, null);
|
||||||
|
|
||||||
if (data2 == null) {
|
if (data2 == null) {
|
||||||
editText2.setVisibility(View.GONE);
|
editText2.setVisibility(View.GONE);
|
||||||
|
|
|
@ -35,6 +35,40 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="2dip"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:layout_marginBottom="5dp"
|
||||||
|
android:background="@color/list_delimiter" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:labelFor="@+id/name"
|
||||||
|
android:text="@string/profile_name"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:ems="10"
|
||||||
|
android:importantForAutofill="no"
|
||||||
|
android:inputType="text" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
@ -152,32 +186,13 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="10dp"
|
android:gravity="center_horizontal"
|
||||||
android:orientation="horizontal">
|
android:text="@string/dia_label"
|
||||||
|
android:textColor="@android:color/white"
|
||||||
<TextView
|
android:textSize="20sp" />
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:layout_marginBottom="10dp"
|
|
||||||
android:labelFor="@+id/name"
|
|
||||||
android:text="@string/profile_name"
|
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
|
||||||
|
|
||||||
<EditText
|
|
||||||
android:id="@+id/name"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginStart="10dp"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:ems="10"
|
|
||||||
android:importantForAutofill="no"
|
|
||||||
android:inputType="text" />
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -210,6 +225,12 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<info.nightscout.androidaps.plugins.insulin.ActivityGraph
|
||||||
|
android:id="@+id/insulin_graph"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dip"
|
||||||
|
android:layout_margin="20dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -277,10 +298,22 @@
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/target"
|
android:id="@+id/target"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/target_holder"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_marginBottom="10dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
<info.nightscout.androidaps.utils.ui.TargetBgProfileGraph
|
||||||
|
android:id="@+id/target_graph"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dip"
|
||||||
|
android:layout_margin="20dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -151,6 +151,7 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
||||||
binding.basalGraph.show(profile1, profile2)
|
binding.basalGraph.show(profile1, profile2)
|
||||||
binding.isfGraph.show(profile1, profile2)
|
binding.isfGraph.show(profile1, profile2)
|
||||||
binding.icGraph.show(profile1, profile2)
|
binding.icGraph.show(profile1, profile2)
|
||||||
|
binding.targetGraph.show(profile1, profile2)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.noprofile.visibility = View.GONE
|
binding.noprofile.visibility = View.GONE
|
||||||
|
@ -171,6 +172,7 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
||||||
binding.basalGraph.show(it)
|
binding.basalGraph.show(it)
|
||||||
binding.isfGraph.show(it)
|
binding.isfGraph.show(it)
|
||||||
binding.icGraph.show(it)
|
binding.icGraph.show(it)
|
||||||
|
binding.targetGraph.show(it)
|
||||||
|
|
||||||
binding.noprofile.visibility = View.GONE
|
binding.noprofile.visibility = View.GONE
|
||||||
val validity = it.isValid("ProfileViewDialog", activePlugin.activePump, config, rh, rxBus, hardLimits, false)
|
val validity = it.isValid("ProfileViewDialog", activePlugin.activePump, config, rh, rxBus, hardLimits, false)
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class AreaGraphSeries<E extends DoubleDataPoint> extends BaseSeries<E> {
|
||||||
/**
|
/**
|
||||||
* the thickness of the line.
|
* the thickness of the line.
|
||||||
* This option will be ignored if you are
|
* This option will be ignored if you are
|
||||||
* using a custom paint via {@link #setCustomPaint(android.graphics.Paint)}
|
* using a custom paint via {@link #setCustomPaint(Paint)}
|
||||||
*/
|
*/
|
||||||
private int thickness = 5;
|
private int thickness = 5;
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ public class AreaGraphSeries<E extends DoubleDataPoint> extends BaseSeries<E> {
|
||||||
/**
|
/**
|
||||||
* the thickness of the line.
|
* the thickness of the line.
|
||||||
* This option will be ignored if you are
|
* This option will be ignored if you are
|
||||||
* using a custom paint via {@link #setCustomPaint(android.graphics.Paint)}
|
* using a custom paint via {@link #setCustomPaint(Paint)}
|
||||||
*
|
*
|
||||||
* @return the thickness of the line
|
* @return the thickness of the line
|
||||||
*/
|
*/
|
||||||
|
@ -353,7 +353,7 @@ public class AreaGraphSeries<E extends DoubleDataPoint> extends BaseSeries<E> {
|
||||||
/**
|
/**
|
||||||
* the thickness of the line.
|
* the thickness of the line.
|
||||||
* This option will be ignored if you are
|
* This option will be ignored if you are
|
||||||
* using a custom paint via {@link #setCustomPaint(android.graphics.Paint)}
|
* using a custom paint via {@link #setCustomPaint(Paint)}
|
||||||
*
|
*
|
||||||
* @param thickness thickness of the line
|
* @param thickness thickness of the line
|
||||||
*/
|
*/
|
|
@ -2,12 +2,14 @@ package info.nightscout.androidaps.utils.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import com.jjoe64.graphview.DefaultLabelFormatter
|
||||||
import com.jjoe64.graphview.GraphView
|
import com.jjoe64.graphview.GraphView
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
import com.jjoe64.graphview.series.LineGraphSeries
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
import info.nightscout.androidaps.core.R
|
import info.nightscout.androidaps.core.R
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import java.text.NumberFormat
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
|
@ -36,6 +38,10 @@ class BasalProfileGraph : GraphView {
|
||||||
viewport.setMaxY(Round.ceilTo(profile.getMaxDailyBasal() * 1.1, 0.5))
|
viewport.setMaxY(Round.ceilTo(profile.getMaxDailyBasal() * 1.1, 0.5))
|
||||||
gridLabelRenderer.numHorizontalLabels = 13
|
gridLabelRenderer.numHorizontalLabels = 13
|
||||||
gridLabelRenderer.verticalLabelsColor = basalSeries.color
|
gridLabelRenderer.verticalLabelsColor = basalSeries.color
|
||||||
|
|
||||||
|
val nf: NumberFormat = NumberFormat.getInstance()
|
||||||
|
nf.maximumFractionDigits = 1
|
||||||
|
gridLabelRenderer.setLabelFormatter(DefaultLabelFormatter(nf, nf))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun show(profile1: Profile, profile2: Profile) {
|
fun show(profile1: Profile, profile2: Profile) {
|
||||||
|
|
|
@ -2,12 +2,14 @@ package info.nightscout.androidaps.utils.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import com.jjoe64.graphview.DefaultLabelFormatter
|
||||||
import com.jjoe64.graphview.GraphView
|
import com.jjoe64.graphview.GraphView
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
import com.jjoe64.graphview.series.LineGraphSeries
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
import info.nightscout.androidaps.core.R
|
import info.nightscout.androidaps.core.R
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import java.text.NumberFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
|
@ -39,6 +41,10 @@ class IcProfileGraph : GraphView {
|
||||||
viewport.setMaxY(Round.ceilTo(maxIc * 1.1, 0.5))
|
viewport.setMaxY(Round.ceilTo(maxIc * 1.1, 0.5))
|
||||||
gridLabelRenderer.numHorizontalLabels = 13
|
gridLabelRenderer.numHorizontalLabels = 13
|
||||||
gridLabelRenderer.verticalLabelsColor = icSeries.color
|
gridLabelRenderer.verticalLabelsColor = icSeries.color
|
||||||
|
|
||||||
|
val nf: NumberFormat = NumberFormat.getInstance()
|
||||||
|
nf.maximumFractionDigits = 1
|
||||||
|
gridLabelRenderer.setLabelFormatter(DefaultLabelFormatter(nf, nf))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun show(profile1: Profile, profile2: Profile) {
|
fun show(profile1: Profile, profile2: Profile) {
|
||||||
|
|
|
@ -2,13 +2,14 @@ package info.nightscout.androidaps.utils.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import com.jjoe64.graphview.DefaultLabelFormatter
|
||||||
import com.jjoe64.graphview.GraphView
|
import com.jjoe64.graphview.GraphView
|
||||||
import com.jjoe64.graphview.series.DataPoint
|
import com.jjoe64.graphview.series.DataPoint
|
||||||
import com.jjoe64.graphview.series.LineGraphSeries
|
import com.jjoe64.graphview.series.LineGraphSeries
|
||||||
import info.nightscout.androidaps.core.R
|
import info.nightscout.androidaps.core.R
|
||||||
import info.nightscout.androidaps.interfaces.Profile
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
import info.nightscout.androidaps.utils.Round
|
import info.nightscout.androidaps.utils.Round
|
||||||
import java.util.ArrayList
|
import java.text.NumberFormat
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
class IsfProfileGraph : GraphView {
|
class IsfProfileGraph : GraphView {
|
||||||
|
@ -31,15 +32,20 @@ class IsfProfileGraph : GraphView {
|
||||||
val isfSeries: LineGraphSeries<DataPoint> = LineGraphSeries(isfDataPoints)
|
val isfSeries: LineGraphSeries<DataPoint> = LineGraphSeries(isfDataPoints)
|
||||||
addSeries(isfSeries)
|
addSeries(isfSeries)
|
||||||
isfSeries.thickness = 8
|
isfSeries.thickness = 8
|
||||||
isfSeries.isDrawBackground = false
|
|
||||||
viewport.isXAxisBoundsManual = true
|
viewport.isXAxisBoundsManual = true
|
||||||
viewport.setMinX(0.0)
|
viewport.setMinX(0.0)
|
||||||
viewport.setMaxX(24.0)
|
viewport.setMaxX(24.0)
|
||||||
viewport.isYAxisBoundsManual = true
|
viewport.isYAxisBoundsManual = true
|
||||||
viewport.setMinY(0.0)
|
viewport.setMinY(0.0)
|
||||||
viewport.setMaxY(Round.ceilTo(maxIsf * 1.1, 0.5))
|
val maxY = Round.ceilTo(maxIsf * 1.1, 0.5)
|
||||||
|
viewport.setMaxY(maxY)
|
||||||
gridLabelRenderer.numHorizontalLabels = 13
|
gridLabelRenderer.numHorizontalLabels = 13
|
||||||
|
gridLabelRenderer.labelVerticalWidth = 40
|
||||||
gridLabelRenderer.verticalLabelsColor = isfSeries.color
|
gridLabelRenderer.verticalLabelsColor = isfSeries.color
|
||||||
|
|
||||||
|
val nf: NumberFormat = NumberFormat.getInstance()
|
||||||
|
nf.maximumFractionDigits = 1
|
||||||
|
gridLabelRenderer.setLabelFormatter(DefaultLabelFormatter(nf, nf))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun show(profile1: Profile, profile2: Profile) {
|
fun show(profile1: Profile, profile2: Profile) {
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
package info.nightscout.androidaps.utils.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import com.jjoe64.graphview.DefaultLabelFormatter
|
||||||
|
import com.jjoe64.graphview.GraphView
|
||||||
|
import info.nightscout.androidaps.core.R
|
||||||
|
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.utils.Round
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.AreaGraphSeries
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DoubleDataPoint
|
||||||
|
import java.text.NumberFormat
|
||||||
|
import java.util.ArrayList
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class TargetBgProfileGraph : GraphView {
|
||||||
|
|
||||||
|
constructor(context: Context?) : super(context)
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
|
||||||
|
|
||||||
|
fun show(profile: Profile) {
|
||||||
|
|
||||||
|
removeAllSeries()
|
||||||
|
val targetArray: MutableList<DoubleDataPoint> = ArrayList()
|
||||||
|
var maxValue = 0.0
|
||||||
|
val units = profile.units
|
||||||
|
for (hour in 0..23) {
|
||||||
|
val valueLow = Profile.fromMgdlToUnits(profile.getTargetLowMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
val valueHigh = Profile.fromMgdlToUnits(profile.getTargetHighMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
maxValue = max(maxValue, valueHigh)
|
||||||
|
targetArray.add(DoubleDataPoint(hour.toDouble(), valueLow, valueHigh))
|
||||||
|
targetArray.add(DoubleDataPoint((hour + 1).toDouble(), valueLow, valueHigh))
|
||||||
|
}
|
||||||
|
val targetDataPoints: Array<DoubleDataPoint> = Array(targetArray.size) { i -> targetArray[i] }
|
||||||
|
val targetSeries: AreaGraphSeries<DoubleDataPoint> = AreaGraphSeries(targetDataPoints)
|
||||||
|
addSeries(targetSeries)
|
||||||
|
targetSeries.isDrawBackground = true
|
||||||
|
|
||||||
|
viewport.isXAxisBoundsManual = true
|
||||||
|
viewport.setMinX(0.0)
|
||||||
|
viewport.setMaxX(24.0)
|
||||||
|
viewport.isYAxisBoundsManual = true
|
||||||
|
viewport.setMinY(0.0)
|
||||||
|
viewport.setMaxY(Round.ceilTo(maxValue * 1.1, 0.5))
|
||||||
|
gridLabelRenderer.numHorizontalLabels = 13
|
||||||
|
gridLabelRenderer.verticalLabelsColor = targetSeries.color
|
||||||
|
|
||||||
|
val nf: NumberFormat = NumberFormat.getInstance()
|
||||||
|
nf.maximumFractionDigits = if (units == GlucoseUnit.MMOL) 1 else 0
|
||||||
|
gridLabelRenderer.setLabelFormatter(DefaultLabelFormatter(nf, nf))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun show(profile1: Profile, profile2: Profile) {
|
||||||
|
|
||||||
|
removeAllSeries()
|
||||||
|
val targetArray1: MutableList<DoubleDataPoint> = ArrayList()
|
||||||
|
var maxValue = 0.0
|
||||||
|
val units = profile1.units
|
||||||
|
for (hour in 0..23) {
|
||||||
|
val valueLow = Profile.fromMgdlToUnits(profile1.getTargetLowMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
val valueHigh = Profile.fromMgdlToUnits(profile1.getTargetHighMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
maxValue = max(maxValue, valueHigh)
|
||||||
|
targetArray1.add(DoubleDataPoint(hour.toDouble(), valueLow, valueHigh))
|
||||||
|
targetArray1.add(DoubleDataPoint((hour + 1).toDouble(), valueLow, valueHigh))
|
||||||
|
}
|
||||||
|
val targetDataPoints1: Array<DoubleDataPoint> = Array(targetArray1.size) { i -> targetArray1[i] }
|
||||||
|
val targetSeries1: AreaGraphSeries<DoubleDataPoint> = AreaGraphSeries(targetDataPoints1)
|
||||||
|
addSeries(targetSeries1)
|
||||||
|
targetSeries1.isDrawBackground = true
|
||||||
|
|
||||||
|
val targetArray2: MutableList<DoubleDataPoint> = ArrayList()
|
||||||
|
for (hour in 0..23) {
|
||||||
|
val valueLow = Profile.fromMgdlToUnits(profile2.getTargetLowMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
val valueHigh = Profile.fromMgdlToUnits(profile2.getTargetHighMgdlTimeFromMidnight(hour * 60 * 60), units)
|
||||||
|
maxValue = max(maxValue, valueHigh)
|
||||||
|
targetArray2.add(DoubleDataPoint(hour.toDouble(), valueLow, valueHigh))
|
||||||
|
targetArray2.add(DoubleDataPoint((hour + 1).toDouble(), valueLow, valueHigh))
|
||||||
|
}
|
||||||
|
val targetDataPoints2: Array<DoubleDataPoint> = Array(targetArray2.size) { i -> targetArray2[i] }
|
||||||
|
val targetSeries2: AreaGraphSeries<DoubleDataPoint> = AreaGraphSeries(targetDataPoints2)
|
||||||
|
addSeries(targetSeries2)
|
||||||
|
targetSeries2.isDrawBackground = false
|
||||||
|
targetSeries2.color = context.getColor(R.color.examinedProfile)
|
||||||
|
|
||||||
|
viewport.isXAxisBoundsManual = true
|
||||||
|
viewport.setMinX(0.0)
|
||||||
|
viewport.setMaxX(24.0)
|
||||||
|
viewport.isYAxisBoundsManual = true
|
||||||
|
viewport.setMinY(0.0)
|
||||||
|
viewport.setMaxY(Round.ceilTo(maxValue * 1.1, 0.5))
|
||||||
|
gridLabelRenderer.numHorizontalLabels = 13
|
||||||
|
gridLabelRenderer.verticalLabelsColor = targetSeries1.color
|
||||||
|
|
||||||
|
val nf: NumberFormat = NumberFormat.getInstance()
|
||||||
|
nf.maximumFractionDigits = if (units == GlucoseUnit.MMOL) 1 else 0
|
||||||
|
gridLabelRenderer.setLabelFormatter(DefaultLabelFormatter(nf, nf))
|
||||||
|
}
|
||||||
|
}
|
|
@ -434,6 +434,12 @@
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<info.nightscout.androidaps.utils.ui.TargetBgProfileGraph
|
||||||
|
android:id="@+id/target_graph"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="100dip"
|
||||||
|
android:layout_margin="20dp" />
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/close_layout"
|
android:id="@+id/close_layout"
|
||||||
layout="@layout/close" />
|
layout="@layout/close" />
|
||||||
|
|
|
@ -111,6 +111,11 @@
|
||||||
<string name="isf_label">ISF</string>
|
<string name="isf_label">ISF</string>
|
||||||
<string name="basal_label">Basal</string>
|
<string name="basal_label">Basal</string>
|
||||||
<string name="target_label">Target</string>
|
<string name="target_label">Target</string>
|
||||||
|
<string name="dia_long_label">Duration of Insulin Action</string>
|
||||||
|
<string name="ic_long_label">Insulin to Carb ratio</string>
|
||||||
|
<string name="isf_long_label">Insulin Sensitivity Factor</string>
|
||||||
|
<string name="basal_long_label">Basel rate</string>
|
||||||
|
<string name="target_long_label">Blood Glucose Target</string>
|
||||||
<string name="initializing">Initializing ...</string>
|
<string name="initializing">Initializing ...</string>
|
||||||
<string name="serialnumber">Serial number</string>
|
<string name="serialnumber">Serial number</string>
|
||||||
<string name="battery_label">Battery</string>
|
<string name="battery_label">Battery</string>
|
||||||
|
|
Loading…
Reference in a new issue