From 5d7df24a4328d8b7727224f1fe95455df1f583ce Mon Sep 17 00:00:00 2001 From: Himanshu Date: Wed, 16 Aug 2023 15:04:59 +0200 Subject: [PATCH 1/3] Fix. Performance + New Config change --- build.gradle | 4 ++-- charty/build.gradle | 4 ++++ .../com/himanshoe/charty/area/AreaChart.kt | 4 +++- .../himanshoe/charty/bubble/BubbleChart.kt | 6 ++---- .../charty/candle/CandleStickChart.kt | 9 +++++---- .../com/himanshoe/charty/gauge/GaugeChart.kt | 19 +++++++++++++++++-- .../charty/gauge/config/GaugeChartConfig.kt | 4 ++++ .../charty/gauge/config/GaugeChartDefaults.kt | 2 ++ .../himanshoe/charty/group/GroupBarChart.kt | 10 ++++++---- docs/GAUGECHART.md | 5 ++++- gradle/wrapper/gradle-wrapper.properties | 2 +- quality/static-check.gradle | 9 +++------ 12 files changed, 53 insertions(+), 25 deletions(-) diff --git a/build.gradle b/build.gradle index 9f9f53b..6ebf896 100644 --- a/build.gradle +++ b/build.gradle @@ -7,8 +7,8 @@ buildscript { } plugins { - id 'com.android.application' version '8.0.0' apply false - id 'com.android.library' version '8.0.0' apply false + id 'com.android.application' version '8.1.0' apply false + id 'com.android.library' version '8.1.0' apply false id 'org.jetbrains.kotlin.android' version '1.8.21' apply false id("org.jetbrains.dokka") version "1.8.20" } diff --git a/charty/build.gradle b/charty/build.gradle index 36d8f4c..b7349e0 100644 --- a/charty/build.gradle +++ b/charty/build.gradle @@ -40,6 +40,10 @@ android { buildFeatures { compose true } + lint { + abortOnError false + warningsAsErrors true + } composeOptions { kotlinCompilerExtensionVersion '1.4.7' } diff --git a/charty/src/main/java/com/himanshoe/charty/area/AreaChart.kt b/charty/src/main/java/com/himanshoe/charty/area/AreaChart.kt index 15ddbe1..c469137 100644 --- a/charty/src/main/java/com/himanshoe/charty/area/AreaChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/area/AreaChart.kt @@ -51,7 +51,9 @@ fun AreaChart( axisConfig: AxisConfig = ChartDefaults.axisConfigDefaults(), padding: Dp = 16.dp, ) { - val items = areaData.data.flatMap { it.points } + val items = remember(areaData) { + areaData.data.flatMap { it.points } + } val maxValue = items.maxOrNull() ?: 0F val minValue = items.minOrNull() ?: 0f var chartWidth by remember { mutableStateOf(0F) } diff --git a/charty/src/main/java/com/himanshoe/charty/bubble/BubbleChart.kt b/charty/src/main/java/com/himanshoe/charty/bubble/BubbleChart.kt index 601386e..b684cd3 100644 --- a/charty/src/main/java/com/himanshoe/charty/bubble/BubbleChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/bubble/BubbleChart.kt @@ -20,7 +20,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.onSizeChanged import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -96,7 +95,6 @@ fun BubbleChart( val maxVolumeSize = data.maxOf { it.volumeSize } dataCollection.data.fastForEachIndexed { index, data -> - if (data is BubbleData) { val bubbleRadius = data.volumeSize / maxVolumeSize * 50 // Adjust the scaling factor here @@ -106,9 +104,9 @@ fun BubbleChart( .coerceIn(0f, chartHeight - bubbleRadius * 2) + bubbleRadius drawCircle( - color = Color.Blue, + brush = contentColor, radius = bubbleRadius, - center = Offset(x, y) + center = Offset(x = x, y = y) ) if (points.count() < 14) { drawXAxisLabels( diff --git a/charty/src/main/java/com/himanshoe/charty/candle/CandleStickChart.kt b/charty/src/main/java/com/himanshoe/charty/candle/CandleStickChart.kt index 3ca6c63..369c21e 100644 --- a/charty/src/main/java/com/himanshoe/charty/candle/CandleStickChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/candle/CandleStickChart.kt @@ -52,10 +52,11 @@ fun CandleStickChart( padding: Dp = 16.dp, candleConfig: CandleStickConfig = CandleStickDefaults.defaultCandleStickConfig(), ) { - val listOfAxisValues = candleData.data.flatMap { listOf(it.high, it.low, it.open, it.close) } - .distinct() - .sorted() - + val listOfAxisValues = remember(candleData.data) { + candleData.data.flatMap { listOf(it.high, it.low, it.open, it.close) } + .distinct() + .sorted() + } val maxValue = candleData.data.maxOf { maxOf(it.high, it.open, it.close) } val minValue = candleData.data.minOf { minOf(it.low, it.open, it.close) } diff --git a/charty/src/main/java/com/himanshoe/charty/gauge/GaugeChart.kt b/charty/src/main/java/com/himanshoe/charty/gauge/GaugeChart.kt index 9783550..14a9938 100644 --- a/charty/src/main/java/com/himanshoe/charty/gauge/GaugeChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/gauge/GaugeChart.kt @@ -8,6 +8,7 @@ package com.himanshoe.charty.gauge +import android.graphics.Paint import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.AnimationSpec import androidx.compose.animation.core.tween @@ -24,6 +25,8 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.tooling.preview.Preview import com.himanshoe.charty.gauge.config.GaugeChartConfig import com.himanshoe.charty.gauge.config.GaugeChartDefaults @@ -53,7 +56,7 @@ fun GaugeChart( animated: Boolean = true, animationSpec: AnimationSpec = tween(), ) { - require(percentValue in 1..100) { "percentValue must be within the range of 1 to 100" } + require(percentValue in 0..100) { "percentValue must be within the range of 1 to 100" } val animatedPercent = rememberAnimatedPercent(animated, percentValue, animationSpec) Box(modifier = modifier.aspectRatio(1f)) { @@ -142,6 +145,18 @@ fun GaugeChart( style = Stroke(width = needleConfig.strokeWidth, cap = StrokeCap.Round) ) } + if (gaugeChartConfig.showText) { + drawContext.canvas.nativeCanvas.drawText( + "$percentValue %", + center.x, + size.height - size.height / 4, + Paint().apply { + color = gaugeChartConfig.textColor.toArgb() + textSize = size.width / 25 + textAlign = Paint.Align.CENTER + } + ) + } } } } @@ -182,7 +197,7 @@ private fun rememberAnimatedPercent( @Preview @Composable -fun GaugeChartPreview() { +private fun GaugeChartPreview() { val percentValue = 100 GaugeChart(percentValue = percentValue) } diff --git a/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartConfig.kt b/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartConfig.kt index f205116..e4b52ed 100644 --- a/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartConfig.kt +++ b/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartConfig.kt @@ -16,6 +16,8 @@ import androidx.compose.ui.graphics.Color * * @param placeHolderColor The color of the placeholder arc in the gauge chart. * @param primaryColor The color of the primary arc in the gauge chart. + * @param textColor The color of the text in the gauge chart. + * @param showText Indicates whether to show the text in the gauge chart. * @param strokeWidth The width of the arcs in the gauge chart. * @param showNeedle Indicates whether to show the needle in the gauge chart. * @param showIndicator Indicates whether to show the indicator in the gauge chart. @@ -30,5 +32,7 @@ data class GaugeChartConfig( val showNeedle: Boolean, val showIndicator: Boolean, val indicatorColor: Color, + val textColor: Color, + val showText: Boolean, val indicatorWidth: Float, ) diff --git a/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartDefaults.kt b/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartDefaults.kt index 11b1db8..4f0dac1 100644 --- a/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartDefaults.kt +++ b/charty/src/main/java/com/himanshoe/charty/gauge/config/GaugeChartDefaults.kt @@ -26,7 +26,9 @@ object GaugeChartDefaults { strokeWidth = 48F, showNeedle = true, showIndicator = true, + showText = true, indicatorColor = Color(0xffed625d), + textColor = Color(0xffed625d), indicatorWidth = 8F ) diff --git a/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt b/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt index cf395f2..75ba912 100644 --- a/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt @@ -62,7 +62,9 @@ fun GroupedBarChart( ) { require(barWidthRatio in 0.4f..0.9f) { "barWidthRatio must be within the range of 0.4F to 0.9F, but use 0.8F for best looking View" } - val allDataPoints = groupBarDataCollection.data.flatMap { it.dataPoints } + val allDataPoints = remember (groupBarDataCollection.data) { + groupBarDataCollection.data.flatMap { it.dataPoints } + } val maxValue = allDataPoints.maxOrNull() ?: 0f val minValue = allDataPoints.minOrNull() ?: 0f val newItems = if (allDataPoints.min() > 0F) { @@ -164,9 +166,9 @@ private fun calculateBarX( barIndex: Int, barWidth: Float ) = (groupIndex * groupWidth) + - ((1 - barWidthRatio) / 2) * - groupWidth + - (barIndex * barWidth) + (barWidth / 2f) + ((1 - barWidthRatio) / 2) * + groupWidth + + (barIndex * barWidth) + (barWidth / 2f) private fun calculateBarHeight( barValue: Float, diff --git a/docs/GAUGECHART.md b/docs/GAUGECHART.md index 87c7690..72d0855 100644 --- a/docs/GAUGECHART.md +++ b/docs/GAUGECHART.md @@ -5,7 +5,8 @@ To use the GaugeChart, follow the steps below: - Include the Charty library in your Android project. - Use the `GaugeChart` composable in your code: -```kotlin @Composable +```kotlin +@Composable fun GaugeChart( percentValue: Int, modifier: Modifier = Modifier, @@ -28,7 +29,9 @@ fun GaugeChart( - Properties of `GaugeChartConfig`: - `placeHolderColor`: `Color` - Color of the background arc of the chart. Default is `Color.LightGray`. - `primaryColor`: `Color` - Color of the primary arc indicating the current value. Default is `Color.Blue`. + - `textColor`: `Color` - Color of the primary text indicating the current value. - `showNeedle`: `Boolean` - Specifies whether to show the needle indicating the current value. Default is `true`. + - `showText`: `Boolean` - Specifies whether to show the text of the current value. Default is `true`. - `showIndicator`: `Boolean` - Specifies whether to show the minute hour dividers. Default is `true`. - `indicatorColor`: `Color` - Color of the minute hour dividers. Default is `Color.Red`. - `indicatorWidth`: `Dp` - Width of the minute hour dividers. Default is `2.dp`. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bae6b64..32d89b3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -9,6 +9,6 @@ #Sun May 14 12:03:03 CEST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/quality/static-check.gradle b/quality/static-check.gradle index f78298a..5f91585 100644 --- a/quality/static-check.gradle +++ b/quality/static-check.gradle @@ -1,12 +1,6 @@ apply plugin: "io.gitlab.arturbosch.detekt" apply plugin: "org.jlleitschuh.gradle.ktlint" -android { - lintOptions { - warningsAsErrors true - abortOnError false - } -} ktlint { version = "0.37.2" @@ -16,4 +10,7 @@ ktlint { detekt { config = files("../quality/detekt-rules.yml") buildUponDefaultConfig = true +} +dependencies { + detektPlugins "io.nlopez.compose.rules:detekt:0.2.1" } \ No newline at end of file From 2588bd0eaaa84280cd5cc13d90d56672e1135d70 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Wed, 16 Aug 2023 15:35:51 +0200 Subject: [PATCH 2/3] Introduced: RefreshVersions --- app/build.gradle | 16 ++++++++-------- charty/build.gradle | 18 +++++++++--------- settings.gradle | 18 ++++++++++++++++++ versions.properties | 30 ++++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 versions.properties diff --git a/app/build.gradle b/app/build.gradle index 0374c70..bc7abd5 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -48,18 +48,18 @@ android { dependencies { implementation(project(":charty")) - implementation 'androidx.core:core-ktx:1.8.0' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1' - implementation 'androidx.activity:activity-compose:1.5.1' - implementation platform('androidx.compose:compose-bom:2022.10.00') + implementation 'androidx.core:core-ktx:_' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:_' + implementation 'androidx.activity:activity-compose:_' + implementation platform('androidx.compose:compose-bom:_') implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' implementation 'androidx.compose.material3:material3' - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' - androidTestImplementation platform('androidx.compose:compose-bom:2022.10.00') + testImplementation 'junit:junit:_' + androidTestImplementation 'androidx.test.ext:junit:_' + androidTestImplementation 'androidx.test.espresso:espresso-core:_' + androidTestImplementation platform('androidx.compose:compose-bom:_') androidTestImplementation 'androidx.compose.ui:ui-test-junit4' debugImplementation 'androidx.compose.ui:ui-tooling' debugImplementation 'androidx.compose.ui:ui-test-manifest' diff --git a/charty/build.gradle b/charty/build.gradle index b7349e0..70d3e44 100644 --- a/charty/build.gradle +++ b/charty/build.gradle @@ -54,12 +54,12 @@ mavenPublishing { } dependencies { - implementation 'androidx.core:core-ktx:1.10.1' - implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'com.google.android.material:material:1.9.0' + implementation 'androidx.core:core-ktx:_' + implementation 'androidx.appcompat:appcompat:_' + implementation 'com.google.android.material:material:_' //Compose - implementation platform('androidx.compose:compose-bom:2023.05.01') + implementation platform('androidx.compose:compose-bom:_') implementation 'androidx.compose.ui:ui' implementation 'androidx.compose.ui:ui-graphics' implementation 'androidx.compose.ui:ui-tooling-preview' @@ -69,12 +69,12 @@ dependencies { implementation 'androidx.compose.material:material-icons-extended' //time - implementation 'org.jetbrains.kotlinx:kotlinx-datetime:0.4.0' - lintChecks('com.slack.lint.compose:compose-lint-checks:1.2.0') + implementation 'org.jetbrains.kotlinx:kotlinx-datetime:_' + lintChecks('com.slack.lint.compose:compose-lint-checks:_') testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test.ext:junit:_' + androidTestImplementation 'androidx.test.espresso:espresso-core:_' - dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:1.8.20") + dokkaPlugin("org.jetbrains.dokka:android-documentation-plugin:_") } \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4bba256..09d5a76 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,6 +5,11 @@ pluginManagement { gradlePluginPortal() } } +plugins { + // See https://jmfayard.github.io/refreshVersions + id 'de.fayard.refreshVersions' version '0.51.0' +} + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { @@ -12,6 +17,19 @@ dependencyResolutionManagement { mavenCentral() } } + rootProject.name = "Charty" include ':app' include ':charty' + +refreshVersions { + featureFlags { + enable 'LIBS' + disable 'GRADLE_UPDATES' + } + + // ignore all non-stable releases + rejectVersionIf { + candidate.stabilityLevel != StabilityLevel.Stable + } +} \ No newline at end of file diff --git a/versions.properties b/versions.properties new file mode 100644 index 0000000..52e25c7 --- /dev/null +++ b/versions.properties @@ -0,0 +1,30 @@ +#### Dependencies and Plugin versions with their available updates. +#### Generated by `./gradlew refreshVersions` version 0.51.0 +#### +#### Don't manually edit or split the comments that start with four hashtags (####), +#### they will be overwritten by refreshVersions. +#### +#### suppress inspection "SpellCheckingInspection" for whole file +#### suppress inspection "UnusedProperty" for whole file + +version.androidx.activity=1.7.2 + +version.androidx.appcompat=1.6.1 + +version.androidx.compose=2023.08.00 + +version.androidx.core=1.10.1 + +version.androidx.lifecycle=2.6.1 + +version.androidx.test.espresso=3.5.1 + +version.androidx.test.ext.junit=1.1.5 + +version.com.slack.lint.compose..compose-lint-checks=1.2.0 + +version.google.android.material=1.9.0 + +version.junit.junit=4.13.2 + +version.kotlinx.datetime=0.4.0 From 0fb86a4f59159ae0eae96f12e2fdd46db1ea3172 Mon Sep 17 00:00:00 2001 From: Himanshu Date: Wed, 16 Aug 2023 15:40:43 +0200 Subject: [PATCH 3/3] Fix. Lint --- .../main/java/com/himanshoe/charty/group/GroupBarChart.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt b/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt index 75ba912..e2848b7 100644 --- a/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt +++ b/charty/src/main/java/com/himanshoe/charty/group/GroupBarChart.kt @@ -62,7 +62,7 @@ fun GroupedBarChart( ) { require(barWidthRatio in 0.4f..0.9f) { "barWidthRatio must be within the range of 0.4F to 0.9F, but use 0.8F for best looking View" } - val allDataPoints = remember (groupBarDataCollection.data) { + val allDataPoints = remember(groupBarDataCollection.data) { groupBarDataCollection.data.flatMap { it.dataPoints } } val maxValue = allDataPoints.maxOrNull() ?: 0f @@ -166,9 +166,9 @@ private fun calculateBarX( barIndex: Int, barWidth: Float ) = (groupIndex * groupWidth) + - ((1 - barWidthRatio) / 2) * - groupWidth + - (barIndex * barWidth) + (barWidth / 2f) + ((1 - barWidthRatio) / 2) * + groupWidth + + (barIndex * barWidth) + (barWidth / 2f) private fun calculateBarHeight( barValue: Float,