Skip to content

Commit

Permalink
✨ Allow for an "All Time" view in statistics page LeoColman#554
Browse files Browse the repository at this point in the history
  • Loading branch information
gBL17 committed Sep 18, 2024
1 parent 176ecb8 commit ae5306e
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import br.com.colman.petals.statistics.card.AverageUseCard
import br.com.colman.petals.statistics.component.MultiPeriodSelect
import br.com.colman.petals.statistics.component.Period
import br.com.colman.petals.statistics.component.Period.Zero
import br.com.colman.petals.statistics.graph.AllTimeGraph
import br.com.colman.petals.statistics.graph.UsePerDayOfWeekGraph
import br.com.colman.petals.statistics.graph.UsePerHourGraph
import br.com.colman.petals.use.repository.Use
Expand All @@ -32,6 +33,9 @@ fun StatisticsPage(useRepository: UseRepository) {

UsePerHourGraph(usesInPeriod)
UsePerDayOfWeekGraph(usesInPeriod)
if (uses.isNotEmpty()) {
AllTimeGraph(uses)
}
usesInPeriod.forEach { (period, uses) ->
AverageUseCard(uses, period.toDateRange())
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package br.com.colman.petals.statistics.graph

import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import br.com.colman.petals.R.string
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.formatter.DaysSinceFirstUseFormatter
import br.com.colman.petals.use.repository.Use
import com.github.mikephil.charting.components.LimitLine
import com.github.mikephil.charting.data.LineDataSet
import java.time.LocalDate
import java.time.YearMonth

@Composable
fun AllTimeGraph(uses: List<Use>) {
val description = stringResource(string.all_time_day_description)
val gramsData = createAllTimeDistribution(uses)
val gramsDataList = mutableListOf<LineDataSet>()
gramsDataList.add(gramsData)

LineChart(gramsDataList, description, 5f) {
axisMinimum = 1f
labelCount = 5
granularity = 1f
valueFormatter = DaysSinceFirstUseFormatter
addLimitLine(LimitLine(YearMonth.from(LocalDate.now()).monthValue.toFloat()).apply { lineWidth = 2f })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.github.mikephil.charting.data.LineDataSet
fun LineChart(
datasets: List<LineDataSet>,
description: String,
range: Float? = null,
configureXAxis: XAxis.() -> Unit
) {
val colors = MaterialTheme.colors
Expand All @@ -34,6 +35,13 @@ fun LineChart(
chart.notifyDataSetChanged()
chart.invalidate()

range?.let {
chart.setVisibleXRange(range, range)
chart.setVisibleXRangeMaximum(datasets[0].xMax)
chart.moveViewToX(datasets[0].xMax)
chart.notifyDataSetChanged()
}

chart.axisRight.isEnabled = false
chart.axisLeft.apply {
axisMinimum = 0f
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package br.com.colman.petals.statistics.graph.data

import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color.Companion.Green
import androidx.compose.ui.graphics.Color.Companion.White
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
import br.com.colman.petals.R
import br.com.colman.petals.statistics.graph.formatter.GramsValueFormatter
import br.com.colman.petals.use.repository.Use
import br.com.colman.petals.use.repository.totalGrams
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import java.time.LocalDateTime.now

private fun calculateGramsDistributionPerDaySinceFirstUse(uses: List<Use>): List<Entry> {
val dayBeforeFirstUseDate = uses.minByOrNull { it.date }!!.localDate.toEpochDay().dec()
val now = now().toLocalDate().toEpochDay()
val dateRange = (dayBeforeFirstUseDate..now).toList()

val usesPerDay = dateRange.associateWith { uses.filter { u -> u.localDate.toEpochDay() == it } }

return usesPerDay.mapValues { it.value.totalGrams }.toSortedMap().map { (k, v) ->
Entry(
(k - dayBeforeFirstUseDate).toFloat(),
v.toFloat()
)
}
}

@Composable
fun createAllTimeDistribution(uses: List<Use>): LineDataSet {
return LineDataSet(calculateGramsDistributionPerDaySinceFirstUse(uses), stringResource(R.string.all_time)).apply {
valueFormatter = GramsValueFormatter
lineWidth = 6f
setDrawCircles(true)
setDrawFilled(false)
setDrawValues(true)
fillColor = Green.toArgb()
color = Green.toArgb()
valueTextColor = White.toArgb()
valueTextSize = 14f
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package br.com.colman.petals.statistics.graph.formatter

import br.com.colman.petals.koin
import br.com.colman.petals.settings.SettingsRepository
import br.com.colman.petals.use.repository.Use
import br.com.colman.petals.use.repository.UseRepository
import com.github.mikephil.charting.components.AxisBase
import com.github.mikephil.charting.formatter.IAxisValueFormatter
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import java.time.LocalDate
import java.time.format.DateTimeFormatter

val DaysSinceFirstUseFormatter = object : IAxisValueFormatter {
val settingsRepository: SettingsRepository = koin.get<SettingsRepository>()
val useRepository: UseRepository = koin.get<UseRepository>()

private var dateFormat: String = runBlocking { settingsRepository.dateFormat.first() }
private val formatter = DateTimeFormatter.ofPattern(dateFormat)

private var uses: List<Use> = runBlocking { useRepository.all().first() }
private val dayBeforeFirstUseDateToEpochDay: Long = uses.minByOrNull { it.date }!!.localDate.toEpochDay().dec()

override fun getFormattedValue(value: Float, axis: AxisBase?): String {
val epochDay = (value + dayBeforeFirstUseDateToEpochDay).toLong()
val localDate = LocalDate.ofEpochDay(epochDay)

return formatter.format(localDate)
}
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
<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="all_time_day_description">All Time Distribution per day</string>
<plurals name="last_x_days">
<item quantity="one">Last %s day</item>
<item quantity="other">Last %s days</item>
Expand Down

0 comments on commit ae5306e

Please sign in to comment.