Dexcom-like statistics
This commit is contained in:
parent
40b337dad5
commit
f286072ae9
8 changed files with 277 additions and 31 deletions
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.databinding.ActivityStatsBinding
|
||||||
import info.nightscout.androidaps.logging.UserEntryLogger
|
import info.nightscout.androidaps.logging.UserEntryLogger
|
||||||
import info.nightscout.androidaps.utils.ActivityMonitor
|
import info.nightscout.androidaps.utils.ActivityMonitor
|
||||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.stats.DexcomTirCalculator
|
||||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||||
import info.nightscout.androidaps.utils.stats.TirCalculator
|
import info.nightscout.androidaps.utils.stats.TirCalculator
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -18,6 +19,7 @@ class StatsActivity : NoSplashAppCompatActivity() {
|
||||||
|
|
||||||
@Inject lateinit var tddCalculator: TddCalculator
|
@Inject lateinit var tddCalculator: TddCalculator
|
||||||
@Inject lateinit var tirCalculator: TirCalculator
|
@Inject lateinit var tirCalculator: TirCalculator
|
||||||
|
@Inject lateinit var dexcomTirCalculator: DexcomTirCalculator
|
||||||
@Inject lateinit var activityMonitor: ActivityMonitor
|
@Inject lateinit var activityMonitor: ActivityMonitor
|
||||||
@Inject lateinit var uel: UserEntryLogger
|
@Inject lateinit var uel: UserEntryLogger
|
||||||
|
|
||||||
|
@ -47,6 +49,13 @@ class StatsActivity : NoSplashAppCompatActivity() {
|
||||||
binding.tir.addView(tir)
|
binding.tir.addView(tir)
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
|
Thread {
|
||||||
|
val dexcomTir = dexcomTirCalculator.stats(this)
|
||||||
|
runOnUiThread {
|
||||||
|
binding.dexcomTir.removeAllViews()
|
||||||
|
binding.dexcomTir.addView(dexcomTir)
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
Thread {
|
Thread {
|
||||||
val activity = activityMonitor.stats(this)
|
val activity = activityMonitor.stats(this)
|
||||||
runOnUiThread {
|
runOnUiThread {
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
package info.nightscout.androidaps.utils.stats
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Typeface
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.widget.TableRow
|
||||||
|
import android.widget.TextView
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.interfaces.Profile
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.roundToInt
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
class DexcomTIR {
|
||||||
|
|
||||||
|
private var veryLow = 0
|
||||||
|
private var low = 0
|
||||||
|
private var inRange = 0
|
||||||
|
private var high = 0
|
||||||
|
private var veryHigh = 0
|
||||||
|
private var error = 0
|
||||||
|
private var count = 0
|
||||||
|
|
||||||
|
var sum = 0.0
|
||||||
|
val values = mutableListOf<Double>()
|
||||||
|
|
||||||
|
private val veryLowTirMgdl = Constants.STATS_RANGE_VERY_LOW_MMOL * Constants.MMOLL_TO_MGDL
|
||||||
|
private val lowTirMgdl = Constants.STATS_RANGE_LOW_MMOL * Constants.MMOLL_TO_MGDL
|
||||||
|
private val highTirMgdl = Constants.STATS_RANGE_HIGH_MMOL * Constants.MMOLL_TO_MGDL
|
||||||
|
private val highNightTirMgdl = Constants.STATS_RANGE_HIGH_NIGHT_MMOL * Constants.MMOLL_TO_MGDL
|
||||||
|
private val veryHighTirMgdl = Constants.STATS_RANGE_VERY_HIGH_MMOL * Constants.MMOLL_TO_MGDL
|
||||||
|
|
||||||
|
private fun error() = run { error++ }
|
||||||
|
private fun veryLow(valueMgdl: Double) = run { values.add(valueMgdl); sum += valueMgdl; veryLow++; count++ }
|
||||||
|
private fun low(valueMgdl: Double) = run { values.add(valueMgdl); sum += valueMgdl; low++; count++ }
|
||||||
|
private fun inRange(valueMgdl: Double) = run { values.add(valueMgdl); sum += valueMgdl; inRange++; count++ }
|
||||||
|
private fun high(valueMgdl: Double) = run { values.add(valueMgdl); sum += valueMgdl; high++; count++ }
|
||||||
|
private fun veryHigh(valueMgdl: Double) = run { values.add(valueMgdl); sum += valueMgdl; veryHigh++; count++ }
|
||||||
|
|
||||||
|
private fun highTirMgdl(hour: Int) = if (hour in 6..22) highTirMgdl else highNightTirMgdl
|
||||||
|
|
||||||
|
fun add(time: Long, valueMgdl: Double) {
|
||||||
|
val c = Calendar.getInstance()
|
||||||
|
c.timeInMillis = time
|
||||||
|
val hour = c[Calendar.HOUR_OF_DAY]
|
||||||
|
when {
|
||||||
|
valueMgdl < 39 -> error()
|
||||||
|
valueMgdl < veryLowTirMgdl -> veryLow(valueMgdl)
|
||||||
|
valueMgdl < lowTirMgdl -> low(valueMgdl)
|
||||||
|
valueMgdl > veryHighTirMgdl -> veryHigh(valueMgdl)
|
||||||
|
valueMgdl > highTirMgdl(hour) -> high(valueMgdl)
|
||||||
|
else -> inRange(valueMgdl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun veryLowPct() = if (count > 0) veryLow.toDouble() / count * 100.0 else 0.0
|
||||||
|
private fun lowPct() = if (count > 0) low.toDouble() / count * 100.0 else 0.0
|
||||||
|
private fun inRangePct() = if (count > 0) 100 - veryLowPct() - lowPct() - highPct() - veryHighPct() else 0.0
|
||||||
|
private fun highPct() = if (count > 0) high.toDouble() / count * 100.0 else 0.0
|
||||||
|
private fun veryHighPct() = if (count > 0) veryHigh.toDouble() / count * 100.0 else 0.0
|
||||||
|
private fun mean() = sum / count
|
||||||
|
|
||||||
|
fun calculateSD(): Double {
|
||||||
|
if (count == 0) return 0.0
|
||||||
|
var standardDeviation = 0.0
|
||||||
|
for (num in values) standardDeviation += (num - mean()).pow(2.0)
|
||||||
|
return sqrt(standardDeviation / count)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toHbA1cView(context: Context, rh: ResourceHelper): TextView =
|
||||||
|
TextView(context).apply {
|
||||||
|
text =
|
||||||
|
if (count == 0) ""
|
||||||
|
else rh.gs(R.string.hba1c) +
|
||||||
|
(10 * (mean() + 46.7) / 28.7).roundToInt() / 10.0 + "%" +
|
||||||
|
" (" +
|
||||||
|
(((mean() + 46.7) / 28.7 - 2.15) * 10.929).roundToInt() +
|
||||||
|
" mmol/L)"
|
||||||
|
setTypeface(typeface, Typeface.NORMAL)
|
||||||
|
gravity = Gravity.CENTER_HORIZONTAL
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
fun toSDView(context: Context, rh: ResourceHelper, profileFunction: ProfileFunction): TextView =
|
||||||
|
TextView(context).apply {
|
||||||
|
val sd = calculateSD()
|
||||||
|
text = "\n" + rh.gs(R.string.std_deviation, Profile.toUnitsString(sd, sd * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()))
|
||||||
|
setTypeface(typeface, Typeface.NORMAL)
|
||||||
|
gravity = Gravity.CENTER_HORIZONTAL
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toRangeHeaderView(context: Context, rh: ResourceHelper, profileFunction: ProfileFunction): TextView =
|
||||||
|
TextView(context).apply {
|
||||||
|
text = StringBuilder()
|
||||||
|
.append(rh.gs(R.string.detailed_14_days))
|
||||||
|
.append("\n")
|
||||||
|
.append(rh.gs(R.string.day_tir))
|
||||||
|
.append(" (")
|
||||||
|
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits()))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, highTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl))
|
||||||
|
.append("-∞)\n")
|
||||||
|
.append(rh.gs(R.string.night_tir))
|
||||||
|
.append(" (")
|
||||||
|
.append(Profile.toUnitsString(0.0, 0.0, profileFunction.getUnits()))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, veryLowTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, lowTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, highNightTirMgdl))
|
||||||
|
.append("-")
|
||||||
|
.append(Profile.toCurrentUnitsString(profileFunction, veryHighTirMgdl))
|
||||||
|
.append("-∞)\n")
|
||||||
|
.toString()
|
||||||
|
setTypeface(typeface, Typeface.BOLD)
|
||||||
|
gravity = Gravity.CENTER_HORIZONTAL
|
||||||
|
setTextAppearance(android.R.style.TextAppearance_Material_Medium)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toTableRowHeader(context: Context, rh: ResourceHelper): TableRow =
|
||||||
|
TableRow(context).also { header ->
|
||||||
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
|
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
|
header.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0; weight = 1f }; text = rh.gs(R.string.veryLow) })
|
||||||
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1; weight = 1f }; text = rh.gs(R.string.low) })
|
||||||
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2; weight = 1f }; text = rh.gs(R.string.in_range) })
|
||||||
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3; weight = 1f }; text = rh.gs(R.string.high) })
|
||||||
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 4; weight = 1f }; text = rh.gs(R.string.veryHigh) })
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
fun toTableRow(context: Context, rh: ResourceHelper): TableRow =
|
||||||
|
TableRow(context).also { row ->
|
||||||
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
|
row.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0 }; text = rh.gs(R.string.formatPercent, veryLowPct()) })
|
||||||
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatPercent, lowPct()) })
|
||||||
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatPercent, inRangePct()) })
|
||||||
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatPercent, highPct()) })
|
||||||
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 4 }; text = rh.gs(R.string.formatPercent, veryHighPct()) })
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package info.nightscout.androidaps.utils.stats
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.TableLayout
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.MidnightTime
|
||||||
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class DexcomTirCalculator @Inject constructor(
|
||||||
|
private val rh: ResourceHelper,
|
||||||
|
private val profileFunction: ProfileFunction,
|
||||||
|
private val dateUtil: DateUtil,
|
||||||
|
private val repository: AppRepository
|
||||||
|
) {
|
||||||
|
val days = 14L
|
||||||
|
|
||||||
|
fun calculate(): DexcomTIR {
|
||||||
|
val startTime = MidnightTime.calc(dateUtil.now() - T.days(days).msecs())
|
||||||
|
val endTime = MidnightTime.calc(dateUtil.now())
|
||||||
|
|
||||||
|
val bgReadings = repository.compatGetBgReadingsDataFromTime(startTime, endTime, true).blockingGet()
|
||||||
|
val result = DexcomTIR()
|
||||||
|
for (bg in bgReadings) result.add(bg.timestamp, bg.value)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
fun stats(context: Context): TableLayout =
|
||||||
|
TableLayout(context).also { layout ->
|
||||||
|
val tir = calculate()
|
||||||
|
layout.layoutParams = TableLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
|
layout.addView(tir.toRangeHeaderView(context, rh, profileFunction))
|
||||||
|
layout.addView(tir.toTableRowHeader(context, rh))
|
||||||
|
layout.addView(tir.toTableRow(context, rh))
|
||||||
|
layout.addView(tir.toSDView(context, rh, profileFunction))
|
||||||
|
layout.addView(tir.toHbA1cView(context, rh))
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,33 +33,33 @@ class TIR(val date: Long, val lowThreshold: Double, val highThreshold: Double) {
|
||||||
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
header.gravity = Gravity.CENTER_HORIZONTAL
|
header.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 0; weight = 1f }; text = rh.gs(R.string.date) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0; weight = 1f }; text = rh.gs(R.string.date) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 1; weight = 1f }; text = rh.gs(R.string.below) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1; weight = 1f }; text = rh.gs(R.string.below) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 2; weight = 1f }; text = rh.gs(R.string.in_range) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2; weight = 1f }; text = rh.gs(R.string.in_range) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 3; weight = 1f }; text = rh.gs(R.string.above) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3; weight = 1f }; text = rh.gs(R.string.above) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toTableRow(context: Context, rh: ResourceHelper, dateUtil: DateUtil): TableRow =
|
fun toTableRow(context: Context, rh: ResourceHelper, dateUtil: DateUtil): TableRow =
|
||||||
TableRow(context).also { row ->
|
TableRow(context).also { row ->
|
||||||
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT).apply { weight = 1f }
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
row.gravity = Gravity.CENTER_HORIZONTAL
|
row.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 0 }; text = dateUtil.dateStringShort(date) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0 }; text = dateUtil.dateStringShort(date) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatPercent, belowPct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatPercent, belowPct()) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatPercent, inRangePct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatPercent, inRangePct()) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatPercent, abovePct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatPercent, abovePct()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("SetTextI18n")
|
@SuppressLint("SetTextI18n")
|
||||||
fun toTableRow(context: Context, rh: ResourceHelper, days: Int): TableRow =
|
fun toTableRow(context: Context, rh: ResourceHelper, days: Int): TableRow =
|
||||||
TableRow(context).also { row ->
|
TableRow(context).also { row ->
|
||||||
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT).apply { weight = 1f }
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT, 1f)
|
||||||
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
row.gravity = Gravity.CENTER_HORIZONTAL
|
row.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 0 }; text = "%02d".format(days) + " " + rh.gs(R.string.days) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0 }; text = "%02d".format(days) + " " + rh.gs(R.string.days) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatPercent, belowPct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatPercent, belowPct()) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatPercent, inRangePct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatPercent, inRangePct()) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatPercent, abovePct()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatPercent, abovePct()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,29 @@
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/cardview_dexcom_tir"
|
||||||
|
style="@style/Widget.MaterialComponents.CardView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="4dp"
|
||||||
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
app:cardCornerRadius="4dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardUseCompatPadding="false"
|
||||||
|
app:contentPadding="2dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/dexcom_tir"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:orientation="vertical" />
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/cardview_activity"
|
android:id="@+id/cardview_activity"
|
||||||
style="@style/Widget.MaterialComponents.CardView"
|
style="@style/Widget.MaterialComponents.CardView"
|
||||||
|
|
|
@ -945,6 +945,11 @@
|
||||||
<string name="invalidpct">Invalid % entry</string>
|
<string name="invalidpct">Invalid % entry</string>
|
||||||
<string name="average">Average</string>
|
<string name="average">Average</string>
|
||||||
<string name="tir">TIR</string>
|
<string name="tir">TIR</string>
|
||||||
|
<string name="day_tir">Day TIR</string>
|
||||||
|
<string name="night_tir">Night TIR</string>
|
||||||
|
<string name="detailed_14_days">Detailed 14 days</string>
|
||||||
|
<string name="std_deviation">SD: %1$s</string>
|
||||||
|
<string name="hba1c">HbA1c: </string>
|
||||||
<string name="activitymonitor">Activity monitor</string>
|
<string name="activitymonitor">Activity monitor</string>
|
||||||
<string name="doyouwantresetstats">Do you want to reset activity stats?</string>
|
<string name="doyouwantresetstats">Do you want to reset activity stats?</string>
|
||||||
<string name="statistics">Statistics</string>
|
<string name="statistics">Statistics</string>
|
||||||
|
@ -1201,6 +1206,10 @@
|
||||||
<string name="count_selected">%1$d selected</string>
|
<string name="count_selected">%1$d selected</string>
|
||||||
<string name="sort_label">Sort</string>
|
<string name="sort_label">Sort</string>
|
||||||
<string name="dialog_canceled">Dialog canceled</string>
|
<string name="dialog_canceled">Dialog canceled</string>
|
||||||
|
<string name="veryLow" comment="below 3.1">Very low</string>
|
||||||
|
<string name="low" comment="3.1-3.9">Low</string>
|
||||||
|
<string name="high" comment="10.0-13.9">High</string>
|
||||||
|
<string name="veryHigh" comment="above 13.9">Very high</string>
|
||||||
<string name="below" comment="below "in range"">Below</string>
|
<string name="below" comment="below "in range"">Below</string>
|
||||||
<string name="in_range">In range</string>
|
<string name="in_range">In range</string>
|
||||||
<string name="above" comment="above "in range"">Above</string>
|
<string name="above" comment="above "in range"">Above</string>
|
||||||
|
|
|
@ -77,8 +77,11 @@ object Constants {
|
||||||
// STATISTICS
|
// STATISTICS
|
||||||
const val STATS_TARGET_LOW_MMOL = 3.9
|
const val STATS_TARGET_LOW_MMOL = 3.9
|
||||||
const val STATS_TARGET_HIGH_MMOL = 7.8
|
const val STATS_TARGET_HIGH_MMOL = 7.8
|
||||||
|
const val STATS_RANGE_VERY_LOW_MMOL = 3.1
|
||||||
const val STATS_RANGE_LOW_MMOL = 3.9
|
const val STATS_RANGE_LOW_MMOL = 3.9
|
||||||
|
const val STATS_RANGE_HIGH_NIGHT_MMOL = 8.3
|
||||||
const val STATS_RANGE_HIGH_MMOL = 10.0
|
const val STATS_RANGE_HIGH_MMOL = 10.0
|
||||||
|
const val STATS_RANGE_VERY_HIGH_MMOL = 13.9
|
||||||
|
|
||||||
// Local profile
|
// Local profile
|
||||||
const val LOCAL_PROFILE = "LocalProfile"
|
const val LOCAL_PROFILE = "LocalProfile"
|
||||||
|
|
|
@ -21,11 +21,11 @@ fun TotalDailyDose.Companion.toTableRowHeader(context: Context, rh: ResourceHelp
|
||||||
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)
|
val lp = TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
header.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
header.gravity = Gravity.CENTER_HORIZONTAL
|
header.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 0; weight = 1f }; text = rh.gs(R.string.date) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0; weight = 1f }; text = rh.gs(R.string.date) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 1; weight = 1f }; text = "∑" })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1; weight = 1f }; text = "∑" })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 2; weight = 1f }; text = rh.gs(R.string.bolus) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2; weight = 1f }; text = rh.gs(R.string.bolus) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 3; weight = 1f }; text = rh.gs(R.string.basal) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3; weight = 1f }; text = rh.gs(R.string.basal) })
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 4; weight = 1f }; text = rh.gs(R.string.basalpct) })
|
header.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 4; weight = 1f }; text = rh.gs(R.string.basalpct) })
|
||||||
if (includeCarbs)
|
if (includeCarbs)
|
||||||
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 5; weight = 1f }; text = rh.gs(R.string.carbs) })
|
header.addView(TextView(context).apply { layoutParams = lp.apply { column = 5; weight = 1f }; text = rh.gs(R.string.carbs) })
|
||||||
}
|
}
|
||||||
|
@ -36,13 +36,13 @@ fun TotalDailyDose.toTableRow(context: Context, rh: ResourceHelper, dateUtil: Da
|
||||||
if ((total.isNaN() || bolusAmount.isNaN() || basalAmount.isNaN() || carbs.isNaN()).not()) {
|
if ((total.isNaN() || bolusAmount.isNaN() || basalAmount.isNaN() || carbs.isNaN()).not()) {
|
||||||
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
row.gravity = Gravity.CENTER_HORIZONTAL
|
row.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 0 }; text = dateUtil.dateStringShort(timestamp) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0 }; text = dateUtil.dateStringShort(timestamp) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatinsulinunits1, total) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatinsulinunits1, total) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatinsulinunits1, bolusAmount) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatinsulinunits1, bolusAmount) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatinsulinunits1, basalAmount) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatinsulinunits1, basalAmount) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 4 }; text = rh.gs(R.string.formatPercent, basalPct) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 4 }; text = rh.gs(R.string.formatPercent, basalPct) })
|
||||||
if (includeCarbs)
|
if (includeCarbs)
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 5 }; text = rh.gs(R.string.format_carbs, carbs.toInt()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 5 }; text = rh.gs(R.string.format_carbs, carbs.toInt()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,12 @@ fun TotalDailyDose.toTableRow(context: Context, rh: ResourceHelper, days: Int, i
|
||||||
if ((total.isNaN() || bolusAmount.isNaN() || basalAmount.isNaN() || carbs.isNaN()).not()) {
|
if ((total.isNaN() || bolusAmount.isNaN() || basalAmount.isNaN() || carbs.isNaN()).not()) {
|
||||||
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
row.layoutParams = TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT)
|
||||||
row.gravity = Gravity.CENTER_HORIZONTAL
|
row.gravity = Gravity.CENTER_HORIZONTAL
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 0 }; text = "%02d".format(days) + " " + rh.gs(R.string.days) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 0 }; text = "%02d".format(days) + " " + rh.gs(R.string.days) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatinsulinunits1, total) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 1 }; text = rh.gs(R.string.formatinsulinunits1, total) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatinsulinunits1, bolusAmount) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 2 }; text = rh.gs(R.string.formatinsulinunits1, bolusAmount) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatinsulinunits1, basalAmount) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 3 }; text = rh.gs(R.string.formatinsulinunits1, basalAmount) })
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 4 }; text = rh.gs(R.string.formatPercent, basalPct) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 4 }; text = rh.gs(R.string.formatPercent, basalPct) })
|
||||||
if (includeCarbs)
|
if (includeCarbs)
|
||||||
row.addView(TextView(context).apply { layoutParams = lp.apply { column = 5 }; text = rh.gs(R.string.format_carbs, carbs.toInt()) })
|
row.addView(TextView(context).apply { gravity = Gravity.CENTER_HORIZONTAL; layoutParams = lp.apply { column = 5 }; text = rh.gs(R.string.format_carbs, carbs.toInt()) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue