Skip to content

Instantly share code, notes, and snippets.

@developerchunk
Last active December 6, 2022 02:18
Show Gist options
  • Save developerchunk/768bf8cefaae90784115012d1b588365 to your computer and use it in GitHub Desktop.
Save developerchunk/768bf8cefaae90784115012d1b588365 to your computer and use it in GitHub Desktop.
Create Custom BarGraph with Scales in Jetpack Compose Medium:
@Composable
fun BarGraph(
graphBarData: List<Float>,
xAxisScaleData: List<Int>,
barData_: List<Int>,
height: Dp,
roundType: BarType,
barWidth: Dp,
barColor: Color,
barArrangement: Arrangement.Horizontal
) {
val barData by remember {
mutableStateOf(barData_+0)
}
// for getting screen width and height you can use LocalConfiguration
val configuration = LocalConfiguration.current
// getting screen width
val width = configuration.screenWidthDp.dp
// bottom height of the X-Axis Scale
val xAxisScaleHeight = 40.dp
val yAxisScaleSpacing by remember {
mutableStateOf(100f)
}
val yAxisTextWidth by remember {
mutableStateOf(100.dp)
}
// bar shape
val barShap =
when (roundType) {
BarType.CIRCULAR_TYPE -> CircleShape
BarType.TOP_CURVED -> RoundedCornerShape(topStart = 5.dp, topEnd = 5.dp)
}
val density = LocalDensity.current
// y-axis scale text paint
val textPaint = remember(density) {
Paint().apply {
color = Color.Black.hashCode()
textAlign = Paint.Align.CENTER
textSize = density.run { 12.sp.toPx() }
}
}
// for y coordinates of y-axis scale to create horizontal dotted line indicating y-axis scale
val yCoordinates = mutableListOf<Float>()
// for dotted line effect
val pathEffect = PathEffect.dashPathEffect(floatArrayOf(10f, 10f), 0f)
// height of vertical line over x-axis scale connecting x-axis horizontal line
val lineHeightXAxis = 10.dp
// height of horizontal line over x-axis scale
val horizontalLineHeight = 5.dp
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.TopStart
) {
// Layer 1
// y-axis scale and horizontal dotted lines on graph indicating y-axis scale
Column(
modifier = Modifier
.padding(top = xAxisScaleHeight, end = 3.dp)
.height(height)
.fillMaxWidth(),
horizontalAlignment = CenterHorizontally
) {
Canvas(modifier = Modifier.padding(bottom = 10.dp).fillMaxSize()) {
// Y-Axis Scale Text
val yAxisScaleText = (barData.max()) / 3f
(0..3).forEach { i ->
drawContext.canvas.nativeCanvas.apply {
drawText(
round(barData.min() + yAxisScaleText * i).toString(),
30f,
size.height - yAxisScaleSpacing - i * size.height / 3f,
textPaint
)
}
yCoordinates.add(size.height - yAxisScaleSpacing - i * size.height / 3f)
}
// horizontal dotted lines on graph indicating y-axis scale
(1..3).forEach {
drawLine(
start = Offset(x = yAxisScaleSpacing +30f, y = yCoordinates[it]),
end = Offset(x= size.width, y = yCoordinates[it]),
color = Color.Gray,
strokeWidth = 5f,
pathEffect = pathEffect
)
}
}
}
// Layer 2
// Graph with Bar Graph and X-Axis Scale
Box(
modifier = Modifier
.padding(start = 50.dp)
.width(width - yAxisTextWidth)
.height(height + xAxisScaleHeight),
contentAlignment = Alignment.BottomCenter
) {
Row(
modifier = Modifier
.width(width - yAxisTextWidth),
verticalAlignment = Alignment.Top,
horizontalArrangement = barArrangement
) {
// Graph
graphBarData.forEachIndexed { index, value ->
var animationTriggered by remember {
mutableStateOf(false)
}
val graphBarHeight by animateFloatAsState(
targetValue = if (animationTriggered) value else 0f,
animationSpec = tween(
durationMillis = 1000,
delayMillis = 0
)
)
LaunchedEffect(key1 = true) {
animationTriggered = true
}
Column(
modifier = Modifier.fillMaxHeight(),
verticalArrangement = Top,
horizontalAlignment = CenterHorizontally
) {
// Each Graph
Box(
modifier = Modifier
.padding(bottom = 5.dp)
.clip(barShap)
.width(barWidth)
.height(height - 10.dp)
.background(Color.Transparent),
contentAlignment = BottomCenter
) {
Box(
modifier = Modifier
.clip(barShap)
.fillMaxWidth()
.fillMaxHeight(graphBarHeight)
.background(barColor)
)
}
// scale x-axis and bottom part of graph
Column(
modifier = Modifier
.height(xAxisScaleHeight),
verticalArrangement = Top,
horizontalAlignment = CenterHorizontally
) {
// small vertical line joining the horizontal x-axis line
Box(
modifier = Modifier
.clip(
RoundedCornerShape(
bottomStart = 2.dp,
bottomEnd = 2.dp
)
)
.width(horizontalLineHeight)
.height(lineHeightXAxis)
.background(color = Color.Gray)
)
// scale x-axis
Text(
modifier = Modifier.padding(bottom = 3.dp),
text = xAxisScaleData[index].toString(),
fontSize = 14.sp,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.Center,
color = Color.Black
)
}
}
}
}
// horizontal line on x-axis on the graph
Column(
modifier = Modifier
.fillMaxWidth()
.background(Color.Transparent),
horizontalAlignment = CenterHorizontally
) {
Box(
modifier = Modifier
.padding(bottom = xAxisScaleHeight + 3.dp)
.clip(RoundedCornerShape(2.dp))
.fillMaxWidth()
.height(horizontalLineHeight)
.background(Color.Gray)
)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment