Skip to content

Commit

Permalink
Merge pull request #131 from hi-manshu/feat/barchart-v2
Browse files Browse the repository at this point in the history
Release 2.1.0-beta03.1🐙
  • Loading branch information
hi-manshu authored Feb 13, 2025
2 parents 6a9cd0d + 5f01fec commit ed29305
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 40 deletions.
2 changes: 1 addition & 1 deletion charty/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ POM_DESCRIPTION=An Elementary Compose Multiplatform Chart library.
POM_PACKAGING=aar
POM_INCEPTION_YEAR=2025
GROUP=com.himanshoe
VERSION_NAME=2.1.0-beta03
VERSION_NAME=2.1.0-beta03.1
VERSION_CODE=2
POM_URL=https://github.com/hi-manshu
POM_LICENCE_NAME=The Apache Software License, Version 2.0
Expand Down
86 changes: 50 additions & 36 deletions charty/src/commonMain/kotlin/com/himanshoe/charty/bar/BarChart.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.text.TextLayoutResult
import androidx.compose.ui.text.TextMeasurer
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.drawText
import androidx.compose.ui.text.rememberTextMeasurer
Expand All @@ -30,6 +31,7 @@ import androidx.compose.ui.util.fastForEachIndexed
import androidx.compose.ui.util.fastMaxOfOrNull
import com.himanshoe.charty.bar.config.BarChartColorConfig
import com.himanshoe.charty.bar.config.BarChartConfig
import com.himanshoe.charty.bar.config.BarTooltip
import com.himanshoe.charty.bar.model.BarData
import com.himanshoe.charty.bar.modifier.drawAxisLineForVerticalChart
import com.himanshoe.charty.bar.modifier.drawRangeLinesForVerticalChart
Expand Down Expand Up @@ -62,6 +64,7 @@ fun BarChart(
targetConfig: TargetConfig = TargetConfig.default(),
barChartConfig: BarChartConfig = BarChartConfig.default(),
labelConfig: LabelConfig = LabelConfig.default(),
barTooltip: BarTooltip? = null,
barChartColorConfig: BarChartColorConfig = BarChartColorConfig.default(),
onBarClick: (Int, BarData) -> Unit = { _, _ -> },
) {
Expand All @@ -72,6 +75,7 @@ fun BarChart(
targetConfig = targetConfig,
barChartConfig = barChartConfig,
labelConfig = labelConfig,
barTooltip = barTooltip,
barChartColorConfig = barChartColorConfig,
onBarClick = onBarClick
)
Expand All @@ -81,6 +85,7 @@ fun BarChart(
private fun BarChartContent(
data: () -> List<BarData>,
modifier: Modifier = Modifier,
barTooltip: BarTooltip? = null,
target: Float? = null,
targetConfig: TargetConfig = TargetConfig.default(),
barChartConfig: BarChartConfig = BarChartConfig.default(),
Expand All @@ -97,7 +102,7 @@ private fun BarChartContent(
val textMeasurer = rememberTextMeasurer()
val bottomPadding = if (labelConfig.showXLabel && !hasNegativeValues) 8.dp else 0.dp
val leftPadding = if (labelConfig.showYLabel) 24.dp else 0.dp
val topPadding = if (labelConfig.showTooltip) 24.dp else 0.dp
val topPadding = if (barTooltip != null) 24.dp else 0.dp

var clickedOffset by mutableStateOf(Offset.Zero)
var clickedBarIndex by mutableIntStateOf(-1)
Expand Down Expand Up @@ -227,48 +232,57 @@ private fun BarChartContent(
),
)
}
if (labelConfig.showYLabel) {
val yLabelTextLayoutResult = textMeasurer.measure(
text = barData.yValue.toString(),
style = labelConfig.labelTextStyle ?: TextStyle(
fontSize = (barWidth / textSizeFactor).toSp(),
brush = Brush.linearGradient(labelConfig.textColor.value)
),
overflow = TextOverflow.Clip,
maxLines = 1,
)
drawText(
textLayoutResult = yLabelTextLayoutResult,
topLeft = Offset(
x = individualBarTopLeft.x + barWidth / 2 - yLabelTextLayoutResult.size.width / 2,
y = individualBarTopLeft.y - yLabelTextLayoutResult.size.height,
),
)
}

if (labelConfig.showTooltip) {
val yValueTextLayoutResult = textMeasurer.measure(
text = barData.yValue.toInt().toString(),
style = labelConfig.labelTextStyle ?: TextStyle(
fontSize = (barWidth / textSizeFactor).toSp(),
brush = Brush.linearGradient(labelConfig.textColor.value)
),
overflow = TextOverflow.Clip,
maxLines = 1,
)
drawText(
textLayoutResult = yValueTextLayoutResult,
topLeft = Offset(
x = individualBarTopLeft.x + barWidth / 2 - yValueTextLayoutResult.size.width / 2,
y = backgroundTopLeftY - yValueTextLayoutResult.size.height - gap,
),
if (barTooltip != null) {
drawTooltip(
textMeasurer = textMeasurer,
barData = barData,
labelConfig = labelConfig,
barWidth = barWidth,
textSizeFactor = textSizeFactor,
barTooltip = barTooltip,
individualBarTopLeft = individualBarTopLeft,
gap = gap,
backgroundTopLeftY = backgroundTopLeftY
)
}
}
}
}
}

private fun DrawScope.drawTooltip(
textMeasurer: TextMeasurer,
barData: BarData,
labelConfig: LabelConfig,
barWidth: Float,
textSizeFactor: Int,
barTooltip: BarTooltip,
individualBarTopLeft: Offset,
gap: Float,
backgroundTopLeftY: Float
) {
val tooltipTextLayoutResult = textMeasurer.measure(
text = barData.yValue.toInt().toString(),
style = labelConfig.labelTextStyle ?: TextStyle(
fontSize = (barWidth / textSizeFactor).toSp(),
brush = Brush.linearGradient(labelConfig.textColor.value)
),
overflow = TextOverflow.Clip,
maxLines = 1,
)
val tooltipYOffset = when (barTooltip) {
BarTooltip.Default -> individualBarTopLeft.y - tooltipTextLayoutResult.size.height - gap
BarTooltip.GraphTop -> backgroundTopLeftY - tooltipTextLayoutResult.size.height - gap
}
drawText(
textLayoutResult = tooltipTextLayoutResult,
topLeft = Offset(
x = individualBarTopLeft.x + barWidth / 2 - tooltipTextLayoutResult.size.width / 2,
y = tooltipYOffset
),
)
}

private fun getCornerRadius(
barChartConfig: BarChartConfig,
cornerRadius: CornerRadius
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.himanshoe.charty.bar.config

sealed interface BarTooltip {

data object Default : BarTooltip
data object GraphTop : BarTooltip
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ data class LabelConfig(
val textColor: ChartColor,
val showXLabel: Boolean,
val showYLabel: Boolean,
val showTooltip: Boolean,
val xAxisCharCount: Int?,
val labelTextStyle: TextStyle?,
) {
Expand All @@ -30,7 +29,6 @@ data class LabelConfig(
xAxisCharCount = null,
labelTextStyle = null,
showYLabel = false,
showTooltip = false,
)
}
}
6 changes: 5 additions & 1 deletion sample/src/commonMain/kotlin/com/himanshoe/sample/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import com.himanshoe.charty.bar.StackedBarChart
import com.himanshoe.charty.bar.StorageBar
import com.himanshoe.charty.bar.config.BarChartColorConfig
import com.himanshoe.charty.bar.config.BarChartConfig
import com.himanshoe.charty.bar.config.BarTooltip
import com.himanshoe.charty.bar.model.BarData
import com.himanshoe.charty.bar.model.ComparisonBarData
import com.himanshoe.charty.bar.model.StackBarData
Expand Down Expand Up @@ -440,8 +441,11 @@ private fun LazyListScope.addBarChart(target: Float?, data: List<BarData>) {
item {
BarChart(modifier = Modifier.padding(10.dp).fillMaxWidth().height(300.dp),
target = target,
barTooltip = BarTooltip.GraphTop,
labelConfig = LabelConfig.default().copy(
showXLabel = true, xAxisCharCount = 4,
showXLabel = true,
xAxisCharCount = 4,
showYLabel = true,
textColor = Color(0xFFFF92C1).asSolidChartColor()
),
barChartColorConfig = BarChartColorConfig.default().copy(
Expand Down

0 comments on commit ed29305

Please sign in to comment.