@@ -1,20 +1,34 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2025 Nishant Mishra
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* This file is part of Tomato - a minimalist pomodoro timer for Android.
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.nsh07.pomodoro.ui.statsScreen
|
package org.nsh07.pomodoro.ui.statsScreen
|
||||||
|
|
||||||
import androidx.compose.animation.core.AnimationSpec
|
import androidx.compose.animation.core.AnimationSpec
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||||
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
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.CartesianValueFormatter
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
|
import com.patrykandpatrick.vico.core.cartesian.data.columnSeries
|
||||||
import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer
|
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.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 com.patrykandpatrick.vico.core.common.shape.CorneredShape
|
||||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToHours
|
import org.nsh07.pomodoro.utils.millisecondsToHours
|
||||||
|
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@@ -58,6 +78,18 @@ fun TimeColumnChart(
|
|||||||
millisecondsToMinutes(value.toLong())
|
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<Float>? = motionScheme.slowEffectsSpec()
|
animationSpec: AnimationSpec<Float>? = motionScheme.slowEffectsSpec()
|
||||||
) {
|
) {
|
||||||
ProvideVicoTheme(rememberM3VicoTheme()) {
|
ProvideVicoTheme(rememberM3VicoTheme()) {
|
||||||
@@ -88,6 +120,20 @@ fun TimeColumnChart(
|
|||||||
guideline = rememberLineComponent(Fill.Transparent),
|
guideline = rememberLineComponent(Fill.Transparent),
|
||||||
valueFormatter = xValueFormatter
|
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()
|
fadingEdges = FadingEdges()
|
||||||
),
|
),
|
||||||
modelProducer = modelProducer,
|
modelProducer = modelProducer,
|
||||||
@@ -97,7 +143,7 @@ fun TimeColumnChart(
|
|||||||
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
|
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
|
||||||
),
|
),
|
||||||
animationSpec = animationSpec,
|
animationSpec = animationSpec,
|
||||||
modifier = modifier,
|
modifier = modifier.height(224.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,28 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2025 Nishant Mishra
|
* Copyright (c) 2025 Nishant Mishra
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* This file is part of Tomato - a minimalist pomodoro timer for Android.
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.nsh07.pomodoro.ui.statsScreen
|
package org.nsh07.pomodoro.ui.statsScreen
|
||||||
|
|
||||||
import androidx.compose.animation.core.AnimationSpec
|
import androidx.compose.animation.core.AnimationSpec
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.motionScheme
|
import androidx.compose.material3.MaterialTheme.motionScheme
|
||||||
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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.data.lineSeries
|
||||||
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
|
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.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.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.shader.ShaderProvider
|
||||||
|
import com.patrykandpatrick.vico.core.common.shape.CorneredShape
|
||||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToHours
|
import org.nsh07.pomodoro.utils.millisecondsToHours
|
||||||
|
import org.nsh07.pomodoro.utils.millisecondsToHoursMinutes
|
||||||
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
import org.nsh07.pomodoro.utils.millisecondsToMinutes
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@@ -62,6 +82,18 @@ fun TimeLineChart(
|
|||||||
millisecondsToMinutes(value.toLong())
|
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<Float>? = motionScheme.slowEffectsSpec()
|
animationSpec: AnimationSpec<Float>? = motionScheme.slowEffectsSpec()
|
||||||
) {
|
) {
|
||||||
ProvideVicoTheme(rememberM3VicoTheme()) {
|
ProvideVicoTheme(rememberM3VicoTheme()) {
|
||||||
@@ -102,6 +134,20 @@ fun TimeLineChart(
|
|||||||
guideline = rememberLineComponent(Fill.Transparent),
|
guideline = rememberLineComponent(Fill.Transparent),
|
||||||
valueFormatter = xValueFormatter
|
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()
|
fadingEdges = FadingEdges()
|
||||||
),
|
),
|
||||||
modelProducer = modelProducer,
|
modelProducer = modelProducer,
|
||||||
@@ -111,7 +157,7 @@ fun TimeLineChart(
|
|||||||
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
|
minZoom = Zoom.min(Zoom.Content, Zoom.fixed())
|
||||||
),
|
),
|
||||||
animationSpec = animationSpec,
|
animationSpec = animationSpec,
|
||||||
modifier = modifier,
|
modifier = modifier.height(224.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user