diff --git a/androidApp/src/screenshotTest/kotlin/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTest.kt b/androidApp/src/screenshotTest/kotlin/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTest.kt index a1193c40..96524a5b 100644 --- a/androidApp/src/screenshotTest/kotlin/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTest.kt +++ b/androidApp/src/screenshotTest/kotlin/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTest.kt @@ -27,14 +27,34 @@ fun BarChartDefaultPreview() { @Composable fun BarChartCustomPreview() { ScreenshotSurface { + val dataSet = SCREENSHOT_BAR_SAMPLE_USE_CASE.initialBarDataSet() BarChart( - dataSet = SCREENSHOT_BAR_SAMPLE_USE_CASE.initialBarDataSet(), + dataSet = dataSet, style = ChartTestStyleFixtures.barCustomStyle(chartViewStyle = ChartViewDefaults.style()), animateOnStart = SCREENSHOT_ANIMATE_ON_START, ) } } +@PreviewTest +@ScreenshotPreview +@Composable +fun BarChartCustomBarColorsPreview() { + ScreenshotSurface { + val dataSet = SCREENSHOT_BAR_SAMPLE_USE_CASE.initialBarDataSet() + BarChart( + dataSet = dataSet, + style = + ChartTestStyleFixtures.barCustomStyle( + chartViewStyle = ChartViewDefaults.style(), + barCount = dataSet.data.item.points.size, + useBarColors = true, + ), + animateOnStart = SCREENSHOT_ANIMATE_ON_START, + ) + } +} + @PreviewTest @ScreenshotPreview @Composable diff --git a/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Dark_9cfa4316_0.png b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Dark_9cfa4316_0.png new file mode 100644 index 00000000..8f3e0d59 Binary files /dev/null and b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Dark_9cfa4316_0.png differ diff --git a/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet Landscape_5e637cf0_0.png b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet Landscape_5e637cf0_0.png new file mode 100644 index 00000000..cef3f19b Binary files /dev/null and b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet Landscape_5e637cf0_0.png differ diff --git a/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet_9301444c_0.png b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet_9301444c_0.png new file mode 100644 index 00000000..fd2e48d1 Binary files /dev/null and b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light Tablet_9301444c_0.png differ diff --git a/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light_bb9fafb0_0.png b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light_bb9fafb0_0.png new file mode 100644 index 00000000..c09b1137 Binary files /dev/null and b/androidApp/src/screenshotTestDebug/reference/io/github/dautovicharis/charts/app/screenshot/BarChartScreenshotTestKt/BarChartCustomBarColorsPreview_Light_bb9fafb0_0.png differ diff --git a/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarChartStyleItems.kt b/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarChartStyleItems.kt index fa118767..f36ec993 100644 --- a/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarChartStyleItems.kt +++ b/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarChartStyleItems.kt @@ -23,17 +23,21 @@ object BarChartStyleItems { @Composable fun customStyle( + barCount: Int, minValue: Float, maxValue: Float, aspectRatioPreset: ChartAspectRatioPreset = ChartAspectRatioPreset.Square, ) = ChartTestStyleFixtures.barCustomStyle( chartViewStyle = chartViewStyle(aspectRatioPreset), + barCount = barCount, + useBarColors = true, minValue = minValue, maxValue = maxValue, ) @Composable fun custom( + barCount: Int, minValue: Float, maxValue: Float, aspectRatioPreset: ChartAspectRatioPreset = ChartAspectRatioPreset.Square, @@ -41,6 +45,7 @@ object BarChartStyleItems { ChartStyleItems( currentStyle = customStyle( + barCount = barCount, minValue = minValue, maxValue = maxValue, aspectRatioPreset = aspectRatioPreset, diff --git a/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarDemo.kt b/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarDemo.kt index b4810376..91d7ed17 100644 --- a/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarDemo.kt +++ b/app/src/commonMain/kotlin/io/github/dautovicharis/charts/app/demo/bar/BarDemo.kt @@ -57,6 +57,7 @@ fun BarChartDemo( ChartPreset.Default -> BarChartStyleItems.default(aspectRatioPreset) ChartPreset.Custom -> BarChartStyleItems.custom( + barCount = dataSet.data.item.points.size, minValue = controlsState.minValue.toFloat(), maxValue = controlsState.maxValue.toFloat(), aspectRatioPreset = aspectRatioPreset, @@ -120,6 +121,7 @@ fun BarChartDemo( dataSet = dataSet, style = BarChartStyleItems.customStyle( + barCount = dataSet.data.item.points.size, minValue = controlsState.minValue.toFloat(), maxValue = controlsState.maxValue.toFloat(), aspectRatioPreset = aspectRatioPreset, diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/BarChart.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/BarChart.kt index 966f57c9..d2220554 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/BarChart.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/BarChart.kt @@ -30,9 +30,10 @@ fun BarChart( selectedBarIndex: Int = NO_SELECTION, ) { val errors = - remember(dataSet) { + remember(dataSet, style.barColors) { validateBarData( data = dataSet.data.item, + colorsSize = style.barColors.size, ) } diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/BarValidation.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/BarValidation.kt index c8f3c87a..630886c4 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/BarValidation.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/BarValidation.kt @@ -1,10 +1,14 @@ package io.github.dautovicharis.charts.internal import io.github.dautovicharis.charts.internal.ValidationErrors.MIN_REQUIRED_BAR +import io.github.dautovicharis.charts.internal.ValidationErrors.RULE_COLORS_SIZE_MISMATCH import io.github.dautovicharis.charts.internal.common.model.ChartData @InternalChartsApi -fun validateBarData(data: ChartData): List { +fun validateBarData( + data: ChartData, + colorsSize: Int = 0, +): List { val validationErrors = mutableListOf() val pointsSize = data.points.size @@ -15,6 +19,12 @@ fun validateBarData(data: ChartData): List { return validationErrors } + if (colorsSize > 0 && colorsSize != pointsSize) { + val validationError = + RULE_COLORS_SIZE_MISMATCH.format(colorsSize, pointsSize) + validationErrors.add(validationError) + } + data.points.forEachIndexed { index, value -> if (value.isNaN()) { val validationError = ValidationErrors.RULE_DATA_POINT_NOT_NUMBER.format(index) diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChart.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChart.kt index d634f85e..ddf1f636 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChart.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChart.kt @@ -42,7 +42,11 @@ internal fun BarChart( selectedBarIndex: Int = NO_SELECTION, onValueChanged: (Int) -> Unit = {}, ) { - val barColor = style.barColor.copy(alpha = style.barAlpha) + val baseBarColor = style.barColor.copy(alpha = style.barAlpha) + val sourceBarColors = + remember(style.barColors, style.barAlpha) { + style.barColors.map { color -> color.copy(alpha = style.barAlpha) } + } val isPreview = LocalInspectionMode.current val sourceDataSize = chartData.points.size BoxWithConstraints(modifier = style.modifier) { @@ -87,6 +91,17 @@ internal fun BarChart( } var denseExpanded by rememberDenseExpandedState(isDenseModeAvailable = isDenseData) val compactDenseMode = isDenseData && !denseExpanded + val compactBarCenterIndices = + remember(sourceDataSize, compactDenseMode, maxFitBars) { + if (compactDenseMode) { + compactDensityCenterIndices( + sourcePointsCount = sourceDataSize, + targetPoints = maxFitBars, + ) + } else { + emptyList() + } + } val renderData = remember(chartData, compactDenseMode, maxFitBars) { if (compactDenseMode) { @@ -98,6 +113,17 @@ internal fun BarChart( chartData } } + val renderBarColors = + remember(sourceBarColors, compactBarCenterIndices, compactDenseMode, baseBarColor) { + when { + sourceBarColors.isEmpty() -> emptyList() + !compactDenseMode -> sourceBarColors + else -> + compactBarCenterIndices.map { centerIndex -> + sourceBarColors.getOrElse(centerIndex) { baseBarColor } + } + } + } val dataSize = renderData.points.size val hasFixedRange = style.minValue != null || style.maxValue != null val (fixedMin, fixedMax) = @@ -214,7 +240,8 @@ internal fun BarChart( interactionEnabled = interactionEnabled, dragSelectionEnabled = !isScrollable, animatedValues = animatedValues, - barColor = barColor, + barColors = renderBarColors, + defaultBarColor = baseBarColor, fixedMin = fixedMin, fixedMax = fixedMax, isScrollable = isScrollable, diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartContent.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartContent.kt index a871bc84..d8c99cf9 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartContent.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartContent.kt @@ -40,7 +40,8 @@ internal fun BarChartContent( interactionEnabled: Boolean, dragSelectionEnabled: Boolean, animatedValues: List>, - barColor: Color, + barColors: List, + defaultBarColor: Color, fixedMin: Double, fixedMax: Double, isScrollable: Boolean, @@ -282,7 +283,8 @@ internal fun BarChartContent( animatedValues = animatedValues, visibleRange = visibleRange, selectedIndex = selectedIndex, - barColor = barColor, + barColors = barColors, + defaultBarColor = defaultBarColor, maxValue = fixedMax, minValue = fixedMin, barWidthPx = barWidthPx, diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartDrawing.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartDrawing.kt index e0950f06..9aa9dc68 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartDrawing.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartDrawing.kt @@ -16,7 +16,8 @@ internal fun DrawScope.drawBars( animatedValues: List>, visibleRange: IntRange, selectedIndex: Int, - barColor: Color, + barColors: List, + defaultBarColor: Color, maxValue: Double, minValue: Double, barWidthPx: Float, @@ -70,9 +71,10 @@ internal fun DrawScope.drawBars( val barHeight = abs(value) * size.height val top = if (value >= 0f) clampedBaselineY - barHeight else clampedBaselineY val left = unitWidth * index + val resolvedBarColor = barColors.getOrNull(index) ?: defaultBarColor drawRect( - color = barColor, + color = resolvedBarColor, topLeft = Offset(x = left, y = top), size = androidx.compose.ui.geometry.Size( diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartHelpers.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartHelpers.kt index b259624f..ac45205b 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartHelpers.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/internal/barchart/BarChartHelpers.kt @@ -101,6 +101,22 @@ internal fun aggregateForCompactDensity( return aggregatedPoints.toChartData(labels = aggregatedLabels) } +internal fun compactDensityCenterIndices( + sourcePointsCount: Int, + targetPoints: Int = BAR_DENSE_THRESHOLD, +): List { + if (sourcePointsCount <= 0) return emptyList() + if (targetPoints <= 1 || sourcePointsCount <= targetPoints) { + return List(sourcePointsCount) { index -> index } + } + + val bucketSize = bucketSizeForTargetCore(totalPoints = sourcePointsCount, targetPoints = targetPoints) + val bucketRanges = buildBucketRangesCore(totalPoints = sourcePointsCount, bucketSize = bucketSize) + return bucketRanges.map { range -> + range.first + ((range.last - range.first) / 2) + } +} + internal fun maxBarsThatFit( viewportWidthPx: Float, spacingPx: Float, diff --git a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/style/BarChartStyle.kt b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/style/BarChartStyle.kt index 1882fac8..08bbec09 100644 --- a/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/style/BarChartStyle.kt +++ b/charts-bar/src/commonMain/kotlin/io/github/dautovicharis/charts/style/BarChartStyle.kt @@ -16,6 +16,7 @@ import androidx.compose.ui.unit.sp * @property modifier The modifier to be applied to the chart. * @property chartViewStyle The style to be applied to the chart view. * @property barColor The color to be used for the bars in the chart. + * @property barColors Optional explicit colors used for individual bars. * @property barAlpha The alpha value applied to rendered bars. * @property space The space between the bars in the chart. * @property minValue Optional fixed minimum value for the chart scale. @@ -46,6 +47,7 @@ class BarChartStyle( val modifier: Modifier, val chartViewStyle: ChartViewStyle, val barColor: Color, + val barColors: List, val barAlpha: Float, val space: Dp, val minValue: Float?, @@ -77,6 +79,7 @@ class BarChartStyle( override fun getProperties(): List> = listOf( BarChartStyle::barColor.name to barColor, + BarChartStyle::barColors.name to barColors, BarChartStyle::barAlpha.name to barAlpha, BarChartStyle::space.name to space, BarChartStyle::minValue.name to (minValue ?: "auto"), @@ -127,6 +130,7 @@ object BarChartDefaults { * Returns a BarChartStyle with the provided parameters or their default values. * * @param barColor The color to be used for the bars in the chart. Defaults to the primary color of the MaterialTheme. + * @param barColors Optional explicit colors used for individual bars. Defaults to an empty list. * @param barAlpha The alpha value applied to rendered bars. Defaults to 0.4f in light theme and 0.6f in dark theme. * @param space The space between the bars in the chart. Defaults to 10.dp. * @param minValue Optional fixed minimum value for the chart scale. Defaults to null. @@ -156,6 +160,7 @@ object BarChartDefaults { @Composable fun style( barColor: Color = MaterialTheme.colorScheme.primary, + barColors: List = emptyList(), barAlpha: Float = defaultChartAlpha(), space: Dp = 10.dp, minValue: Float? = null, @@ -187,6 +192,7 @@ object BarChartDefaults { return BarChartStyle( modifier = modifier, barColor = barColor, + barColors = barColors, barAlpha = barAlpha.coerceIn(0f, 1f), space = space, minValue = minValue, diff --git a/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/ui/BarChartTest.kt b/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/ui/BarChartTest.kt index 7d023ec7..190ba1ee 100644 --- a/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/ui/BarChartTest.kt +++ b/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/ui/BarChartTest.kt @@ -1,5 +1,6 @@ package io.github.dautovicharis.charts.ui +import androidx.compose.ui.graphics.Color import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertTextEquals import androidx.compose.ui.test.isDisplayed @@ -9,6 +10,7 @@ import androidx.compose.ui.test.runComposeUiTest import io.github.dautovicharis.charts.BarChart import io.github.dautovicharis.charts.internal.TestTags import io.github.dautovicharis.charts.internal.ValidationErrors.MIN_REQUIRED_BAR +import io.github.dautovicharis.charts.internal.ValidationErrors.RULE_COLORS_SIZE_MISMATCH import io.github.dautovicharis.charts.internal.ValidationErrors.RULE_DATA_POINTS_LESS_THAN_MIN import io.github.dautovicharis.charts.internal.common.model.ChartDataType import io.github.dautovicharis.charts.internal.format @@ -16,6 +18,7 @@ import io.github.dautovicharis.charts.mock.MockTest.TITLE import io.github.dautovicharis.charts.mock.MockTest.dataSet import io.github.dautovicharis.charts.model.ChartDataSet import io.github.dautovicharis.charts.model.toChartDataSet +import io.github.dautovicharis.charts.style.BarChartDefaults import kotlin.test.Test import kotlin.test.assertTrue @@ -104,4 +107,47 @@ class BarChartTest { assertTrue(lastLabelBounds.right <= axisBounds.right - 1f) } + + @OptIn(ExperimentalTestApi::class) + @Test + fun barChart_withMatchingBarColors_displaysChart() = + runComposeUiTest { + setContent { + val style = + BarChartDefaults.style( + barColors = listOf(Color.Red, Color.Green, Color.Blue, Color.Cyan), + ) + BarChart( + dataSet = dataSet, + style = style, + ) + } + + onNodeWithTag(TestTags.BAR_CHART).isDisplayed() + } + + @OptIn(ExperimentalTestApi::class) + @Test + fun barChart_withInvalidBarColors_displaysError() = + runComposeUiTest { + val expectedError = + RULE_COLORS_SIZE_MISMATCH.format( + 2, + dataSet.data.item.points.size, + ) + + setContent { + val style = + BarChartDefaults.style( + barColors = listOf(Color.Red, Color.Green), + ) + BarChart( + dataSet = dataSet, + style = style, + ) + } + + onNodeWithTag(TestTags.CHART_ERROR).isDisplayed() + onNodeWithText("${expectedError}\n").isDisplayed() + } } diff --git a/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/unit/helpers/BarChartHelpersTest.kt b/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/unit/helpers/BarChartHelpersTest.kt index 7f10d51d..b1953f85 100644 --- a/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/unit/helpers/BarChartHelpersTest.kt +++ b/charts-bar/src/commonTest/kotlin/io/github/dautovicharis/charts/unit/helpers/BarChartHelpersTest.kt @@ -4,6 +4,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.unit.IntSize import io.github.dautovicharis.charts.internal.barchart.YAxisTick import io.github.dautovicharis.charts.internal.barchart.buildYAxisTicks +import io.github.dautovicharis.charts.internal.barchart.compactDensityCenterIndices import io.github.dautovicharis.charts.internal.barchart.contentWidth import io.github.dautovicharis.charts.internal.barchart.estimateXAxisLabelFootprintPx import io.github.dautovicharis.charts.internal.barchart.estimateYAxisLabelWidthPx @@ -135,6 +136,28 @@ class BarChartHelpersTest { assertEquals(expected = 25, actual = capacity) } + @Test + fun compactDensityCenterIndices_nonDense_returnsIdentityIndices() { + val centers = + compactDensityCenterIndices( + sourcePointsCount = 8, + targetPoints = 12, + ) + + assertEquals(expected = listOf(0, 1, 2, 3, 4, 5, 6, 7), actual = centers) + } + + @Test + fun compactDensityCenterIndices_dense_returnsBucketCenters() { + val centers = + compactDensityCenterIndices( + sourcePointsCount = 10, + targetPoints = 4, + ) + + assertEquals(expected = listOf(1, 4, 7, 9), actual = centers) + } + @Test fun getSelectedIndexForContentX_clampsNegativeAndOverflowCoordinates() { val unit = unitWidth(barWidthPx = 8f, spacingPx = 2f) diff --git a/charts-demo-shared/src/commonMain/kotlin/io/github/dautovicharis/charts/demoshared/fixtures/ChartTestStyleFixtures.kt b/charts-demo-shared/src/commonMain/kotlin/io/github/dautovicharis/charts/demoshared/fixtures/ChartTestStyleFixtures.kt index 11370a6f..615b6026 100644 --- a/charts-demo-shared/src/commonMain/kotlin/io/github/dautovicharis/charts/demoshared/fixtures/ChartTestStyleFixtures.kt +++ b/charts-demo-shared/src/commonMain/kotlin/io/github/dautovicharis/charts/demoshared/fixtures/ChartTestStyleFixtures.kt @@ -78,13 +78,22 @@ object ChartTestStyleFixtures { @Composable fun barCustomStyle( chartViewStyle: ChartViewStyle, + barCount: Int = 1, + useBarColors: Boolean = false, minValue: Float? = null, maxValue: Float? = null, ): BarChartStyle { val chartColors = LocalChartColors.current + val barColors = + if (useBarColors) { + chartColors.seriesColors(barCount.coerceAtLeast(1)) + } else { + emptyList() + } return BarChartDefaults.style( chartViewStyle = chartViewStyle, barColor = chartColors.seriesColor(4), + barColors = barColors, minValue = minValue, maxValue = maxValue, gridColor = chartColors.gridLine,