Vivek Modi
Vivek Modi

Reputation: 7151

How to draw vertical line in canvas jetpack compose

I have value in Percentage from 0 to 100% which is in Float type . I am drawing vertical lines, I am using Offset which value is also in Float type. So how can I convert values in pixel values?

Values are

 Pixel in size 996.0
2023-02-12 19:02:01.063 13417-13417 MainActivity            com.example.queueapplication         E  name Low --++-- startPoint 0.0 --++-- endPoint 16.666666 
2023-02-12 19:02:01.064 13417-13417 MainActivity            com.example.queueapplication         E  name Normal --++-- startPoint 16.666666 --++-- endPoint 33.333332 
2023-02-12 19:02:01.064 13417-13417 MainActivity            com.example.queueapplication         E  name Elevated --++-- startPoint 33.333332 --++-- endPoint 50.0 
2023-02-12 19:02:01.064 13417-13417 MainActivity            com.example.queueapplication         E  name High --++-- startPoint 50.0 --++-- endPoint 66.666664 
2023-02-12 19:02:01.064 13417-13417 MainActivity            com.example.queueapplication         E  name Very High --++-- startPoint 66.666664 --++-- endPoint 83.33333 
2023-02-12 19:02:01.064 13417-13417 MainActivity            com.example.queueapplication         E  name Extremely High --++-- startPoint 83.33333 --++-- endPoint 100.0 

I tried this pieced of code

@Composable
fun DrawProgressBar() {
    val activity = LocalContext.current as AppCompatActivity
    val rangeComposition = RangeComposition()
    val itemLst = rangeComposition.bpExplained
    val boxSize = 30.dp
    Box(
        modifier = Modifier
            .background(Color.LightGray)
            .height(height = boxSize)
    ) {
        Canvas(
            modifier = Modifier
                .fillMaxWidth()
        ) {
            val canvasWidth = size.width
            drawLine(
                start = Offset(x = 0f, y = (boxSize / 2).toPx()),
                end = Offset(x = canvasWidth, y = (boxSize / 2).toPx()),
                color = Color.Black,
                strokeWidth = 8.dp.toPx(),
            )
            activity.logE("Pixel in size $canvasWidth")
            itemLst.forEach { rangeItem ->
                val endPointInPixel = rangeItem.endPoint
                activity.logE("name ${rangeItem.name} --++-- startPoint ${rangeItem.startPoint} --++-- endPoint ${rangeItem.endPoint} ")
                drawLine(
                    start = Offset(x = endPointInPixel, y = 0F),
                    end = Offset(x = endPointInPixel, y = boxSize.toPx()),
                    color = Color.Black,
                    strokeWidth = 4.dp.toPx(),
                )
            }
        }
    }
}

Actual Output

enter image description here

My all lines is taking Float value and draw very close to each other.

Expected Output

enter image description here

Upvotes: 1

Views: 1091

Answers (1)

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363785

You can divide the width of the Canvas for the number of steps to get the width of each step, or you can multiply the width of the canvas for the percentage to get the value of the offset.

Something like:

   Canvas(Modifier.fillMaxSize()) {

        val strokeWidth = 2.dp
        val color = Black

        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val width = size.width
        val height = size.height

        drawLine(
            start = Offset(x = 0f, y = height / 2),
            end = Offset(x = width, y = height / 2),
            color = color,
            strokeWidth = strokeWidthPx,
        )

        val stepCount = itemsList.size + 1
        val stepWidth = (width / stepCount).toFloat()
        itemsList.forEach { index ->
            val endPointInPixel = stepWidth * (index + 1)

            drawLine(
                start = Offset(x = endPointInPixel, y = 0F),
                end = Offset(x = endPointInPixel, y = height),
                color = color,
                strokeWidth = strokeWidthPx,
            )
        }

    }

enter image description here

Upvotes: 2

Related Questions