diff --git a/build.gradle.kts b/build.gradle.kts index bf893c05d..37b367c63 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,3 +30,7 @@ plugins { apply("versions.gradle") tasks.register("clean") { delete(rootProject.layout.buildDirectory) } + +subprojects.forEach { project -> + project.tasks.withType().configureEach { useJUnitPlatform() } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index db806e9dc..746e7d981 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,15 +4,16 @@ activity = "1.9.0" agp = "8.4.1" androidXAnnotation = "1.8.0" androidXCore = "1.13.1" -appcompat = "1.6.1" +appcompat = "1.7.0" composeBom = "2024.05.00" composeNavigation = "2.7.7" coroutines = "1.8.1" dokka = "1.9.20" jUnit = "4.13.2" jUnitExt = "1.1.5" +jupiter = "5.10.2" kotlin = "2.0.0" -lifecycle = "2.8.0" +lifecycle = "2.8.1" material = "1.12.0" mockK = "1.13.11" paparazziGradlePlugin = "1.3.4" @@ -34,8 +35,9 @@ composeUI = { group = "androidx.compose.ui", name = "ui" } composeUITooling = { group = "androidx.compose.ui", name = "ui-tooling" } composeViewBinding = { group = "androidx.compose.ui", name = "ui-viewbinding" } coroutinesCore = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "coroutines" } -jUnit = { group = "junit", name = "junit", version.ref = "jUnit" } -jUnitExt = { group = "androidx.test.ext", name = "junit", version.ref = "jUnitExt" } +jUnit = { module = "junit:junit", version.ref = "jUnit" } +jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "jupiter" } +jupiterParams = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "jupiter" } kotlinGradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } kotlinStdLib = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib", version.ref = "kotlin" } kotlinTest = { group = "org.jetbrains.kotlin", name = "kotlin-test", version.ref = "kotlin" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index b82aa23a4..a4413138c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426..b740cf133 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. diff --git a/renovate.json b/renovate.json index 9c4bc609e..79f9c607d 100644 --- a/renovate.json +++ b/renovate.json @@ -1,5 +1,8 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": ["config:base"], + "automerge": true, + "automergeType": "branch", + "baseBranches": ["master", "v1"], "dependencyDashboard": false } diff --git a/sample/build.gradle b/sample/build.gradle index b4ec03cd1..d8537c2da 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -76,7 +76,5 @@ dependencies { implementation libs.systemUIController implementation libs.viewModelCompose debugImplementation libs.composeUITooling - testImplementation libs.JUnit - testImplementation libs.JUnitExt testImplementation libs.kotlinTest } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/VicoApp.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/VicoApp.kt index 00ecb1910..0085bbe93 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/VicoApp.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/VicoApp.kt @@ -32,17 +32,17 @@ internal fun VicoApp() { NavHost(navController = navController, startDestination = "chartList") { composable("chartList") { ChartListScreen(navController) } composable( - "chart/{initialChartID}/{uiSystemID}", + "chart/{initialChartID}/{uiFrameworkID}", listOf( navArgument("initialChartID") { type = NavType.IntType }, - navArgument("uiSystemID") { type = NavType.IntType }, + navArgument("uiFrameworkID") { type = NavType.IntType }, ), ) { backStackEntry -> val arguments = requireNotNull(backStackEntry.arguments) ChartScreen( navController, arguments.getInt("initialChartID"), - arguments.getInt("uiSystemID"), + arguments.getInt("uiFrameworkID"), ) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartListScreen.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartListScreen.kt index 29e6c0fbe..840da521a 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartListScreen.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartListScreen.kt @@ -44,7 +44,7 @@ import com.patrykandpatrick.vico.R @OptIn(ExperimentalMaterial3Api::class) @Composable internal fun ChartListScreen(navController: NavController) { - var uiSystem by rememberSaveable { mutableStateOf(UISystem.Compose) } + var uiFramework by rememberSaveable { mutableStateOf(UIFramework.Compose) } val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() Scaffold( Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), @@ -60,13 +60,13 @@ internal fun ChartListScreen(navController: NavController) { SingleChoiceSegmentedButtonRow( Modifier.fillMaxWidth().padding(start = 16.dp, end = 16.dp, bottom = 8.dp) ) { - UISystem.entries.forEachIndexed { index, segmentUISystem -> + UIFramework.entries.forEachIndexed { index, segmentUIFramework -> SegmentedButton( - selected = uiSystem == segmentUISystem, - onClick = { uiSystem = segmentUISystem }, - shape = SegmentedButtonDefaults.itemShape(index, UISystem.entries.size), + selected = uiFramework == segmentUIFramework, + onClick = { uiFramework = segmentUIFramework }, + shape = SegmentedButtonDefaults.itemShape(index, UIFramework.entries.size), ) { - Text(stringResource(segmentUISystem.labelResourceID)) + Text(stringResource(segmentUIFramework.labelResourceID)) } } } @@ -74,7 +74,7 @@ internal fun ChartListScreen(navController: NavController) { items(charts.size) { chartID -> ListItem( { Text(stringResource(R.string.chart_x, chartID + 1)) }, - Modifier.clickable { navController.navigate("chart/$chartID/${uiSystem.ordinal}") }, + Modifier.clickable { navController.navigate("chart/$chartID/${uiFramework.ordinal}") }, ) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartScreen.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartScreen.kt index 11183aa90..286dff30f 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartScreen.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/ChartScreen.kt @@ -52,7 +52,7 @@ import com.patrykandpatrick.vico.R @OptIn(ExperimentalMaterial3Api::class) @Composable -internal fun ChartScreen(navController: NavController, initialChartID: Int, uiSystemID: Int) { +internal fun ChartScreen(navController: NavController, initialChartID: Int, uiFrameworkID: Int) { val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() val nestedNavController = rememberNavController() val chartID = @@ -113,7 +113,7 @@ internal fun ChartScreen(navController: NavController, initialChartID: Int, uiSy BackHandler(onBack = navigateBack) val arguments = requireNotNull(backStackEntry.arguments) charts[arguments.getInt("chartID")]( - UISystem.entries[uiSystemID], + UIFramework.entries[uiFrameworkID], Modifier.padding(horizontal = 16.dp), ) } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Charts.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Charts.kt index 71ca994e1..930af767b 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Charts.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Charts.kt @@ -30,15 +30,15 @@ import com.patrykandpatrick.vico.sample.showcase.charts.Chart8 import com.patrykandpatrick.vico.sample.showcase.charts.Chart9 internal val charts = - listOf<@Composable (UISystem, Modifier) -> Unit>( - { uiSystem, modifier -> Chart1(uiSystem, modifier) }, - { uiSystem, modifier -> Chart2(uiSystem, modifier) }, - { uiSystem, modifier -> Chart3(uiSystem, modifier) }, - { uiSystem, modifier -> Chart4(uiSystem, modifier) }, - { uiSystem, modifier -> Chart5(uiSystem, modifier) }, - { uiSystem, modifier -> Chart6(uiSystem, modifier) }, - { uiSystem, modifier -> Chart7(uiSystem, modifier) }, - { uiSystem, modifier -> Chart8(uiSystem, modifier) }, - { uiSystem, modifier -> Chart9(uiSystem, modifier) }, - { uiSystem, modifier -> Chart10(uiSystem, modifier) }, + listOf<@Composable (UIFramework, Modifier) -> Unit>( + { uiFramework, modifier -> Chart1(uiFramework, modifier) }, + { uiFramework, modifier -> Chart2(uiFramework, modifier) }, + { uiFramework, modifier -> Chart3(uiFramework, modifier) }, + { uiFramework, modifier -> Chart4(uiFramework, modifier) }, + { uiFramework, modifier -> Chart5(uiFramework, modifier) }, + { uiFramework, modifier -> Chart6(uiFramework, modifier) }, + { uiFramework, modifier -> Chart7(uiFramework, modifier) }, + { uiFramework, modifier -> Chart8(uiFramework, modifier) }, + { uiFramework, modifier -> Chart9(uiFramework, modifier) }, + { uiFramework, modifier -> Chart10(uiFramework, modifier) }, ) diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Marker.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Marker.kt index ddadb4624..84dad1482 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Marker.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/Marker.kt @@ -104,16 +104,10 @@ internal fun rememberMarker( ) { with(context) { super.getInsets(context, outInsets, horizontalDimensions) - val shadowInset = - (CLIPPING_FREE_SHADOW_RADIUS_MULTIPLIER * LABEL_BACKGROUND_SHADOW_RADIUS_DP - - LABEL_BACKGROUND_SHADOW_DY_DP) - .pixels - when (labelPosition) { - LabelPosition.Top, - LabelPosition.AroundPoint, - LabelPosition.AbovePoint -> outInsets.top += shadowInset - LabelPosition.Bottom -> outInsets.bottom += shadowInset - } + val baseShadowInsetDp = + CLIPPING_FREE_SHADOW_RADIUS_MULTIPLIER * LABEL_BACKGROUND_SHADOW_RADIUS_DP + outInsets.top += (baseShadowInsetDp - LABEL_BACKGROUND_SHADOW_DY_DP).pixels + outInsets.bottom += (baseShadowInsetDp + LABEL_BACKGROUND_SHADOW_DY_DP).pixels } } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UISystem.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UIFramework.kt similarity index 91% rename from sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UISystem.kt rename to sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UIFramework.kt index 3cd821d0d..c5bddb76d 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UISystem.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/UIFramework.kt @@ -19,7 +19,7 @@ package com.patrykandpatrick.vico.sample.showcase import androidx.annotation.StringRes import com.patrykandpatrick.vico.R -internal enum class UISystem(@StringRes val labelResourceID: Int) { +internal enum class UIFramework(@StringRes val labelResourceID: Int) { Compose(R.string.compose), Views(R.string.views), } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart1.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart1.kt index 996aeab6f..8720b0d5c 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart1.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart1.kt @@ -35,25 +35,27 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.lineSeries import com.patrykandpatrick.vico.core.common.shader.DynamicShader import com.patrykandpatrick.vico.databinding.Chart1Binding -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @Composable -internal fun Chart1(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart1(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { series(x, x.map { Random.nextFloat() * 15 }) } } } } - when (uiSystem) { - UISystem.Compose -> ComposeChart1(modelProducer, modifier) - UISystem.Views -> ViewChart1(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart1(modelProducer, modifier) + UIFramework.Views -> ViewChart1(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart10.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart10.kt index a42a4d23f..09cfa4b25 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart10.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart10.kt @@ -33,7 +33,7 @@ import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer import com.patrykandpatrick.vico.core.cartesian.data.RandomCartesianModelGenerator import com.patrykandpatrick.vico.databinding.Chart10Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay @@ -41,21 +41,23 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart10(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart10(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(key1 = Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/candlestick-layer#data. */ add(RandomCartesianModelGenerator.getRandomCandlestickLayerModelPartial()) } delay(Defaults.TRANSACTION_INTERVAL_MS) } } } - when (uiSystem) { - UISystem.Compose -> ComposeChart10(modelProducer, modifier) - UISystem.Views -> ViewChart10(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart10(modelProducer, modifier) + UIFramework.Views -> ViewChart10(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart2.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart2.kt index 9bd329edc..e552d0df4 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart2.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart2.kt @@ -50,7 +50,7 @@ import com.patrykandpatrick.vico.core.common.component.TextComponent import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart2Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import java.text.DateFormatSymbols import java.util.Locale @@ -61,21 +61,23 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart2(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart2(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */ columnSeries { series(List(47) { 2 + Random.nextFloat() * 18 }) } } delay(Defaults.TRANSACTION_INTERVAL_MS) } } } - when (uiSystem) { - UISystem.Compose -> ComposeChart2(modelProducer, modifier) - UISystem.Views -> ViewChart2(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart2(modelProducer, modifier) + UIFramework.Views -> ViewChart2(modelProducer, modifier) } } @@ -158,8 +160,8 @@ private fun getViewHorizontalLine() = background = ShapeComponent(Shape.Pill, HORIZONTAL_LINE_COLOR) padding = Dimensions( - HORIZONTAL_LINE_LABEL_VERTICAL_PADDING_DP, HORIZONTAL_LINE_LABEL_HORIZONTAL_PADDING_DP, + HORIZONTAL_LINE_LABEL_VERTICAL_PADDING_DP, ) margins = Dimensions(HORIZONTAL_LINE_LABEL_MARGIN_DP) typeface = Typeface.MONOSPACE diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart3.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart3.kt index e338923da..290fc2cf4 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart3.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart3.kt @@ -51,7 +51,7 @@ import com.patrykandpatrick.vico.core.common.shader.DynamicShader import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart3Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -60,21 +60,23 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart3(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart3(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { series(List(Defaults.ENTRY_COUNT) { Random.nextFloat() * 20 }) } } delay(Defaults.TRANSACTION_INTERVAL_MS) } } } - when (uiSystem) { - UISystem.Compose -> ComposeChart3(modelProducer, modifier) - UISystem.Views -> ViewChart3(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart3(modelProducer, modifier) + UIFramework.Views -> ViewChart3(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart4.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart4.kt index 5e543bf21..d6fe313c9 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart4.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart4.kt @@ -43,7 +43,7 @@ import com.patrykandpatrick.vico.core.common.shader.DynamicShader import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart4Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -52,12 +52,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart4(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart4(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */ columnSeries { repeat(3) { series( @@ -68,15 +70,17 @@ internal fun Chart4(uiSystem: UISystem, modifier: Modifier) { ) } } + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { series(List(Defaults.ENTRY_COUNT) { Random.nextFloat() * Defaults.MAX_Y }) } } delay(Defaults.TRANSACTION_INTERVAL_MS) } } } - when (uiSystem) { - UISystem.Compose -> ComposeChart4(modelProducer, modifier) - UISystem.Views -> ViewChart4(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart4(modelProducer, modifier) + UIFramework.Views -> ViewChart4(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart5.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart5.kt index 9bbec9c1f..b76b1253b 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart5.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart5.kt @@ -38,7 +38,7 @@ import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart5Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -47,12 +47,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart5(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart5(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */ columnSeries { repeat(3) { series( @@ -69,9 +71,9 @@ internal fun Chart5(uiSystem: UISystem, modifier: Modifier) { } } - when (uiSystem) { - UISystem.Compose -> ComposeChart5(modelProducer, modifier) - UISystem.Views -> ViewChart5(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart5(modelProducer, modifier) + UIFramework.Views -> ViewChart5(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart6.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart6.kt index 12e9fdc2b..61310f128 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart6.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart6.kt @@ -40,12 +40,16 @@ import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis 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.decoration.HorizontalBox import com.patrykandpatrick.vico.core.cartesian.layer.ColumnCartesianLayer import com.patrykandpatrick.vico.core.common.Dimensions +import com.patrykandpatrick.vico.core.common.component.ShapeComponent +import com.patrykandpatrick.vico.core.common.component.TextComponent +import com.patrykandpatrick.vico.core.common.copyColor import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart6Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -54,12 +58,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart6(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart6(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */ columnSeries { repeat(Defaults.MULTI_SERIES_COUNT) { series( @@ -76,15 +82,15 @@ internal fun Chart6(uiSystem: UISystem, modifier: Modifier) { } } - when (uiSystem) { - UISystem.Compose -> ComposeChart6(modelProducer, modifier) - UISystem.Views -> ViewChart6(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart6(modelProducer, modifier) + UIFramework.Views -> ViewChart6(modelProducer, modifier) } } @Composable private fun ComposeChart6(modelProducer: CartesianChartModelProducer, modifier: Modifier) { - val horizontalBox = rememberHorizontalBox() + val horizontalBox = rememberComposeHorizontalBox() val shape = remember { Shape.cut(topLeftPercent = 50) } CartesianChartHost( chart = @@ -108,38 +114,69 @@ private fun ComposeChart6(modelProducer: CartesianChartModelProducer, modifier: @Composable private fun ViewChart6(modelProducer: CartesianChartModelProducer, modifier: Modifier) { - val horizontalBox = rememberHorizontalBox() - val decorations = remember(horizontalBox) { listOf(horizontalBox) } val marker = rememberMarker() - AndroidViewBinding(Chart6Binding::inflate, modifier) { - with(chartView) { - chart?.setDecorations(decorations) - runInitialAnimation = false - this.modelProducer = modelProducer - (chart?.bottomAxis as HorizontalAxis).valueFormatter = - bottomAxisValueFormatter - this.marker = marker - } - } + AndroidViewBinding( + { inflater, parent, attachToParent -> + Chart6Binding.inflate(inflater, parent, attachToParent).apply { + with(chartView) { + chart?.addDecoration(getViewHorizontalBox()) + runInitialAnimation = false + this.modelProducer = modelProducer + (chart?.bottomAxis as HorizontalAxis).valueFormatter = + bottomAxisValueFormatter + this.marker = marker + } + } + }, + modifier, + ) } @Composable -private fun rememberHorizontalBox() = - rememberHorizontalBox( - y = { 7f..14f }, - box = rememberShapeComponent(color = horizontalBoxColor.copy(.36f)), +private fun rememberComposeHorizontalBox(): HorizontalBox { + val color = Color(HORIZONTAL_BOX_COLOR) + return rememberHorizontalBox( + y = { horizontalBoxY }, + box = rememberShapeComponent(color = color.copy(HORIZONTAL_BOX_ALPHA)), labelComponent = rememberTextComponent( - color = Color.Black, - background = rememberShapeComponent(Shape.Rectangle, horizontalBoxColor), - padding = Dimensions.of(8.dp, 2.dp), - margins = Dimensions.of(4.dp), + background = rememberShapeComponent(Shape.Rectangle, color), + padding = + Dimensions.of( + HORIZONTAL_BOX_LABEL_HORIZONTAL_PADDING_DP.dp, + HORIZONTAL_BOX_LABEL_VERTICAL_PADDING_DP.dp, + ), + margins = Dimensions.of(HORIZONTAL_BOX_LABEL_MARGIN_DP.dp), typeface = Typeface.MONOSPACE, ), ) +} + +private fun getViewHorizontalBox() = + HorizontalBox( + y = { horizontalBoxY }, + box = ShapeComponent(color = HORIZONTAL_BOX_COLOR.copyColor(HORIZONTAL_BOX_ALPHA)), + labelComponent = + TextComponent.build { + typeface = Typeface.MONOSPACE + background = ShapeComponent(Shape.Rectangle, HORIZONTAL_BOX_COLOR) + padding = + Dimensions( + HORIZONTAL_BOX_LABEL_HORIZONTAL_PADDING_DP, + HORIZONTAL_BOX_LABEL_VERTICAL_PADDING_DP, + ) + margins = Dimensions(HORIZONTAL_BOX_LABEL_MARGIN_DP) + }, + ) + +private const val HORIZONTAL_BOX_COLOR = -1448529 +private const val HORIZONTAL_BOX_ALPHA = .36f +private const val HORIZONTAL_BOX_LABEL_HORIZONTAL_PADDING_DP = 8f +private const val HORIZONTAL_BOX_LABEL_VERTICAL_PADDING_DP = 2f +private const val HORIZONTAL_BOX_LABEL_MARGIN_DP = 4f private val columnColors = listOf(Color(0xff3e6558), Color(0xff5e836a), Color(0xffa5ba8e)) -private val horizontalBoxColor = Color(0xffe9e5af) +private val horizontalBoxY = 7f..14f private val daysOfWeek = listOf("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") private val bottomAxisValueFormatter = CartesianValueFormatter { x, _, _ -> daysOfWeek[x.toInt() % daysOfWeek.size] diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart7.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart7.kt index bf498d063..d682dd21b 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart7.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart7.kt @@ -53,7 +53,7 @@ import com.patrykandpatrick.vico.core.common.shader.DynamicShader import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart7Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -62,12 +62,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart7(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart7(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { repeat(Defaults.MULTI_SERIES_COUNT) { series( @@ -84,9 +86,9 @@ internal fun Chart7(uiSystem: UISystem, modifier: Modifier) { } } - when (uiSystem) { - UISystem.Compose -> ComposeChart7(modelProducer, modifier) - UISystem.Views -> ViewChart7(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart7(modelProducer, modifier) + UIFramework.Views -> ViewChart7(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart8.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart8.kt index bb9dd8ea8..edc808c7a 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart8.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart8.kt @@ -45,7 +45,7 @@ import com.patrykandpatrick.vico.core.common.shader.DynamicShader import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart8Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -54,12 +54,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart8(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart8(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */ columnSeries { repeat(Defaults.MULTI_SERIES_COUNT) { series( @@ -70,6 +72,8 @@ internal fun Chart8(uiSystem: UISystem, modifier: Modifier) { ) } } + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { series(List(Defaults.ENTRY_COUNT) { Random.nextFloat() * Defaults.MAX_Y }) } } delay(Defaults.TRANSACTION_INTERVAL_MS) @@ -77,9 +81,9 @@ internal fun Chart8(uiSystem: UISystem, modifier: Modifier) { } } - when (uiSystem) { - UISystem.Compose -> ComposeChart8(modelProducer, modifier) - UISystem.Views -> ViewChart8(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart8(modelProducer, modifier) + UIFramework.Views -> ViewChart8(modelProducer, modifier) } } diff --git a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart9.kt b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart9.kt index a894bf2b3..b38eb0d70 100644 --- a/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart9.kt +++ b/sample/src/main/java/com/patrykandpatrick/vico/sample/showcase/charts/Chart9.kt @@ -57,7 +57,7 @@ import com.patrykandpatrick.vico.core.common.shader.TopBottomShader import com.patrykandpatrick.vico.core.common.shape.Shape import com.patrykandpatrick.vico.databinding.Chart9Binding import com.patrykandpatrick.vico.sample.showcase.Defaults -import com.patrykandpatrick.vico.sample.showcase.UISystem +import com.patrykandpatrick.vico.sample.showcase.UIFramework import com.patrykandpatrick.vico.sample.showcase.rememberMarker import kotlin.random.Random import kotlinx.coroutines.Dispatchers @@ -66,12 +66,14 @@ import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext @Composable -internal fun Chart9(uiSystem: UISystem, modifier: Modifier) { +internal fun Chart9(uiFramework: UIFramework, modifier: Modifier) { val modelProducer = remember { CartesianChartModelProducer.build() } LaunchedEffect(Unit) { withContext(Dispatchers.Default) { while (isActive) { modelProducer.tryRunTransaction { + /* Learn more: + https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/line-layer#data. */ lineSeries { series(x = x, y = x.map { Random.nextFloat() * 30 - 10 }) } } delay(Defaults.TRANSACTION_INTERVAL_MS) @@ -79,9 +81,9 @@ internal fun Chart9(uiSystem: UISystem, modifier: Modifier) { } } - when (uiSystem) { - UISystem.Compose -> ComposeChart9(modelProducer, modifier) - UISystem.Views -> ViewChart9(modelProducer, modifier) + when (uiFramework) { + UIFramework.Compose -> ComposeChart9(modelProducer, modifier) + UIFramework.Views -> ViewChart9(modelProducer, modifier) } } diff --git a/sample/src/main/res/layout/chart_8.xml b/sample/src/main/res/layout/chart_8.xml index f483e344d..e1413eb90 100644 --- a/sample/src/main/res/layout/chart_8.xml +++ b/sample/src/main/res/layout/chart_8.xml @@ -23,12 +23,13 @@ android:id="@+id/chart_view" android:layout_width="match_parent" android:layout_height="wrap_content" - app:axisStyle="@style/Chart8AxisStyle" app:chartZoomEnabled="false" app:columnLayerStyle="@style/Chart8ColumnLayerStyle" + app:endAxisStyle="@style/Chart8VerticalAxisStyle" app:layers="line|column" app:lineLayerStyle="@style/Chart8LineLayerStyle" app:showBottomAxis="true" app:showEndAxis="true" - app:showStartAxis="true" /> + app:showStartAxis="true" + app:startAxisStyle="@style/Chart8VerticalAxisStyle" /> diff --git a/sample/src/main/res/values/chart_8_styles.xml b/sample/src/main/res/values/chart_8_styles.xml index a0cb6e10c..533435f30 100644 --- a/sample/src/main/res/values/chart_8_styles.xml +++ b/sample/src/main/res/values/chart_8_styles.xml @@ -20,7 +20,7 @@ #f09b7d #ffc3a1 - diff --git a/sample/src/test/kotlin/com/patrykandpatrick/vico/sample/PaparazziTest.kt b/sample/src/test/kotlin/com/patrykandpatrick/vico/sample/PaparazziTest.kt index f43df95bc..0cef94952 100644 --- a/sample/src/test/kotlin/com/patrykandpatrick/vico/sample/PaparazziTest.kt +++ b/sample/src/test/kotlin/com/patrykandpatrick/vico/sample/PaparazziTest.kt @@ -18,6 +18,7 @@ package com.patrykandpatrick.vico.sample import androidx.compose.runtime.Composable import app.cash.paparazzi.Paparazzi +import com.android.ide.common.rendering.api.SessionParams import com.patrykandpatrick.vico.sample.paparazzi.lightConfig import com.patrykandpatrick.vico.sample.paparazzi.nightConfig import com.patrykandpatrick.vico.sample.previews.composables.column.DefaultColumnChart @@ -50,7 +51,13 @@ public class PaparazziTest { "ColumnChart Long Not Scrollable" to { DefaultColumnChartLongNonScrollable() }, ) - @get:Rule public val paparazzi: Paparazzi = Paparazzi(deviceConfig = lightConfig) + @get:Rule + public val paparazzi = + Paparazzi( + deviceConfig = lightConfig, + renderingMode = SessionParams.RenderingMode.SHRINK, + maxPercentDifference = .2, + ) private fun List Unit>>.snapshotAll() { forEach { (name, composable) -> paparazzi.snapshot(name) { composable() } } diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart.png index 4069443da..d7fe6abef 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f96866cb52f2b2a998fbf2ac901fbb2d6374202fe44184e45e9177ff9730c07 -size 69590 +oid sha256:5b245060fe704c8bdd6e76373e72a184bde9a51548bf0d201052da4b8ea7f87f +size 12996 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_not_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_not_scrollable.png index 374de0ff6..bfa332b71 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_not_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_not_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d061d0f9d499f177a1308125735d09ba2222da8e4c71366c4bfb25fab0535f1 -size 75857 +oid sha256:5832637d14a5b58c71cafa6649d9a4094a0e9b029f57b30ac6d74523636467d9 +size 14315 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable.png index 374de0ff6..0afc86090 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d061d0f9d499f177a1308125735d09ba2222da8e4c71366c4bfb25fab0535f1 -size 75857 +oid sha256:061a58c500cfa517536578f53ebdb853e4e653f4eff3d6fc0f4afa2f74a5d932 +size 13974 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png index 374de0ff6..a58158316 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d061d0f9d499f177a1308125735d09ba2222da8e4c71366c4bfb25fab0535f1 -size 75857 +oid sha256:4551137f3f524c95009e64a553998994a323ec72df11ca274022d86f114e5ef2 +size 14256 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart.png index 4f85cbc95..7033d8c2a 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1c07ec599fd9a7a669583db0f6fe8321bc08014d108ed784e2fd96c7f9c72130 -size 91631 +oid sha256:875dcb29ba9b28fce6b8ade4c889f3b3e4485160519b4c5b98c1611e23dd791d +size 21043 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_not_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_not_scrollable.png index 7b423daef..d30a6c14d 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_not_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_not_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:218376de53c6fc0a44b2ea734f585bb8f0ec5dc650c33a76ab4cb6c8e0260bff -size 122743 +oid sha256:9d3448bab165c067b12c7037347e102f09091845483ae336cd944ee52b69d1c4 +size 29334 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable.png index 7b423daef..8b004ae21 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:218376de53c6fc0a44b2ea734f585bb8f0ec5dc650c33a76ab4cb6c8e0260bff -size 122743 +oid sha256:dff3d13d62ba4ddb76d2a8c411792affd5eb86c0fef3c1c719175b7798600e9b +size 29597 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable_with_initial_scroll_end.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable_with_initial_scroll_end.png index 7b423daef..706f7bf30 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable_with_initial_scroll_end.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NIGHT_linechart_long_scrollable_with_initial_scroll_end.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:218376de53c6fc0a44b2ea734f585bb8f0ec5dc650c33a76ab4cb6c8e0260bff -size 122743 +oid sha256:e25ece745b961c1b5310990f54e989676bd2b367d3ff2ca9b7da6bb51a58ce0c +size 29675 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart.png index 821e1aa8b..5ff736133 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:080c0eb596f76f8813dc018087f8deed9f4781d30dcbf928808f33f4025af22c -size 68799 +oid sha256:2e131d25f1abd8047d92dd6577f7a6aec210cf85799077d229e38796bee8f2d2 +size 12963 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_not_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_not_scrollable.png index 8ba5ff1a9..9af65cb3c 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_not_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_not_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:858cd653b02e74801f86ec031d54c3204c156d14b1fec05f5de6c963afd57976 -size 76443 +oid sha256:72126acdf5357ed4c78f13ac272d0d1139d157df0c232de9879965b2714c2755 +size 14372 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable.png index 8ba5ff1a9..76bb24aa9 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:858cd653b02e74801f86ec031d54c3204c156d14b1fec05f5de6c963afd57976 -size 76443 +oid sha256:eb2ee633e85ad34a9329df5d93a69d851c2140e4baba8a79b5b9dedcf9971f2b +size 14047 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png index 8ba5ff1a9..1c97c5116 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_columnchart_long_scrollable_with_initial_scroll_end.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:858cd653b02e74801f86ec031d54c3204c156d14b1fec05f5de6c963afd57976 -size 76443 +oid sha256:3e74cd55976872df9f23a1fb026f8babc1134020eeea7775f6519f26d663763a +size 14375 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart.png index 3760106b5..dd4e6c97f 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:979812857b868a0bcf0fd62a379aa01d7524f7d2e90deaaaa0a75de4d4f88148 -size 89810 +oid sha256:f7e55543e005c48d7bbe72ed8ffabf79c10327a4fa45d71773174785c59ef63c +size 20415 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_not_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_not_scrollable.png index eef61b2b7..a50506134 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_not_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_not_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b1e3b82703a73f07c33a539c9976f886b9ddba98db092e813ef1a5221b0af90 -size 119874 +oid sha256:9b221f4dc27146835528c00bc6ca3bd7e8dca74f6d8101b1f48c20a8f285c405 +size 28252 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable.png index eef61b2b7..90ec92082 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b1e3b82703a73f07c33a539c9976f886b9ddba98db092e813ef1a5221b0af90 -size 119874 +oid sha256:10f8dcf8bba82df069d11886ae0a682c74dad562a8de3bfcf3d5a73990391fdf +size 28527 diff --git a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable_with_initial_scroll_end.png b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable_with_initial_scroll_end.png index eef61b2b7..18e0e6498 100644 --- a/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable_with_initial_scroll_end.png +++ b/sample/src/test/snapshots/images/com.patrykandpatrick.vico.sample_PaparazziTest_Test default charts in NOT NIGHT_linechart_long_scrollable_with_initial_scroll_end.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2b1e3b82703a73f07c33a539c9976f886b9ddba98db092e813ef1a5221b0af90 -size 119874 +oid sha256:936429772cf9236f7d8f524176d978f7584510b52184a2374564458381f0bdd4 +size 28609 diff --git a/versions.gradle b/versions.gradle index f490b9e0b..b358940d6 100644 --- a/versions.gradle +++ b/versions.gradle @@ -18,7 +18,7 @@ ext { library = [ groupId : "com.patrykandpatrick.vico", - version_name : "2.0.0-alpha.20", + version_name : "2.0.0-alpha.21", version_code : 1, target_sdk : 34, min_sdk : 19, diff --git a/vico/compose/build.gradle b/vico/compose/build.gradle index 9741c6b84..5d33619d1 100644 --- a/vico/compose/build.gradle +++ b/vico/compose/build.gradle @@ -76,7 +76,5 @@ dependencies { implementation libs.composeFoundation implementation libs.composeUI implementation libs.kotlinStdLib - testImplementation libs.JUnit - testImplementation libs.JUnitExt testImplementation libs.kotlinTest } diff --git a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/cartesian/CartesianChartHost.kt b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/cartesian/CartesianChartHost.kt index 48213332c..28042b9ed 100644 --- a/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/cartesian/CartesianChartHost.kt +++ b/vico/compose/src/main/java/com/patrykandpatrick/vico/compose/cartesian/CartesianChartHost.kt @@ -210,7 +210,7 @@ internal fun CartesianChartHostImpl( with(LocalContext.current) { ::spToPx }, chartValues, ) - val previousMarkerX = remember { ValueWrapper(null) } + val previousMarkerTargetHashCode = remember { ValueWrapper(null) } val elevationOverlayColor = vicoTheme.elevationOverlayColor.toArgb() val coroutineScope = rememberCoroutineScope() @@ -280,13 +280,13 @@ internal fun CartesianChartHostImpl( chart.draw(cartesianDrawContext, model) if (marker != null) { - previousMarkerX.value = + previousMarkerTargetHashCode.value = cartesianDrawContext.drawMarker( marker, markerTouchPoint.value, chart, markerVisibilityListener, - previousMarkerX.value, + previousMarkerTargetHashCode.value, ) } diff --git a/vico/core/build.gradle b/vico/core/build.gradle index 8d01976c9..469c48e86 100644 --- a/vico/core/build.gradle +++ b/vico/core/build.gradle @@ -59,12 +59,12 @@ afterEvaluate { } dependencies { - implementation libs.androidXAnnotation implementation libs.coroutinesCore implementation libs.kotlinStdLib testImplementation libs.JUnit - testImplementation libs.JUnitExt + testImplementation libs.jupiter + testImplementation libs.jupiterParams testImplementation libs.kotlinTest testImplementation libs.mockK testImplementation libs.testCore diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/CartesianDrawContext.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/CartesianDrawContext.kt index d7e04385e..7b629d936 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/CartesianDrawContext.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/CartesianDrawContext.kt @@ -99,10 +99,10 @@ public fun CartesianDrawContext.drawMarker( markerTouchPoint: Point?, chart: CartesianChart, visibilityListener: CartesianMarkerVisibilityListener?, - previousX: Float?, -): Float? { + previousTargetHashCode: Int?, +): Int? { if (markerTouchPoint == null || chart.markerTargets.isEmpty()) { - if (previousX != null) visibilityListener?.onHidden(marker) + if (previousTargetHashCode != null) visibilityListener?.onHidden(marker) return null } var targets = emptyList() @@ -115,11 +115,11 @@ public fun CartesianDrawContext.drawMarker( previousDistance = distance } marker.draw(this, targets) - val x = targets.first().x - if (previousX == null) { + val targetHashCode = targets.hashCode() + if (previousTargetHashCode == null) { visibilityListener?.onShown(marker, targets) - } else if (x != previousX) { - visibilityListener?.onMoved(marker, targets) + } else if (targetHashCode != previousTargetHashCode) { + visibilityListener?.onUpdated(marker, targets) } - return x + return targetHashCode } diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/axis/VerticalAxis.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/axis/VerticalAxis.kt index 1baf81499..b7af7e990 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/axis/VerticalAxis.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/axis/VerticalAxis.kt @@ -276,9 +276,11 @@ public open class VerticalAxis(override val po .orZero val labelSpace = when (horizontalLabelPosition) { - Outside -> - getMaxLabelWidth(height).ceil.also { extraStore[maxLabelWidthKey] = it } + - tickLength + Outside -> { + val maxLabelWidth = getMaxLabelWidth(height).ceil + extraStore[maxLabelWidthKey] = maxLabelWidth + maxLabelWidth + tickLength + } Inside -> 0f } (labelSpace + titleComponentWidth + axisThickness).coerceIn( diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/data/ChartValues.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/data/ChartValues.kt index c8789995e..5578ccabf 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/data/ChartValues.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/data/ChartValues.kt @@ -18,6 +18,9 @@ package com.patrykandpatrick.vico.core.cartesian.data import com.patrykandpatrick.vico.core.cartesian.CartesianChart import com.patrykandpatrick.vico.core.cartesian.axis.AxisPosition +import com.patrykandpatrick.vico.core.common.round +import kotlin.math.absoluteValue +import kotlin.math.ulp /** Houses a [CartesianChart]’s [CartesianChartModel] and _x_ and _y_ ranges. */ public interface ChartValues { @@ -81,3 +84,11 @@ public interface ChartValues { } } } + +internal fun ChartValues.getXSpacingMultiplier(entryX: Float): Float { + val xSpacingMultiplier = (entryX - minX) / xStep + check((xSpacingMultiplier - xSpacingMultiplier.round).absoluteValue <= xSpacingMultiplier.ulp) { + "Each entry’s x value must be a multiple of the x step." + } + return xSpacingMultiplier +} diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/CandlestickCartesianLayer.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/CandlestickCartesianLayer.kt index a65b3974d..cc49869ba 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/CandlestickCartesianLayer.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/CandlestickCartesianLayer.kt @@ -30,6 +30,7 @@ import com.patrykandpatrick.vico.core.cartesian.data.CandlestickCartesianLayerMo import com.patrykandpatrick.vico.core.cartesian.data.ChartValues import com.patrykandpatrick.vico.core.cartesian.data.MutableChartValues import com.patrykandpatrick.vico.core.cartesian.data.forEachIn +import com.patrykandpatrick.vico.core.cartesian.data.getXSpacingMultiplier import com.patrykandpatrick.vico.core.cartesian.layer.CandlestickCartesianLayer.Candle import com.patrykandpatrick.vico.core.cartesian.marker.CandlestickCartesianLayerMarkerTarget import com.patrykandpatrick.vico.core.cartesian.marker.CartesianMarker @@ -130,8 +131,7 @@ public open class CandlestickCartesianLayer( model.series.forEachIn(chartValues.minX..chartValues.maxX) { entry, _ -> candle = candles.getCandle(entry, model.extraStore) val candleInfo = drawingModel?.entries?.get(entry.x) ?: entry.toCandleInfo(yRange) - - val xSpacingMultiplier = (entry.x - chartValues.minX) / chartValues.xStep + val xSpacingMultiplier = chartValues.getXSpacingMultiplier(entry.x) bodyCenterX = drawingStart + layoutDirectionMultiplier * horizontalDimensions.xSpacing * xSpacingMultiplier + diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/ColumnCartesianLayer.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/ColumnCartesianLayer.kt index da3c85fe4..542e2b9d1 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/ColumnCartesianLayer.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/layer/ColumnCartesianLayer.kt @@ -28,6 +28,7 @@ import com.patrykandpatrick.vico.core.cartesian.data.ColumnCartesianLayerDrawing import com.patrykandpatrick.vico.core.cartesian.data.ColumnCartesianLayerModel import com.patrykandpatrick.vico.core.cartesian.data.MutableChartValues import com.patrykandpatrick.vico.core.cartesian.data.forEachIn +import com.patrykandpatrick.vico.core.cartesian.data.getXSpacingMultiplier import com.patrykandpatrick.vico.core.cartesian.marker.CartesianMarker import com.patrykandpatrick.vico.core.cartesian.marker.ColumnCartesianLayerMarkerTarget import com.patrykandpatrick.vico.core.cartesian.marker.MutableColumnCartesianLayerMarkerTarget @@ -126,10 +127,7 @@ public open class ColumnCartesianLayer( entryCollection.forEachIn(chartValues.minX..chartValues.maxX) { entry, _ -> val columnInfo = drawingModel?.getOrNull(index)?.get(entry.x) height = (columnInfo?.height ?: (abs(entry.y) / yRange.length)) * bounds.height() - val xSpacingMultiplier = (entry.x - chartValues.minX) / chartValues.xStep - check(xSpacingMultiplier % 1f == 0f) { - "Each entry’s x value must be a multiple of the x step." - } + val xSpacingMultiplier = chartValues.getXSpacingMultiplier(entry.x) val column = columnProvider.getColumn(entry, index, model.extraStore) columnCenterX = drawingStart + diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/CartesianMarkerVisibilityListener.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/CartesianMarkerVisibilityListener.kt index 595b40d66..001ab8a15 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/CartesianMarkerVisibilityListener.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/CartesianMarkerVisibilityListener.kt @@ -21,8 +21,14 @@ public interface CartesianMarkerVisibilityListener { /** Called when the specified [CartesianMarker] is shown. */ public fun onShown(marker: CartesianMarker, targets: List) - /** Called when the specified [CartesianMarker]’s _x_ value changes. */ - public fun onMoved(marker: CartesianMarker, targets: List): Unit = Unit + /** Called when the specified [CartesianMarker]’s [CartesianMarker.Target]s change. */ + public fun onUpdated(marker: CartesianMarker, targets: List) { + @Suppress("DEPRECATION") onMoved(marker, targets) + } + + /** Called when the specified [CartesianMarker]’s [CartesianMarker.Target]s change. */ + @Deprecated("Use `onUpdated` instead.") + public fun onMoved(marker: CartesianMarker, targets: List) {} /** Called when the specified [CartesianMarker] is hidden. */ public fun onHidden(marker: CartesianMarker) diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/DefaultCartesianMarker.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/DefaultCartesianMarker.kt index be40071d0..133a16543 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/DefaultCartesianMarker.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/cartesian/marker/DefaultCartesianMarker.kt @@ -47,13 +47,14 @@ import com.patrykandpatrick.vico.core.common.shape.MarkerCorneredShape * @param guideline drawn vertically through the marked points. */ public open class DefaultCartesianMarker( - public val label: TextComponent, - public var valueFormatter: CartesianMarkerValueFormatter = DefaultCartesianMarkerValueFormatter(), - public val labelPosition: LabelPosition = LabelPosition.Top, - public val indicator: Component? = null, - public var indicatorSizeDp: Float = Defaults.MARKER_INDICATOR_SIZE, - public var setIndicatorColor: ((Int) -> Unit)? = null, - public val guideline: LineComponent? = null, + protected val label: TextComponent, + protected val valueFormatter: CartesianMarkerValueFormatter = + DefaultCartesianMarkerValueFormatter(), + protected val labelPosition: LabelPosition = LabelPosition.Top, + protected val indicator: Component? = null, + protected val indicatorSizeDp: Float = Defaults.MARKER_INDICATOR_SIZE, + protected val setIndicatorColor: ((Int) -> Unit)? = null, + protected val guideline: LineComponent? = null, ) : CartesianMarker { protected val tempBounds: RectF = RectF() diff --git a/vico/core/src/test/java/com/patrykandpatrick/vico/core/data/XSpacingMultiplierTest.kt b/vico/core/src/test/java/com/patrykandpatrick/vico/core/data/XSpacingMultiplierTest.kt new file mode 100644 index 000000000..0257eba76 --- /dev/null +++ b/vico/core/src/test/java/com/patrykandpatrick/vico/core/data/XSpacingMultiplierTest.kt @@ -0,0 +1,82 @@ +/* + * Copyright 2024 by Patryk Goworowski and Patrick Michalik. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.patrykandpatrick.vico.core.data + +import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModel +import com.patrykandpatrick.vico.core.cartesian.data.ColumnCartesianLayerModel +import com.patrykandpatrick.vico.core.cartesian.data.MutableChartValues +import com.patrykandpatrick.vico.core.cartesian.data.getXSpacingMultiplier +import java.util.stream.Stream +import org.junit.jupiter.api.assertThrows +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource + +public class XSpacingMultiplierTest { + + @ParameterizedTest + @MethodSource("getXWithValidXStep") + public fun `Valid xStep produces the correct xStepMultiplier`(x: List, xStep: Float) { + checkXSpacingMultiplier(x, xStep) + } + + @ParameterizedTest() + @MethodSource("getXWithInvalidXStep") + public fun `Invalid xStep throws an exception on xStepMultiplier calculation`( + x: List, + xStep: Float, + ) { + assertThrows { checkXSpacingMultiplier(x, xStep) } + } + + private fun checkXSpacingMultiplier(xCollection: List, xStep: Float) { + val chartValues = MutableChartValues() + val columnCartesianModel = + ColumnCartesianLayerModel.build { series(xCollection, xCollection.map { 1f }) } + val model = CartesianChartModel(columnCartesianModel) + chartValues.update(xStep, model) + + chartValues.tryUpdate( + columnCartesianModel.minX, + columnCartesianModel.maxX, + columnCartesianModel.minY, + columnCartesianModel.maxY, + null, + ) + xCollection.forEach { chartValues.getXSpacingMultiplier(it.toFloat()) } + } + + private companion object { + @JvmStatic + private fun getXWithValidXStep(): Stream = + Stream.of( + Arguments.of(listOf(1.35, 1.9, 2.59), 0.01f), + Arguments.of(listOf(0.1, 0.2), 0.1f), + Arguments.of(listOf(0.000001f, 0.000002f), 0.000001f), + Arguments.of(listOf(1000f, 0.000002f), 1000f), + ) + + @JvmStatic + private fun getXWithInvalidXStep(): Stream = + Stream.of( + Arguments.of(listOf(1.35, 1.9, 2.59), 0.1f), + Arguments.of(listOf(0.1, 0.2), 1f), + Arguments.of(listOf(0.000001f, 0.000002f), 10f), + Arguments.of(listOf(1000f, 0.000002f), 10000f), + ) + } +} diff --git a/vico/views/build.gradle b/vico/views/build.gradle index 9f2002d91..89d27bd5d 100644 --- a/vico/views/build.gradle +++ b/vico/views/build.gradle @@ -62,7 +62,5 @@ dependencies { implementation libs.androidXCore implementation libs.appcompat implementation libs.kotlinStdLib - testImplementation libs.JUnit - testImplementation libs.JUnitExt testImplementation libs.kotlinTest } diff --git a/vico/views/src/main/java/com/patrykandpatrick/vico/views/cartesian/CartesianChartView.kt b/vico/views/src/main/java/com/patrykandpatrick/vico/views/cartesian/CartesianChartView.kt index 621fcda49..7e4cfb854 100644 --- a/vico/views/src/main/java/com/patrykandpatrick/vico/views/cartesian/CartesianChartView.kt +++ b/vico/views/src/main/java/com/patrykandpatrick/vico/views/cartesian/CartesianChartView.kt @@ -84,7 +84,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 private var markerTouchPoint: Point? = null - private var previousMarkerX: Float? = null + private var previousMarkerTargetHashCode: Int? = null private var scrollDirectionResolved = false @@ -346,13 +346,13 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 chart.draw(cartesianDrawContext, model) marker?.also { marker -> - previousMarkerX = + previousMarkerTargetHashCode = cartesianDrawContext.drawMarker( marker, markerTouchPoint, chart, markerVisibilityListener, - previousMarkerX, + previousMarkerTargetHashCode, ) } measureContext.reset()