Skip to main content
Version: 2.0.0-alpha.19

Data

CartesianChart data is stored in CartesianChartModels. Just like CartesianCharts are collections of CartesianLayers, CartesianChartModels are collections of CartesianLayerModels.

CartesianChartModels are created via CartesianChartModelProducer, which works off the main thread. CartesianChartModelProducer uses Transactions. How data is added to a Transaction depends on the CartesianLayer (or CartesianLayers) in use, so this is covered on the “Column layer” and “Line layer” pages.

Create a CartesianChartModelProducer instance as follows:

CartesianChartModelProducer.build()
warning

Avoid the unnecessary recreation of CartesianChartModelProducers. We recommend instantiating this class in ViewModels. If you have to create an instance in a composable function, use remember. Don’t run data updates by recreating your CartesianChartModelProducer.

Then, to add and update data, use one of the following:

  1. tryRunTransaction, which is a normal function, attempts to run a data update. The update is rejected if there’s already an update in progress. A boolean indicating whether the update has been accepted is returned. Update processing is fast, so unless you run data updates multiple times per second, and every update must go through, tryRunTransaction is sufficient.

    cartesianChartModelProducer.tryRunTransaction { ... }
  2. runTransaction, which is a suspending function, suspends the coroutine from which it’s called until an update can be run. The suspension ends when the update starts being processed.

    cartesianChartModelProducer.runTransaction { ... }

    A Deferred implementation is returned, and it is marked as completed once the update has been processed. Thus, to wait until the update has been processed, you can use await:

    cartesianChartModelProducer.runTransaction { ... }.await()
warning

Since CartesianChartModelProducer handles Transactions asynchronously, configuration that depends on the chart data and can change as the data is updated should be performed based on the CartesianChartModels and CartesianLayerModels passed to callback-based APIs (lambdas and interfaces). Directly using the data from the latest Transaction may lead to unexpected behavior, as the Transaction may not have been processed yet. This applies equally to auxiliary data—see “Extras.”

Add a CartesianChartModelProducer to a CartesianChart as follows:

CartesianChartHost(modelProducer = cartesianChartModelProducer, ...)

Extras

CartesianChartModelProducer lets you define extras (auxiliary data). These can later be read from model-receiving functions via CartesianChartModel#extraStore and CartesianLayerModel#extraStore. Extras are useful for properties that should change with the chart data and that can’t be directly derived from it or should be precalculated. They ensure that the auxiliary data and the chart data remain in sync, given CartesianChartModelProducer’s asynchronous nature. Solutions such as a Flow updated each time a Transaction is commited don’t ensure this synchronization and should thus be avoided. To add extras, use Transaction#updateExtras. A simple example can be found below. (Don’t worry if you’re not familiar with CartesianValueFormatter—you’ll learn about it soon.)

val xAxisLabelSuffixKey = ExtraStore.Key<String>()
cartesianChartModelProducer.tryRunTransaction {
updateExtras { it[xAxisLabelSuffixKey] = "km" }
...
}
CartesianValueFormatter<AxisPosition.Horizontal.Bottom> { x, chartValues, _ ->
"$x ${chartValues.model.extraStore[xAxisLabelSuffixKey]}"
}
tip

Use extras only when necessary. The solution above would be needed in instances where the suffix should change with the data. A suffix that never changes or depends on something else wouldn’t benefit from being an extra and could be determined at the formatting stage (in the CartesianValueFormatter).

Manual CartesianChartModel creation

We recommend using CartesianChartModelProducer because it offers performance benefits and animations. However, you can create CartesianChartModels manually via the class’s constructor, which takes a list of CartesianLayerModels. Since each CartesianLayer has its own CartesianLayerModel, you’ll learn how to create CartesianLayerModels on the “Column layer” and “Line layer” pages.

CartesianChartModel(...)

Add a CartesianChartModel to a CartesianChart as follows:

CartesianChartHost(model = cartesianChartModel, ...)

When a host receives a CartesianChartModel, it handles it synchronously, so extras are unneeded here.