Skip to content

Instantly share code, notes, and snippets.

@virendersran01
Forked from 7kashif/BarChart.kt
Created October 9, 2022 17:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save virendersran01/5dbbd6133ea88468bf818ec73eae9e65 to your computer and use it in GitHub Desktop.
Save virendersran01/5dbbd6133ea88468bf818ec73eae9e65 to your computer and use it in GitHub Desktop.
suspend fun LazyListState.getFirstVisibleAsState(index: (Int) -> Unit) {
this.interactionSource.interactions.collectLatest {
index(this.firstVisibleItemIndex)
}
}
data class WeeklyStat(
val earning: Float = 0.0f
)
internal fun List<WeeklyStat>.maxState(from: Int, to: Int) = maxOf {
this.subList(from, to).maxOf {
it.earning
}
}
private val statsList = listOf(
WeeklyStat(earning = 10000.0f),
WeeklyStat(earning = 15000.0f),
WeeklyStat(earning = 7000.0f),
WeeklyStat(earning = 20000.0f),
WeeklyStat(earning = 40000.0f),
WeeklyStat(earning = 50000.0f),
WeeklyStat(earning = 10000.0f),
WeeklyStat(earning = 60000.0f),
WeeklyStat(earning = 19000.0f),
WeeklyStat(earning = 10000.0f),
WeeklyStat(earning = 30000.0f),
WeeklyStat(earning = 78000.0f),
)
@Composable
fun BarChart(modifier: Modifier, onMaxValueChange: (Float) -> Unit) {
val listState = rememberLazyListState()
var selectedBar by remember {
mutableStateOf(0)
}
var maxHeight by remember {
mutableStateOf(statsList.maxState(0, 6))
}
val scope = rememberCoroutineScope()
onMaxValueChange(maxHeight)
LaunchedEffect(key1 = true, block = {
listState.getFirstVisibleAsState { index ->
maxHeight = statsList.maxState(index + 1, index + 7)
}
})
LazyRow(
modifier = modifier
.fillMaxWidth()
.height(300.dp),
state = listState,
contentPadding = PaddingValues(start = 8.dp, end = 8.dp, bottom = 4.dp, top = 4.dp),
horizontalArrangement = Arrangement.spacedBy(6.dp),
verticalAlignment = Alignment.Bottom
) {
itemsIndexed(statsList) { index, item ->
val barHeight = ((item.earning / maxHeight) * 294)
Text(
text = "${item.earning.toInt()}",
modifier = Modifier
.size(width = 52.dp, height = barHeight.dp)
.clickable {
selectedBar = index
}
.background(
color = if (index == selectedBar) Color(0xFF02BC87) else Color(0xFFF1F1F1),
shape = RoundedCornerShape(5.dp)
),
color = if (index == selectedBar) Color.White else Color(0xFF02BC87),
textAlign = TextAlign.Center,
fontSize = 10.sp
)
}
}
}
@Composable
fun BarChartView(modifier: Modifier = Modifier) {
var maxVal by remember {
mutableStateOf("")
}
var maxValMargin by remember {
mutableStateOf(0.0f)
}
ConstraintLayout(
modifier = modifier
.padding(end = 4.dp)
.background(Color.White)
.fillMaxWidth()
.height(304.dp)
) {
val (chart, minValue, maxValue, div, maxValueDiv) = createRefs()
Divider(
color = Color(0xFFF1F1F1),
thickness = 1.dp,
modifier = Modifier.constrainAs(maxValueDiv) {
start.linkTo(parent.start)
end.linkTo(div.start)
top.linkTo(maxValue.top)
bottom.linkTo(maxValue.bottom)
width = Dimension.fillToConstraints
}
)
BarChart(
modifier = Modifier.constrainAs(chart) {
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(maxValue.start, 4.dp)
width = Dimension.fillToConstraints
}
) {
val temp = it.toInt().toString()
var newTemp = ""
temp.forEachIndexed { index, c ->
newTemp += if (index == 0)
c
else
'0'
}
val margin = newTemp.trim().toInt()
val difference = it - margin
maxValMargin = (difference / it) * 100
maxVal = "$margin"
}
Divider(
color = Color(0xFFF1F1F1),
thickness = 1.dp,
modifier = Modifier
.width(1.dp)
.constrainAs(div) {
start.linkTo(chart.end)
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
height = Dimension.fillToConstraints
}
)
Text(
text = maxVal,
color = Color(0xFFB8B5C3),
modifier = Modifier.constrainAs(maxValue) {
top.linkTo(chart.top, (maxValMargin).dp)
start.linkTo(div.end, 4.dp)
end.linkTo(parent.end)
},
fontSize = 8.sp
)
Text(
text = "0",
color = Color(0xFFB8B5C3),
modifier = Modifier.constrainAs(minValue) {
bottom.linkTo(div.bottom)
start.linkTo(div.end, 4.dp)
},
fontSize = 8.sp
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment