From 1e8f5db05829e2709a908c7806b34fb813388f49 Mon Sep 17 00:00:00 2001 From: Fabian Zobrist Date: Sun, 2 Jul 2023 22:55:44 +0200 Subject: [PATCH] WIP. Show graph --- app/build.gradle | 1 + .../tichucounter/ui/counter/CounterView.kt | 4 +- .../tichucounter/ui/counter/RoundGraphView.kt | 106 ++++++++++++++++++ 3 files changed, 109 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/me/zobrist/tichucounter/ui/counter/RoundGraphView.kt diff --git a/app/build.gradle b/app/build.gradle index 663caf8..448c63f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -127,6 +127,7 @@ dependencies { implementation "androidx.room:room-ktx:2.5.1" implementation "androidx.multidex:multidex:2.0.1" api "androidx.navigation:navigation-fragment-ktx:2.5.3" + implementation "com.patrykandpatrick.vico:compose-m3:1.6.5" } // Allow references to generated code diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt index a338d72..7476fe6 100644 --- a/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/CounterView.kt @@ -50,7 +50,7 @@ fun Landscape(viewModel: ICounterViewModel) { viewModel.totalScoreB ) - RoundListView( + RoundGraphView( viewModel.roundScoreList, Modifier.weight(1f) ) @@ -81,7 +81,7 @@ fun Portrait(viewModel: ICounterViewModel) { viewModel.totalScoreB ) - RoundListView( + RoundGraphView( viewModel.roundScoreList, Modifier.weight(1f) ) diff --git a/app/src/main/java/me/zobrist/tichucounter/ui/counter/RoundGraphView.kt b/app/src/main/java/me/zobrist/tichucounter/ui/counter/RoundGraphView.kt new file mode 100644 index 0000000..ebc6807 --- /dev/null +++ b/app/src/main/java/me/zobrist/tichucounter/ui/counter/RoundGraphView.kt @@ -0,0 +1,106 @@ +package me.zobrist.tichucounter.ui.counter + +import android.content.res.Configuration +import android.graphics.Color +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.tooling.preview.Preview +import com.patrykandpatrick.vico.compose.axis.horizontal.bottomAxis +import com.patrykandpatrick.vico.compose.axis.vertical.endAxis +import com.patrykandpatrick.vico.compose.axis.vertical.startAxis +import com.patrykandpatrick.vico.compose.chart.Chart +import com.patrykandpatrick.vico.compose.chart.line.lineChart +import com.patrykandpatrick.vico.compose.chart.scroll.rememberChartScrollSpec +import com.patrykandpatrick.vico.compose.m3.style.m3ChartStyle +import com.patrykandpatrick.vico.compose.style.ProvideChartStyle +import com.patrykandpatrick.vico.compose.style.currentChartStyle +import com.patrykandpatrick.vico.core.axis.axisBuilder +import com.patrykandpatrick.vico.core.axis.formatter.DecimalFormatAxisValueFormatter +import com.patrykandpatrick.vico.core.axis.vertical.VerticalAxis +import com.patrykandpatrick.vico.core.chart.composed.plus +import com.patrykandpatrick.vico.core.chart.line.LineChart +import com.patrykandpatrick.vico.core.chart.values.AxisValuesOverrider +import com.patrykandpatrick.vico.core.component.text.TextComponent +import com.patrykandpatrick.vico.core.entry.FloatEntry +import com.patrykandpatrick.vico.core.entry.composed.ComposedChartEntryModelProducer.Companion.composedChartEntryModelOf +import com.patrykandpatrick.vico.core.entry.entryModelOf +import com.patrykandpatrick.vico.core.extension.ceil +import com.patrykandpatrick.vico.core.extension.round +import com.patrykandpatrick.vico.core.legend.Legend +import me.zobrist.tichucounter.data.entity.Round +import me.zobrist.tichucounter.ui.AppTheme +import java.lang.Math.round +import kotlin.math.ceil +import kotlin.math.floor +import kotlin.math.roundToInt + + +@Composable +fun RoundGraphView(rounds: List, modifier: Modifier) { + + val points = getPoints(rounds) + + val range = getRange(points.first, points.second, 50) + + val specA = LineChart.LineSpec(MaterialTheme.colorScheme.primary.toArgb()) + val specB = LineChart.LineSpec(MaterialTheme.colorScheme.secondary.toArgb()) + + + Chart( + chart = lineChart(lines = listOf(specA, specB), axisValuesOverrider = AxisValuesOverrider.fixed(minY = range.first.toFloat(), maxY = range.second.toFloat())), + model = composedChartEntryModelOf(listOf(entryModelOf(points.first), entryModelOf(points.second))), + startAxis = startAxis(maxLabelCount = 10, valueFormatter = DecimalFormatAxisValueFormatter("#")), + chartScrollSpec = rememberChartScrollSpec(isScrollEnabled = false), + modifier = modifier + ) +} + +private fun getPoints(rounds: List): Pair, List> { + var a = mutableListOf(FloatEntry(0f,0f)) + var b = mutableListOf(FloatEntry(0f,0f)) + + var sumA = 0 + var sumB = 0 + + rounds.forEachIndexed { index, round -> + sumA += round.scoreA + sumB += round.scoreB + a.add(FloatEntry(index.toFloat(), sumA.toFloat())) + b.add(FloatEntry(index.toFloat(), sumB.toFloat())) + } + return Pair(a, b) +} + +private fun getRange(a: List, b: List, step: Int): Pair { + + var min = (a + b).minBy { it -> it.y } + var max = (a + b).maxBy { it -> it.y } + + var lo = floor(min.y / step) * step + var hi = ceil(max.y / step) * step + + return Pair(lo.toFloat(), hi.toFloat()) +} + +@Preview(name = "Light Mode") +@Preview(name = "Dark Mode", uiMode = Configuration.UI_MODE_NIGHT_YES, showBackground = true) +@Composable +fun RoundGraphViewPreview() { + val rounds = listOf( + Round(1, 10, -10), + Round(1, 5, 95), + Round(1, 100, 0), + Round(1, 125, -25), + Round(1, 50, 50) + ) + + AppTheme { + Surface { + RoundGraphView(rounds, Modifier) + } + } +} \ No newline at end of file