diff --git a/Reef/src/main/java/dev/pranav/reef/util/TimeColumnChart.kt b/Reef/src/main/java/dev/pranav/reef/util/TimeColumnChart.kt
index c312e5c..45c4b2b 100644
--- a/Reef/src/main/java/dev/pranav/reef/util/TimeColumnChart.kt
+++ b/Reef/src/main/java/dev/pranav/reef/util/TimeColumnChart.kt
@@ -2,7 +2,8 @@
* Copyright (c) 2025 Nishant Mishra
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
+ * along with this program.
+ * If not, see .
*/
package org.nsh07.pomodoro.ui.statsScreen
@@ -34,6 +35,7 @@ import com.patrykandpatrick.vico.compose.common.MarkerCornerBasedShape
import com.patrykandpatrick.vico.compose.common.ProvideVicoTheme
import com.patrykandpatrick.vico.compose.common.component.rememberLineComponent
import com.patrykandpatrick.vico.compose.m3.common.rememberM3VicoTheme
+import kotlin.math.roundToInt
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -51,46 +53,43 @@ internal fun TimeColumnChart(
) {
if (dataValues.isEmpty()) return
- val radius = with(LocalDensity.current) {
- (thickness / 2).toPx()
- }
-
var chartSize by remember { mutableStateOf(IntSize.Zero) }
val density = LocalDensity.current
-
val primaryColor = MaterialTheme.colorScheme.primary
+ // Use a dedicated scrollState variable to track horizontal movement
+ val vicoScrollState = rememberVicoScrollState(initialScroll = Scroll.Absolute.End)
+
ProvideVicoTheme(rememberM3VicoTheme()) {
CartesianChartHost(
- chart =
- rememberCartesianChart(
- rememberColumnCartesianLayer(
- ColumnCartesianLayer.ColumnProvider.series(
- dataValues.indices.map { _ ->
- rememberLineComponent(
- fill = Fill(primaryColor),
- thickness = thickness,
- shape = MarkerCornerBasedShape(RoundedCornerShape(16.dp))
- )
- }
- ),
- columnCollectionSpacing = columnCollectionSpacing
- ),
- startAxis = VerticalAxis.rememberStart(
- valueFormatter = yValueFormatter
+ chart = rememberCartesianChart(
+ rememberColumnCartesianLayer(
+ ColumnCartesianLayer.ColumnProvider.series(
+ dataValues.indices.map { _ ->
+ rememberLineComponent(
+ fill = Fill(primaryColor),
+ thickness = thickness,
+ shape = MarkerCornerBasedShape(RoundedCornerShape(16.dp))
+ )
+ }
),
- bottomAxis = HorizontalAxis.rememberBottom(
- guideline = rememberLineComponent(Fill.Transparent),
- valueFormatter = xValueFormatter
- )
+ columnCollectionSpacing = columnCollectionSpacing
),
+ startAxis = VerticalAxis.rememberStart(
+ valueFormatter = yValueFormatter
+ ),
+ bottomAxis = HorizontalAxis.rememberBottom(
+ guideline = rememberLineComponent(Fill.Transparent),
+ valueFormatter = xValueFormatter
+ )
+ ),
modelProducer = modelProducer,
zoomState = rememberVicoZoomState(
zoomEnabled = false,
initialZoom = Zoom.fixed(),
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
),
- scrollState = rememberVicoScrollState(initialScroll = Scroll.Absolute.End),
+ scrollState = vicoScrollState,
animationSpec = animationSpec,
modifier = modifier
.onSizeChanged { chartSize = it }
@@ -104,28 +103,35 @@ internal fun TimeColumnChart(
val endPadding = with(density) { 16.dp.toPx() }
val bottomAxisHeight = with(density) { 32.dp.toPx() }
val topPadding = with(density) { 8.dp.toPx() }
- val availableWidth = chartWidth - startAxisWidth - endPadding
+
val availableHeight = chartHeight - bottomAxisHeight - topPadding
val columnWidth = with(density) { thickness.toPx() }
val spacing = with(density) { columnCollectionSpacing.toPx() }
val totalColumnWidth = columnWidth + spacing
- val clickX = offset.x - startAxisWidth
+ // Correcting coordinate: Add current scroll offset to the tap position relative to the chart start
+ val scrollOffset = vicoScrollState.value
+ val relativeTapX = offset.x - startAxisWidth
+ val absoluteX = relativeTapX + scrollOffset
val clickY = offset.y - topPadding
- if (clickX in 0.0f..availableWidth && clickY >= 0 && clickY <= availableHeight) {
- val columnIndex = (clickX / totalColumnWidth).toInt()
- if (columnIndex >= 0 && columnIndex < dataValues.size) {
- val maxValue = dataValues.maxOrNull() ?: 1f
- val barHeightRatio =
- if (maxValue > 0) dataValues[columnIndex] / maxValue else 0f
- val barHeight = availableHeight * barHeightRatio
- val barTop = availableHeight - barHeight
+ // Ensure tap is within the horizontal bounds of the chart content
+ if (offset.x in startAxisWidth..(chartWidth - endPadding) &&
+ clickY in 0f..availableHeight) {
+
+ // Using integer division for more predictable column mapping
+ val columnIndex = (absoluteX / totalColumnWidth).toInt()
+ .coerceIn(0, dataValues.size - 1)
- if (clickY in barTop..availableHeight) {
- onColumnClick(columnIndex)
- }
+ val maxValue = dataValues.maxOrNull() ?: 1f
+ val barHeightRatio = if (maxValue > 0) dataValues[columnIndex] / maxValue else 0f
+ val barHeight = availableHeight * barHeightRatio
+ val barTop = availableHeight - barHeight
+
+ // Trigger callback if the tap falls within the column's vertical area
+ if (clickY in barTop..availableHeight) {
+ onColumnClick(columnIndex)
}
}
}
@@ -186,4 +192,4 @@ internal fun TimeLineChart(
modifier = modifier
)
}
-}
+}
\ No newline at end of file