From 890cae381b2a1b5aa5183d9efa6353819b106c51 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 24 Jan 2022 17:04:14 +0100 Subject: [PATCH] Show IC and ISF graphs too --- .../profile/local/LocalProfileFragment.kt | 10 ++- .../main/res/layout/localprofile_fragment.xml | 46 ++++++++-- .../androidaps/dialogs/ProfileViewerDialog.kt | 4 + .../{ProfileGraph.kt => BasalProfileGraph.kt} | 2 +- .../androidaps/utils/ui/IcProfileGraph.kt | 83 ++++++++++++++++++ .../androidaps/utils/ui/IsfProfileGraph.kt | 85 +++++++++++++++++++ .../main/res/layout/dialog_profileviewer.xml | 14 ++- 7 files changed, 230 insertions(+), 14 deletions(-) rename core/src/main/java/info/nightscout/androidaps/utils/ui/{ProfileGraph.kt => BasalProfileGraph.kt} (98%) create mode 100644 core/src/main/java/info/nightscout/androidaps/utils/ui/IcProfileGraph.kt create mode 100644 core/src/main/java/info/nightscout/androidaps/utils/ui/IsfProfileGraph.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index 1f5e9f82f4..87c6875084 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -59,6 +59,8 @@ class LocalProfileFragment : DaggerFragment() { basalView?.updateLabel(rh.gs(R.string.basal_label) + ": " + sumLabel()) localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let { binding.basalGraph.show(ProfileSealed.Pure(it)) + binding.icGraph.show(ProfileSealed.Pure(it)) + binding.isfGraph.show(ProfileSealed.Pure(it)) } } @@ -128,13 +130,13 @@ class LocalProfileFragment : DaggerFragment() { binding.name.addTextChangedListener(textWatch) binding.dia.setParams(currentProfile.dia, hardLimits.minDia(), hardLimits.maxDia(), 0.1, DecimalFormat("0.0"), false, null, textWatch) binding.dia.tag = "LP_DIA" - TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "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_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 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) if (units == Constants.MGDL) { - TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", rh.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save) + 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) 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) } else { - TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "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) + 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) 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) } @@ -171,6 +173,8 @@ class LocalProfileFragment : DaggerFragment() { }) localProfilePlugin.profile?.getSpecificProfile(spinner?.selectedItem.toString())?.let { binding.basalGraph.show(ProfileSealed.Pure(it)) + binding.icGraph.show(ProfileSealed.Pure(it)) + binding.isfGraph.show(ProfileSealed.Pure(it)) } binding.profileAdd.setOnClickListener { diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml index e66a0c9c62..7b650bcd89 100644 --- a/app/src/main/res/layout/localprofile_fragment.xml +++ b/app/src/main/res/layout/localprofile_fragment.xml @@ -214,17 +214,45 @@ + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + - = ArrayList() + var maxIc = 0.0 + for (hour in 0..23) { + val ic = profile.getIcTimeFromMidnight(hour * 60 * 60) + maxIc = max(maxIc, ic) + icArray.add(DataPoint(hour.toDouble(), ic)) + icArray.add(DataPoint((hour + 1).toDouble(), ic)) + } + val icDataPoints: Array = Array(icArray.size) { i -> icArray[i] } + val icSeries: LineGraphSeries = LineGraphSeries(icDataPoints) + addSeries(icSeries) + icSeries.thickness = 8 + icSeries.isDrawBackground = false + viewport.isXAxisBoundsManual = true + viewport.setMinX(0.0) + viewport.setMaxX(24.0) + viewport.isYAxisBoundsManual = true + viewport.setMinY(0.0) + viewport.setMaxY(Round.ceilTo(maxIc * 1.1, 0.5)) + gridLabelRenderer.numHorizontalLabels = 13 + gridLabelRenderer.verticalLabelsColor = icSeries.color + } + + fun show(profile1: Profile, profile2: Profile) { + removeAllSeries() + + var maxIc = 0.0 + // ic 1 + val icArray1: MutableList = ArrayList() + for (hour in 0..23) { + val ic = profile1.getIcTimeFromMidnight(hour * 60 * 60) + maxIc = max(maxIc, ic) + icArray1.add(DataPoint(hour.toDouble(), ic)) + icArray1.add(DataPoint((hour + 1).toDouble(), ic)) + } + val icSeries1: LineGraphSeries = LineGraphSeries(Array(icArray1.size) { i -> icArray1[i] }) + addSeries(icSeries1) + icSeries1.thickness = 8 + icSeries1.isDrawBackground = false + + // ic 2 + val icArray2: MutableList = ArrayList() + for (hour in 0..23) { + val ic = profile2.getIcTimeFromMidnight(hour * 60 * 60) + maxIc = max(maxIc, ic) + icArray2.add(DataPoint(hour.toDouble(), ic)) + icArray2.add(DataPoint((hour + 1).toDouble(), ic)) + } + val icSeries2: LineGraphSeries = LineGraphSeries(Array(icArray2.size) { i -> icArray2[i] }) + addSeries(icSeries2) + icSeries2.thickness = 8 + icSeries2.isDrawBackground = false + icSeries2.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(maxIc * 1.1, 0.5)) + gridLabelRenderer.numHorizontalLabels = 13 + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/IsfProfileGraph.kt b/core/src/main/java/info/nightscout/androidaps/utils/ui/IsfProfileGraph.kt new file mode 100644 index 0000000000..d48dfd1dc4 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/IsfProfileGraph.kt @@ -0,0 +1,85 @@ +package info.nightscout.androidaps.utils.ui + +import android.content.Context +import android.util.AttributeSet +import com.jjoe64.graphview.GraphView +import com.jjoe64.graphview.series.DataPoint +import com.jjoe64.graphview.series.LineGraphSeries +import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.interfaces.Profile +import info.nightscout.androidaps.utils.Round +import java.util.ArrayList +import kotlin.math.max + +class IsfProfileGraph : GraphView { + + constructor(context: Context?) : super(context) + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) + + fun show(profile: Profile) { + removeAllSeries() + val isfArray: MutableList = ArrayList() + var maxIsf = 0.0 + val units = profile.units + for (hour in 0..23) { + val isf = Profile.fromMgdlToUnits(profile.getIsfMgdlTimeFromMidnight(hour * 60 * 60), units) + maxIsf = max(maxIsf, isf) + isfArray.add(DataPoint(hour.toDouble(), isf)) + isfArray.add(DataPoint((hour + 1).toDouble(), isf)) + } + val isfDataPoints: Array = Array(isfArray.size) { i -> isfArray[i] } + val isfSeries: LineGraphSeries = LineGraphSeries(isfDataPoints) + addSeries(isfSeries) + isfSeries.thickness = 8 + isfSeries.isDrawBackground = false + viewport.isXAxisBoundsManual = true + viewport.setMinX(0.0) + viewport.setMaxX(24.0) + viewport.isYAxisBoundsManual = true + viewport.setMinY(0.0) + viewport.setMaxY(Round.ceilTo(maxIsf * 1.1, 0.5)) + gridLabelRenderer.numHorizontalLabels = 13 + gridLabelRenderer.verticalLabelsColor = isfSeries.color + } + + fun show(profile1: Profile, profile2: Profile) { + removeAllSeries() + + var maxIsf = 0.0 + val units = profile1.units + // isf 1 + val isfArray1: MutableList = ArrayList() + for (hour in 0..23) { + val isf = Profile.fromMgdlToUnits(profile1.getIsfMgdlTimeFromMidnight(hour * 60 * 60), units) + maxIsf = max(maxIsf, isf) + isfArray1.add(DataPoint(hour.toDouble(), isf)) + isfArray1.add(DataPoint((hour + 1).toDouble(), isf)) + } + val isfSeries1: LineGraphSeries = LineGraphSeries(Array(isfArray1.size) { i -> isfArray1[i] }) + addSeries(isfSeries1) + isfSeries1.thickness = 8 + isfSeries1.isDrawBackground = false + + // isf 2 + val isfArray2: MutableList = ArrayList() + for (hour in 0..23) { + val isf = Profile.fromMgdlToUnits(profile2.getIsfMgdlTimeFromMidnight(hour * 60 * 60), units) + maxIsf = max(maxIsf, isf) + isfArray2.add(DataPoint(hour.toDouble(), isf)) + isfArray2.add(DataPoint((hour + 1).toDouble(), isf)) + } + val isfSeries2: LineGraphSeries = LineGraphSeries(Array(isfArray2.size) { i -> isfArray2[i] }) + addSeries(isfSeries2) + isfSeries2.thickness = 8 + isfSeries2.isDrawBackground = false + isfSeries2.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(maxIsf * 1.1, 0.5)) + gridLabelRenderer.numHorizontalLabels = 13 + } +} \ No newline at end of file diff --git a/core/src/main/res/layout/dialog_profileviewer.xml b/core/src/main/res/layout/dialog_profileviewer.xml index 7f02c1457e..880b79aa9b 100644 --- a/core/src/main/res/layout/dialog_profileviewer.xml +++ b/core/src/main/res/layout/dialog_profileviewer.xml @@ -245,6 +245,12 @@ + + + + -