patrykandpatrick / vico

A light and extensible chart library for Android.
https://patrykandpatrick.com/vico/guide
Apache License 2.0
2.17k stars 130 forks source link

Updating the graph composable with mutable states doesn't reflect #958

Closed ivaylopenevmg closed 13 hours ago

ivaylopenevmg commented 18 hours ago

How to reproduce

Hello, I have a strange case where the graph doesn't reflect properly on state updates from a view model with graph data. In the video shared, I have 2 scenarios:

1) On the left. When a filter of data is applied, I first show a loading spin then then send an update to the graph, which re-draws completely. This works but it's more like a work-around and has a "flickering effect"

2) On the right, I don't show any loading progress but directly update the graph with a new state. Then the graph only reflects the changes if I move the marker. And it reflects them wrongly in some cases.

In the demo app (graph 5) I see that smooth updates are possible, without a complete re-draw of the graph. However this is achieved with a looping function inside the LaunchedEffect.

LaunchedEffect(Unit) {
    withContext(Dispatchers.Default) {
      while (isActive) {
        modelProducer.runTransaction {
          /* Learn more:
          https://patrykandpatrick.com/vico/wiki/cartesian-charts/layers/column-layer#data. */
          columnSeries {
            repeat(3) {
              series(
                List(Defaults.ENTRY_COUNT) {
                  Defaults.COLUMN_LAYER_MIN_Y +
                    Random.nextFloat() * Defaults.COLUMN_LAYER_RELATIVE_MAX_Y
                }
              )
            }
          }
        }
        delay(Defaults.TRANSACTION_INTERVAL_MS)
      }
    }

This seems more like a demo code, but my case is a standard VM + Composable case, where the view model holds a mutable state with the graph data. The state gets updates with some filters => the graph composable receives the new state but it acts weird (see video). Is there something I'm doing wrong or it's a limitation of the library?

Vico version(s)

2.0.0-beta.3

Android version(s)

15

Additional information

No response

Gowsky commented 7 hours ago

Hello, @ivaylopenevmg. I assume that you've determined what you were doing wrong. I have two comments.

In the demo app (graph 5) I see that smooth updates are possible, without a complete re-draw of the graph. However this is achieved with a looping function inside the LaunchedEffect.

The loop runs a data update every 2 seconds for showcase purposes. This doesn't directly relate to animations. Under correct usage, all data updates are animated, regardless of from where and how often they're triggered.

the view model holds a mutable state with the graph data. The state gets updates with some filters => the graph composable receives the new state

If the data is in the ViewModel, then you should also store the CartesianChartModelProducer and feed it with data there. The composable should then have just a modelProducer parameter. It makes no sense to pass the data through the composable tree in this case. It unnecessarily complicates the logic and leads to unnecessary recompositions.