Reputation: 377
I'm drawing chart in Jetpack Compose, with x labels written using drawIntoCanvas
method. Basically very simple block of code:
data.forEachIndexed { index, point ->
drawIntoCanvas {
it.nativeCanvas.drawText(
"${point.x}",
chartCanvasStartX + index * intervalX,
size.height + 4.dp.toPx(),
textPaint
)
}
}
However I would like to achieve those labels to be sloped at desired angle, to fit longer text. I've tried applying rotation to the canvas, but that produces output, where whole canvas is rotated, not the individual iterations of this forEach loop. Even using methods like canvas.save()
and canvas.restore()
between angle transformation didn't produce desired output. Maybe in Compose declarative world there is some simpler solution for drawing such a texts?
Here is mockup for visualization of what I would like to achieve:
Note: Whole chart is written in single Compose Canvas
method, because I want to have reference to every x value of chart to place label precisely at this point, so I don't want to place any Column
with regular Compose Text
with rotate modifier applied.
Upvotes: 2
Views: 4957
Reputation: 87924
Generally using android.graphics.Canvas
you can rotate the canvas before drawing the item, and then invert the rotation.
But also compose has a built-in solution for such cases: rotate
will take effect only for the elements drawn inside the block:
Canvas(modifier = Modifier.fillMaxSize()) {
val rect = Rect(Offset.Zero, size)
drawLine(Color.Yellow, start = rect.topLeft, end = rect.bottomRight, strokeWidth = 20f)
rotate(degrees = -45f, rect.center) {
drawIntoCanvas { canvas ->
canvas.nativeCanvas.drawText(
"1",
rect.center.x, rect.center.y,
android.graphics.Paint().apply {
color = Color.Red.toArgb()
textSize = 100f
}
)
}
}
drawLine(Color.Green.copy(alpha = 0.5f), start = rect.topRight, end = rect.bottomLeft, strokeWidth = 20f)
}
Result of my sample code (both before and after drawn lines are not rotated):
Upvotes: 4