Skip to content

Commit

Permalink
✨ Add Moving Average Graph to "All Time" chart
Browse files Browse the repository at this point in the history
Closes #776

Signed-off-by: Leonardo Colman Lopes <[email protected]>
  • Loading branch information
LeoColman committed Jan 7, 2025
1 parent 76c1853 commit b42c810
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import br.com.colman.petals.R.string.grams_distribution_over_days_since_first_use
import br.com.colman.petals.statistics.graph.component.LineChart
import br.com.colman.petals.statistics.graph.data.createAllTimeDistribution
import br.com.colman.petals.statistics.graph.data.createAllTimeDistributionWithMovingAverage
import br.com.colman.petals.statistics.graph.formatter.DaysSinceFirstUseFormatter
import br.com.colman.petals.use.repository.Use
import com.github.mikephil.charting.components.LimitLine
Expand All @@ -13,10 +13,10 @@ import java.time.YearMonth
@Composable
fun AllTimeGraph(uses: List<Use>, dateFormat: String) {
val description = stringResource(grams_distribution_over_days_since_first_use)
val gramsData = createAllTimeDistribution(uses)
val gramsData = createAllTimeDistributionWithMovingAverage(uses)
val gramsDataList = listOf(gramsData)

LineChart(gramsDataList, description, 5f) {
LineChart(gramsDataList.flatten(), description, 5f) {
axisMinimum = 1f
labelCount = 5
granularity = 1f
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Color.Companion.Gray
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import br.com.colman.petals.R
import br.com.colman.petals.R.string.grams_distribution_over_days_since_first_use
import br.com.colman.petals.statistics.graph.formatter.GramsValueFormatter
import br.com.colman.petals.use.repository.Use
Expand All @@ -14,25 +15,41 @@ import java.math.BigDecimal
import java.time.LocalDate.now

@Composable
fun createAllTimeDistribution(uses: List<Use>): LineDataSet {
val label = stringResource(grams_distribution_over_days_since_first_use)
return createAllTimeLineDataSet(calculateAllTimeGramsDistribution(uses), label)
fun createAllTimeDistributionWithMovingAverage(uses: List<Use>): List<LineDataSet> {
val gramsLabel = stringResource(grams_distribution_over_days_since_first_use)
val gramsDataSet = createAllTimeLineDataSet(calculateAllTimeGramsDistribution(uses), gramsLabel)

val movingAverageLabel = stringResource(R.string.moving_average_grams_distribution)
val movingAverageDataSet = createAllTimeAverageDataSet(
calculateMovingAverage(calculateAllTimeGramsDistribution(uses)),
movingAverageLabel
)

return listOf(gramsDataSet, movingAverageDataSet)
}

fun createAllTimeLineDataSet(entryList: List<Entry>, label: String): LineDataSet {
return LineDataSet(entryList, label).apply {
valueFormatter = GramsValueFormatter
lineWidth = 6f
setDrawCircles(true)
setDrawFilled(true)
setDrawValues(true)
setDrawCircles(false)
fillColor = Color.Cyan.copy(alpha = 0.3f).toArgb()
color = Color.Cyan.toArgb()
valueTextColor = Gray.toArgb()
valueTextSize = 14f
}
}

fun createAllTimeAverageDataSet(entryList: List<Entry>, label: String): LineDataSet {
return LineDataSet(entryList, label).apply {
setDrawValues(false)
setDrawCircles(false)
lineWidth = 6f
color = Color.Green.toArgb()
}
}

private fun calculateAllTimeGramsDistribution(uses: List<Use>): List<Entry> {
if (uses.isEmpty()) return emptyList()

Expand All @@ -46,3 +63,18 @@ private fun calculateAllTimeGramsDistribution(uses: List<Use>): List<Entry> {
Entry((day - firstUseDay).toFloat(), totalGrams.toFloat())
}
}

private fun calculateMovingAverage(entries: List<Entry>): List<Entry> {
if (entries.isEmpty()) return emptyList()

val result = mutableListOf<Entry>()
for (i in entries.indices) {
val start = maxOf(0, i - 14 + 1)
val end = i + 1
val windowEntries = entries.subList(start, end)

val averageValue = windowEntries.map { it.y }.average().toFloat()
result.add(Entry(entries[i].x, averageValue))
}
return result
}
3 changes: 2 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@
<string name="no_break_period">No break period</string>
<string name="hours_12">12 hours</string>
<string name="hours_24">24 hours</string>
<string name="grams_distribution_over_days_since_first_use">Grams distribution over days since first use</string>
<string name="grams_distribution_over_days_since_first_use">Grams per Day</string>
<plurals name="last_x_days">
<item quantity="one">Last %s day</item>
<item quantity="other">Last %s days</item>
</plurals>
<string name="language_label">App language</string>
<string name="what_language_should_be_used">What language should be used</string>
<string name="moving_average_grams_distribution">Average Grams per Day</string>
</resources>

0 comments on commit b42c810

Please sign in to comment.