Profile comparator
This commit is contained in:
parent
ceaa3c8750
commit
b91f8e668a
|
@ -8,9 +8,9 @@ import info.nightscout.androidaps.R
|
|||
import info.nightscout.androidaps.data.defaultProfile.DefaultProfile
|
||||
import info.nightscout.androidaps.dialogs.ProfileViewerDialog
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.InstanceId
|
||||
|
@ -62,16 +62,19 @@ class SurveyActivity : NoSplashAppCompatActivity() {
|
|||
ToastUtils.showToastInUiThread(this, R.string.invalidweight)
|
||||
return@setOnClickListener
|
||||
}
|
||||
val profile = defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
|
||||
val args = Bundle()
|
||||
args.putLong("time", DateUtil.now())
|
||||
args.putInt("mode", ProfileViewerDialog.Mode.CUSTOM_PROFILE.ordinal)
|
||||
args.putString("customProfile", profile.data.toString())
|
||||
args.putString("customProfileUnits", profile.units)
|
||||
args.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
|
||||
val pvd = ProfileViewerDialog()
|
||||
pvd.arguments = args
|
||||
pvd.show(supportFragmentManager, "ProfileViewDialog")
|
||||
profileFunction.getProfile()?.let { runningProfile ->
|
||||
val profile = defaultProfile.profile(age, tdd, weight, profileFunction.getUnits())
|
||||
ProfileViewerDialog().also { pvd ->
|
||||
pvd.arguments = Bundle().also {
|
||||
it.putLong("time", DateUtil.now())
|
||||
it.putInt("mode", ProfileViewerDialog.Mode.PROFILE_COMPARE.ordinal)
|
||||
it.putString("customProfile", runningProfile.data.toString())
|
||||
it.putString("customProfile2", profile.data.toString())
|
||||
it.putString("customProfileUnits", profile.units)
|
||||
it.putString("customProfileName", "Age: $age TDD: $tdd Weight: $weight")
|
||||
}
|
||||
}.show(supportFragmentManager, "ProfileViewDialog")
|
||||
}
|
||||
}
|
||||
|
||||
survey_submit.setOnClickListener {
|
||||
|
|
|
@ -370,7 +370,7 @@ public class Profile {
|
|||
return lastValue;
|
||||
}
|
||||
|
||||
protected String format_HH_MM(Integer timeAsSeconds) {
|
||||
public static String format_HH_MM(Integer timeAsSeconds) {
|
||||
String time;
|
||||
int hour = timeAsSeconds / 60 / 60;
|
||||
int minutes = (timeAsSeconds - hour * 60 * 60) / 60;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -14,10 +15,12 @@ import info.nightscout.androidaps.data.Profile
|
|||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.HtmlHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import kotlinx.android.synthetic.main.close.*
|
||||
import kotlinx.android.synthetic.main.dialog_profileviewer.*
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
import javax.inject.Inject
|
||||
|
||||
class ProfileViewerDialog : DaggerDialogFragment() {
|
||||
|
@ -32,11 +35,13 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
enum class Mode(val i: Int) {
|
||||
RUNNING_PROFILE(1),
|
||||
CUSTOM_PROFILE(2),
|
||||
DB_PROFILE(3)
|
||||
DB_PROFILE(3),
|
||||
PROFILE_COMPARE(4)
|
||||
}
|
||||
|
||||
private var mode: Mode = Mode.RUNNING_PROFILE
|
||||
private var customProfileJson: String = ""
|
||||
private var customProfileJson2: String = ""
|
||||
private var customProfileName: String = ""
|
||||
private var customProfileUnits: String = Constants.MGDL
|
||||
|
||||
|
@ -49,6 +54,8 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
customProfileJson = bundle.getString("customProfile", "")
|
||||
customProfileUnits = bundle.getString("customProfileUnits", Constants.MGDL)
|
||||
customProfileName = bundle.getString("customProfileName", "")
|
||||
if (mode == Mode.PROFILE_COMPARE)
|
||||
customProfileJson2 = bundle.getString("customProfile2", "")
|
||||
}
|
||||
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
|
@ -65,11 +72,13 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
close.setOnClickListener { dismiss() }
|
||||
|
||||
val profile: Profile?
|
||||
val profile2: Profile?
|
||||
val profileName: String?
|
||||
val date: String?
|
||||
when (mode) {
|
||||
Mode.RUNNING_PROFILE -> {
|
||||
profile = activePlugin.activeTreatments.getProfileSwitchFromHistory(time)?.profileObject
|
||||
profile2 = null
|
||||
profileName = activePlugin.activeTreatments.getProfileSwitchFromHistory(time)?.customizedName
|
||||
date = dateUtil.dateAndTimeString(activePlugin.activeTreatments.getProfileSwitchFromHistory(time)?.date
|
||||
?: 0)
|
||||
|
@ -78,6 +87,15 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
|
||||
Mode.CUSTOM_PROFILE -> {
|
||||
profile = Profile(injector, JSONObject(customProfileJson), customProfileUnits)
|
||||
profile2 = null
|
||||
profileName = customProfileName
|
||||
date = ""
|
||||
profileview_datelayout.visibility = View.GONE
|
||||
}
|
||||
|
||||
Mode.PROFILE_COMPARE -> {
|
||||
profile = Profile(injector, JSONObject(customProfileJson), customProfileUnits)
|
||||
profile2 = Profile(injector, JSONObject(customProfileJson2), customProfileUnits)
|
||||
profileName = customProfileName
|
||||
date = ""
|
||||
profileview_datelayout.visibility = View.GONE
|
||||
|
@ -86,6 +104,7 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
Mode.DB_PROFILE -> {
|
||||
val profileList = databaseHelper.getProfileSwitchData(time, true)
|
||||
profile = if (profileList.isNotEmpty()) profileList[0].profileObject else null
|
||||
profile2 = null
|
||||
profileName = if (profileList.isNotEmpty()) profileList[0].customizedName else null
|
||||
date = if (profileList.isNotEmpty()) dateUtil.dateAndTimeString(profileList[0].date) else null
|
||||
profileview_datelayout.visibility = View.VISIBLE
|
||||
|
@ -93,20 +112,38 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
}
|
||||
profileview_noprofile.visibility = View.VISIBLE
|
||||
|
||||
profile?.let {
|
||||
profileview_units.text = it.units
|
||||
profileview_dia.text = resourceHelper.gs(R.string.format_hours, it.dia)
|
||||
profileview_activeprofile.text = profileName
|
||||
profileview_date.text = date
|
||||
profileview_ic.text = it.icList
|
||||
profileview_isf.text = it.isfList
|
||||
profileview_basal.text = it.basalList
|
||||
profileview_target.text = it.targetList
|
||||
basal_graph.show(it)
|
||||
if (mode == Mode.PROFILE_COMPARE)
|
||||
profile?.let { profile1 ->
|
||||
profile2?.let { profile2 ->
|
||||
profileview_units.text = profile1.units
|
||||
profileview_dia.text = HtmlHelper.fromHtml(formatColors("", profile1.dia, profile1.dia, DecimalFormat("0.00"), resourceHelper.gs(R.string.shorthour)))
|
||||
profileview_activeprofile.text = profileName
|
||||
profileview_date.text = date
|
||||
profileview_ic.text = ics(profile1, profile2)
|
||||
profileview_isf.text = isfs(profile1, profile2)
|
||||
profileview_basal.text = basals(profile1, profile2)
|
||||
profileview_target.text = HtmlHelper.fromHtml(formatColors("", profile1.targetList + "<br>", profile2.targetList, ""))
|
||||
basal_graph.show(profile1, profile2)
|
||||
}
|
||||
|
||||
profileview_noprofile.visibility = View.GONE
|
||||
profileview_invalidprofile.visibility = if (it.isValid("ProfileViewDialog")) View.GONE else View.VISIBLE
|
||||
}
|
||||
profileview_noprofile.visibility = View.GONE
|
||||
profileview_invalidprofile.visibility = if (profile1.isValid("ProfileViewDialog")) View.GONE else View.VISIBLE
|
||||
}
|
||||
else
|
||||
profile?.let {
|
||||
profileview_units.text = it.units
|
||||
profileview_dia.text = resourceHelper.gs(R.string.format_hours, it.dia)
|
||||
profileview_activeprofile.text = profileName
|
||||
profileview_date.text = date
|
||||
profileview_ic.text = it.icList
|
||||
profileview_isf.text = it.isfList
|
||||
profileview_basal.text = it.basalList
|
||||
profileview_target.text = it.targetList
|
||||
basal_graph.show(it)
|
||||
|
||||
profileview_noprofile.visibility = View.GONE
|
||||
profileview_invalidprofile.visibility = if (it.isValid("ProfileViewDialog")) View.GONE else View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -121,6 +158,79 @@ class ProfileViewerDialog : DaggerDialogFragment() {
|
|||
bundle.putString("customProfile", customProfileJson)
|
||||
bundle.putString("customProfileName", customProfileName)
|
||||
bundle.putString("customProfileUnits", customProfileUnits)
|
||||
if (mode == Mode.PROFILE_COMPARE)
|
||||
bundle.putString("customProfile2", customProfileJson2)
|
||||
}
|
||||
|
||||
private fun formatColors(label: String, value1: Double, value2: Double, format: DecimalFormat, units: String): String {
|
||||
return formatColors(label, format.format(value1), format.format(value2), units)
|
||||
}
|
||||
|
||||
private fun formatColors(label: String, text1: String, text2: String, units: String): String {
|
||||
var s = "<font color='${resourceHelper.gc(R.color.white)}'>$label</font>"
|
||||
s += " "
|
||||
s += "<font color='${resourceHelper.gc(R.color.tempbasal)}'>$text1</font>"
|
||||
s += " "
|
||||
s += "<font color='${resourceHelper.gc(R.color.examinedProfile)}'>$text2</font>"
|
||||
s += " "
|
||||
s += "<font color='${resourceHelper.gc(R.color.white)}'>$units</font>"
|
||||
return s
|
||||
}
|
||||
|
||||
private fun basals(profile1: Profile, profile2: Profile): Spanned {
|
||||
var prev1 = 0.0
|
||||
var prev2 = 0.0
|
||||
val s = StringBuilder()
|
||||
for (hour in 0..23) {
|
||||
val val1 = profile1.getBasalTimeFromMidnight(hour * 60 * 60)
|
||||
val val2 = profile2.getBasalTimeFromMidnight(hour * 60 * 60)
|
||||
if (val1 != prev1 || val2 != prev2) {
|
||||
s.append(formatColors(Profile.format_HH_MM(hour * 60 * 60), val1, val2, DecimalFormat("0.00"), resourceHelper.gs(R.string.profile_ins_units_per_hour)))
|
||||
s.append("<br>")
|
||||
}
|
||||
prev1 = val1
|
||||
prev2 = val2
|
||||
}
|
||||
s.append(formatColors(
|
||||
" ∑ ",
|
||||
profile1.baseBasalSum(),
|
||||
profile2.baseBasalSum(),
|
||||
DecimalFormat("0.00"),
|
||||
resourceHelper.gs(R.string.insulin_unit_shortname)))
|
||||
return HtmlHelper.fromHtml(s.toString())
|
||||
}
|
||||
|
||||
private fun ics(profile1: Profile, profile2: Profile): Spanned {
|
||||
var prev1 = 0.0
|
||||
var prev2 = 0.0
|
||||
val s = StringBuilder()
|
||||
for (hour in 0..23) {
|
||||
val val1 = profile1.getIcTimeFromMidnight(hour * 60 * 60)
|
||||
val val2 = profile2.getIcTimeFromMidnight(hour * 60 * 60)
|
||||
if (val1 != prev1 || val2 != prev2) {
|
||||
s.append(formatColors(Profile.format_HH_MM(hour * 60 * 60), val1, val2, DecimalFormat("0.0"), resourceHelper.gs(R.string.profile_carbs_per_unit)))
|
||||
s.append("<br>")
|
||||
}
|
||||
prev1 = val1
|
||||
prev2 = val2
|
||||
}
|
||||
return HtmlHelper.fromHtml(s.toString())
|
||||
}
|
||||
|
||||
private fun isfs(profile1: Profile, profile2: Profile): Spanned {
|
||||
var prev1 = 0.0
|
||||
var prev2 = 0.0
|
||||
val s = StringBuilder()
|
||||
for (hour in 0..23) {
|
||||
val val1 = Profile.fromMgdlToUnits(profile1.getIsfMgdlTimeFromMidnight(hour * 60 * 60), profile1.units)
|
||||
val val2 = Profile.fromMgdlToUnits(profile2.getIsfMgdlTimeFromMidnight(hour * 60 * 60), profile1.units)
|
||||
if (val1 != prev1 || val2 != prev2) {
|
||||
s.append(formatColors(Profile.format_HH_MM(hour * 60 * 60), val1, val2, DecimalFormat("0.0"), resourceHelper.gs(R.string.profile_carbs_per_unit)))
|
||||
s.append("<br>")
|
||||
}
|
||||
prev1 = val1
|
||||
prev2 = val2
|
||||
}
|
||||
return HtmlHelper.fromHtml(s.toString())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package info.nightscout.androidaps.plugins.treatments.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
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.data.Profile
|
||||
import info.nightscout.androidaps.utils.Round
|
||||
import java.util.*
|
||||
import kotlin.math.max
|
||||
|
||||
class ProfileGraph : GraphView {
|
||||
|
||||
|
@ -21,7 +24,7 @@ class ProfileGraph : GraphView {
|
|||
basalArray.add(DataPoint(hour.toDouble(), profile.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
basalArray.add(DataPoint((hour + 1).toDouble(), profile.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
}
|
||||
val basalDataPoints: Array<DataPoint> = Array(basalArray.size){ i-> basalArray[i]}
|
||||
val basalDataPoints: Array<DataPoint> = Array(basalArray.size) { i -> basalArray[i] }
|
||||
val basalSeries: LineGraphSeries<DataPoint> = LineGraphSeries(basalDataPoints)
|
||||
addSeries(basalSeries)
|
||||
basalSeries.thickness = 8
|
||||
|
@ -35,4 +38,40 @@ class ProfileGraph : GraphView {
|
|||
gridLabelRenderer.numHorizontalLabels = 13
|
||||
gridLabelRenderer.verticalLabelsColor = basalSeries.color
|
||||
}
|
||||
|
||||
fun show(profile1: Profile, profile2: Profile) {
|
||||
removeAllSeries()
|
||||
|
||||
// profile 1
|
||||
val basalArray1: MutableList<DataPoint> = ArrayList()
|
||||
for (hour in 0..23) {
|
||||
basalArray1.add(DataPoint(hour.toDouble(), profile1.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
basalArray1.add(DataPoint((hour + 1).toDouble(), profile1.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
}
|
||||
val basalSeries1: LineGraphSeries<DataPoint> = LineGraphSeries(Array(basalArray1.size) { i -> basalArray1[i] })
|
||||
addSeries(basalSeries1)
|
||||
basalSeries1.thickness = 8
|
||||
basalSeries1.isDrawBackground = true
|
||||
|
||||
// profile 2
|
||||
val basalArray2: MutableList<DataPoint> = ArrayList()
|
||||
for (hour in 0..23) {
|
||||
basalArray2.add(DataPoint(hour.toDouble(), profile2.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
basalArray2.add(DataPoint((hour + 1).toDouble(), profile2.getBasalTimeFromMidnight(hour * 60 * 60)))
|
||||
}
|
||||
val basalSeries2: LineGraphSeries<DataPoint> = LineGraphSeries(Array(basalArray2.size) { i -> basalArray2[i] })
|
||||
addSeries(basalSeries2)
|
||||
basalSeries2.thickness = 8
|
||||
basalSeries2.isDrawBackground = false
|
||||
basalSeries2.color = context.getColor(R.color.examinedProfile)
|
||||
basalSeries2.backgroundColor = 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(max(profile1.maxDailyBasal, profile2.maxDailyBasal) * 1.1, 0.5))
|
||||
gridLabelRenderer.numHorizontalLabels = 13
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
<color name="warningAlertHeaderText">#FF000000</color>
|
||||
<color name="errorAlertBackground">#FFFF5555</color>
|
||||
<color name="errorAlertHeaderText">#FF000000</color>
|
||||
<color name="examinedProfile">#FFFF5555</color>
|
||||
|
||||
<!-- Treatment-->
|
||||
<color name="tempbasal">#C803A9F4</color>
|
||||
|
|
Loading…
Reference in a new issue