Skip to content

Instantly share code, notes, and snippets.

@rezaiyan
Created March 8, 2025 18:11
Show Gist options
  • Save rezaiyan/490e7f79e28975c8699e497e58332f09 to your computer and use it in GitHub Desktop.
Save rezaiyan/490e7f79e28975c8699e497e58332f09 to your computer and use it in GitHub Desktop.
@Composable
fun PriceGraph(
priceHistory: List<Double>,
modifier: Modifier = Modifier,
lineColor: Color = Color.Black
) {
val path = remember { Path() }
val offsetX = remember { androidx.compose.animation.core.Animatable(0f) }
val animatedHead = animateFloatAsState(
targetValue = priceHistory.lastOrNull()?.toFloat() ?: 0f,
animationSpec = tween(durationMillis = 500)
).value
Canvas(
modifier = modifier
.fillMaxWidth()
.height(200.dp)
) {
path.reset()
if (priceHistory.size > 1) {
val totalPoints = priceHistory.size
val width = size.width
val headPositionX = width * (2f / 3f)
val widthStep = headPositionX / (totalPoints - 1)
path.moveTo(-offsetX.value, priceHistory[0].toFloat())
for (i in 1 until totalPoints - 1) {
val prevX = (i - 1) * widthStep - offsetX.value
val prevY = priceHistory[i - 1].toFloat()
val currX = i * widthStep - offsetX.value
val currY = priceHistory[i].toFloat()
val midX = (prevX + currX) / 2
val midY = (prevY + currY) / 2
path.quadraticBezierTo(prevX, prevY, midX, midY)
}
path.quadraticBezierTo(
(totalPoints - 2) * widthStep - offsetX.value,
priceHistory[totalPoints - 2].toFloat(),
headPositionX,
animatedHead
)
}
drawPath(path, color = lineColor, style = Stroke(width = 5f))
}
}
@Composable
fun RealTimeBitcoinGraph() {
val priceHistory = remember { mutableStateListOf<Double>() }
val maxPoints = 30
LaunchedEffect(Unit) {
while (true) {
val newPrice = 1000 + (Math.random() * 500)
if (priceHistory.size >= maxPoints) {
priceHistory.removeAt(0)
}
priceHistory.add(newPrice)
delay(1000)
}
}
PriceGraph(priceHistory)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment