Compose Canvas 折线图

package com.anguomob.compose.ui.components

import android.util.Log
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Divider
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.ConstraintLayout
import androidx.constraintlayout.compose.ConstraintSet
import androidx.constraintlayout.compose.Dimension
import coil.compose.AsyncImage
import com.anguomob.compose.model.ArticleEntity
import com.anguomob.compose.model.VideoEntity

private const val TAG = "ChartView"

@Composable
fun ChartView(modifier: Modifier = Modifier, points: List<Float>) {
    //每一行的高度
    val heightForRow = 24

    //总行数
    val countForRow = 5

    //小圆圈半径
    val circleRadius = 2.5

    //画布宽度
    val canvasWidth = LocalConfiguration.current.screenWidthDp - 8 * 2
    //画布高度
    val canvasHeight = heightForRow * countForRow + circleRadius * 2

    //没8 dp 代表1积分 每一行 3积分
    val perY = 8 //24 * 5 /15

    //七平分宽度
    val averageOfWidth = canvasWidth / 7


    Canvas(modifier = modifier.size(width = canvasWidth.dp, canvasHeight.dp), onDraw = {
        //背景横线
        for (index in 0..countForRow) {
            val startY = (index * heightForRow.toFloat() + circleRadius).dp.toPx()
            val endX = size.width
            val endY = startY
            drawLine(Color(0xFFEEEEEE),
                start = Offset(x = 0f, y = startY),
                end = Offset(x = endX, y = endY),
                strokeWidth = 2.5f)
        }

        //画小圆圈、折线
        for (index in 0 until points.count()) {
            Log.e(TAG, "index:${index} ");
            val centerX = (averageOfWidth * index + averageOfWidth / 2).dp.toPx()
            val centerY =
                (heightForRow * countForRow - points[index] * perY + circleRadius).dp.toPx()
            val circleCenter = Offset(centerX, centerY)
            //点
            drawCircle(Color(0xff149ee7), radius = circleRadius.dp.toPx(),
                center = circleCenter,
                style = Stroke(width = 5f)
            )
            //线
            if (index < points.count() - 1) {
                val nextPointOffsetX = (averageOfWidth * (index + 1) + averageOfWidth / 2).dp.toPx()
                val nextPointOffsetY =
                    (heightForRow * countForRow - points[(index + 1)] * perY + circleRadius).dp.toPx()
                val nextPoint = Offset(nextPointOffsetX, nextPointOffsetY)
                drawLine(Color(0xFF149EE7), start = circleCenter, end = nextPoint, strokeWidth = 5f)
            }

        }
    })
}

数据为

var pointsOfWeek by mutableStateOf(listOf(3f, 2f, 6f, 9.3f, 10f, 15f, 8f))
    private set

效果为

下面的周几是因为没有drawText

所以

            Row() {
                        taskViewModel.weeks.forEach {
                            Text(text = it,
                                color = Color(0xff999999),
                                fontSize = 12.sp,
                                modifier = Modifier.weight(1f),
                                textAlign = TextAlign.Center
                            )
                        }
                    }

    val weeks = listOf("02.05", "02.06", "02.07", "02.08", "02.09", "02.10", "今日")

猜你喜欢

转载自blog.csdn.net/mp624183768/article/details/125827717