ehsannarmani / ComposeCharts

Animated & Flexible Practical Charts For Jetpack Compose
https://ehsannarmani.github.io/ComposeCharts/
Apache License 2.0
388 stars 25 forks source link

Pie Chart onClick Issue #49

Closed msshin0202 closed 2 weeks ago

msshin0202 commented 2 weeks ago
val data = remember {
                    mutableStateListOf(
                        Pie(label = "Android", data = 20.0, color = Color.Red, selectedColor = Color.Green),
                        Pie(label = "Windows", data = 45.0, color = Color.Cyan, selectedColor = Color.Blue),
                        Pie(label = "Linux", data = 35.0, color = Color.Gray, selectedColor = Color.Yellow),
                    )
                }
                PieChart(
                    modifier = Modifier.size(200.dp),
                    data = data,
                    onPieClick = { clickedPie ->
                        val index = data.indexOfFirst { it == clickedPie }
                        if (index != -1) {
                            data[index] = data[index].copy(selected = !data[index].selected)
                        }
                    },
                    selectedScale = 1.2f,
                    scaleAnimEnterSpec = spring<Float>(
                        dampingRatio = Spring.DampingRatioMediumBouncy,
                        stiffness = Spring.StiffnessLow
                    ),
                    colorAnimEnterSpec = tween(300),
                    colorAnimExitSpec = tween(300),
                    scaleAnimExitSpec = tween(300),
                    spaceDegreeAnimExitSpec = tween(300),
                    style = Pie.Style.Fill
                )

Using this Pie Chart as followed in the documentation seems to have issues animating. After some debugging it seems like there's some issue with the onPieClick listener where the data is is not being overwritten properly. I am pretty sure that the way I have set up the remember with the mutableStateListOf should be sufficient for recomposition when I trigger a change within the data but doesn't seem to be doing that. I've also tried the way it shows in the documentation with only remember and a var for the data and replacing the entire data list instead of modifying a single Pie object, but same issue.

ehsannarmani commented 2 weeks ago

Hi @msshin0202 , dead you print something in onPieClick? i dont understand your problem is chart recomposition after data change or your have problem with onPieClick calls

msshin0202 commented 2 weeks ago

Hey @ehsannarmani I'm just not getting any animation when I use that code above. Am I missing something in the code? I am updating the data with the selected state but nothing happens. What's weird is that with print statements it works to go into the lambda but any print statements I put after data = ... doesn't print out suggesting either a crash or some other issue.

ehsannarmani commented 2 weeks ago

try this: data = data.toList()

msshin0202 commented 2 weeks ago

Oh yes that worked! Thanks so much!

msshin0202 commented 2 weeks ago

@ehsannarmani out of curiosity though, why does doing something like this, not work?

var data = remember {
        listOf(
            Pie(label = "Android", data = 20.0, color = Color.Red, selectedColor = Color.Green),
            Pie(label = "Windows", data = 45.0, color = Color.Cyan, selectedColor = Color.Blue),
            Pie(label = "Linux", data = 35.0, color = Color.Gray, selectedColor = Color.Yellow),
        )
    }
    PieChart(
        modifier = modifier.size(200.dp),
        data = data.toList(),
        onPieClick = { clickedPie ->
            val pieIndex = data.indexOf(clickedPie)
            data = data.mapIndexed { mapIndex, pie -> pie.copy(selected = pieIndex == mapIndex) }
        },
        selectedScale = 1.2f,
        scaleAnimEnterSpec = spring<Float>(
            dampingRatio = Spring.DampingRatioMediumBouncy,
            stiffness = Spring.StiffnessLow
        ),
        colorAnimEnterSpec = tween(300),
        colorAnimExitSpec = tween(300),
        scaleAnimExitSpec = tween(300),
        spaceDegreeAnimExitSpec = tween(300),
        style = Pie.Style.Fill
    )

It's essentially the same as what I had before, but instead using your documentation's example of overwriting the data with the mapIndexed

ehsannarmani commented 2 weeks ago

in this sample, data is not state, so ui wont update after data changed.

ehsannarmani commented 2 weeks ago

i will update and fix document

msshin0202 commented 2 weeks ago

@ehsannarmani one more question for you, the LineChart seems to cause rendering issues when put inside a Column with a verticalScroll modifier due to infinite height constraint. Any ideas?

ehsannarmani commented 2 weeks ago

hi @msshin0202 , set a fixed height for chart for example:

LineChart(
 modifier= Modifier.height(300.dp)
 ...
)
msshin0202 commented 2 weeks ago

@ehsannarmani Yeah I wanted to not have to do a fixed height, but if that's the only way!