diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt
index ef5c563..7866783 100644
--- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt
+++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeColumnChart.kt
@@ -1,20 +1,34 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * This file is part of Tomato - a minimalist pomodoro timer for Android.
+ *
+ * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Tomato.
+ * If not, see .
*/
package org.nsh07.pomodoro.ui.statsScreen
import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.foundation.layout.height
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.motionScheme
+import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@@ -37,10 +51,16 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
+import com.patrykandpatrick.vico.core.cartesian.marker.ColumnCartesianLayerMarkerTarget
+import com.patrykandpatrick.vico.core.cartesian.marker.DefaultCartesianMarker
import com.patrykandpatrick.vico.core.common.Fill
+import com.patrykandpatrick.vico.core.common.Insets
+import com.patrykandpatrick.vico.core.common.component.ShapeComponent
+import com.patrykandpatrick.vico.core.common.component.TextComponent
import com.patrykandpatrick.vico.core.common.shape.CorneredShape
import org.nsh07.pomodoro.ui.theme.TomatoTheme
import org.nsh07.pomodoro.utils.millisecondsToHours
+import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
import org.nsh07.pomodoro.utils.millisecondsToMinutes
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@@ -58,6 +78,18 @@ fun TimeColumnChart(
millisecondsToMinutes(value.toLong())
}
},
+ markerValueFormatter: DefaultCartesianMarker.ValueFormatter = DefaultCartesianMarker.ValueFormatter { _, targets ->
+ val first = targets.firstOrNull()
+ val value = if (first is ColumnCartesianLayerMarkerTarget) {
+ first.columns.sumOf { it.entry.y.toLong() }
+ } else 0L
+
+ if (value >= 60 * 60 * 1000) {
+ millisecondsToHoursMinutes(value)
+ } else {
+ millisecondsToMinutes(value)
+ }
+ },
animationSpec: AnimationSpec? = motionScheme.slowEffectsSpec()
) {
ProvideVicoTheme(rememberM3VicoTheme()) {
@@ -88,6 +120,20 @@ fun TimeColumnChart(
guideline = rememberLineComponent(Fill.Transparent),
valueFormatter = xValueFormatter
),
+ marker = DefaultCartesianMarker(
+ TextComponent(
+ color = colorScheme.surface.toArgb(),
+ background = ShapeComponent(
+ fill = fill(colorScheme.onSurface),
+ shape = CorneredShape.Pill
+ ),
+ textSizeSp = typography.labelSmall.fontSize.value,
+ lineHeightSp = typography.labelSmall.fontSize.value,
+ padding = Insets(verticalDp = 4f, horizontalDp = 8f),
+ margins = Insets(bottomDp = 2f)
+ ),
+ valueFormatter = markerValueFormatter
+ ),
fadingEdges = FadingEdges()
),
modelProducer = modelProducer,
@@ -97,7 +143,7 @@ fun TimeColumnChart(
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
),
animationSpec = animationSpec,
- modifier = modifier,
+ modifier = modifier.height(224.dp),
)
}
}
diff --git a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt
index 73485f9..5a5b290 100644
--- a/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt
+++ b/app/src/main/java/org/nsh07/pomodoro/ui/statsScreen/TimeLineChart.kt
@@ -1,15 +1,28 @@
/*
* Copyright (c) 2025 Nishant Mishra
*
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * This file is part of Tomato - a minimalist pomodoro timer for Android.
+ *
+ * Tomato is free software: you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License as published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * Tomato is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with Tomato.
+ * If not, see .
*/
package org.nsh07.pomodoro.ui.statsScreen
import androidx.compose.animation.core.AnimationSpec
+import androidx.compose.foundation.layout.height
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.motionScheme
+import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -41,10 +54,17 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer.LineFill.Companion.single
+import com.patrykandpatrick.vico.core.cartesian.marker.DefaultCartesianMarker
+import com.patrykandpatrick.vico.core.cartesian.marker.LineCartesianLayerMarkerTarget
import com.patrykandpatrick.vico.core.common.Fill
+import com.patrykandpatrick.vico.core.common.Insets
+import com.patrykandpatrick.vico.core.common.component.ShapeComponent
+import com.patrykandpatrick.vico.core.common.component.TextComponent
import com.patrykandpatrick.vico.core.common.shader.ShaderProvider
+import com.patrykandpatrick.vico.core.common.shape.CorneredShape
import org.nsh07.pomodoro.ui.theme.TomatoTheme
import org.nsh07.pomodoro.utils.millisecondsToHours
+import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
import org.nsh07.pomodoro.utils.millisecondsToMinutes
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@@ -62,6 +82,18 @@ fun TimeLineChart(
millisecondsToMinutes(value.toLong())
}
},
+ markerValueFormatter: DefaultCartesianMarker.ValueFormatter = DefaultCartesianMarker.ValueFormatter { _, targets ->
+ val first = targets.firstOrNull()
+ val value = if (first is LineCartesianLayerMarkerTarget) {
+ first.points.sumOf { it.entry.y.toLong() }
+ } else 0L
+
+ if (value >= 60 * 60 * 1000) {
+ millisecondsToHoursMinutes(value)
+ } else {
+ millisecondsToMinutes(value)
+ }
+ },
animationSpec: AnimationSpec? = motionScheme.slowEffectsSpec()
) {
ProvideVicoTheme(rememberM3VicoTheme()) {
@@ -102,6 +134,20 @@ fun TimeLineChart(
guideline = rememberLineComponent(Fill.Transparent),
valueFormatter = xValueFormatter
),
+ marker = DefaultCartesianMarker(
+ TextComponent(
+ color = colorScheme.surface.toArgb(),
+ background = ShapeComponent(
+ fill = fill(colorScheme.onSurface),
+ shape = CorneredShape.Pill
+ ),
+ textSizeSp = typography.labelSmall.fontSize.value,
+ lineHeightSp = typography.labelSmall.fontSize.value,
+ padding = Insets(verticalDp = 4f, horizontalDp = 8f),
+ margins = Insets(bottomDp = 2f)
+ ),
+ valueFormatter = markerValueFormatter
+ ),
fadingEdges = FadingEdges()
),
modelProducer = modelProducer,
@@ -111,7 +157,7 @@ fun TimeLineChart(
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
),
animationSpec = animationSpec,
- modifier = modifier,
+ modifier = modifier.height(224.dp),
)
}
}