# Introduction

<figure><img src="https://raw.githubusercontent.com/patrykandpatrick/vico/master/cover.png" alt=""><figcaption></figcaption></figure>

Vico is a powerful and extensible chart library for Compose Multiplatform.

## Sponsored by Software Mansion

Founded in 2012, [Software Mansion](https://swmansion.com) is a software agency with experience in building web and mobile apps. We are core React Native contributors and experts in dealing with all kinds of React Native issues. We can help you build your next dream product—[hire us](https://swmansion.com/contact/projects?utm_source=vico\&utm_medium=readme).

[![](https://logo.swmansion.com/logo?color=white\&variant=desktop\&width=152\&tag=vico-github)](https://swmansion.com)


# Getting started

## Prerequisites

Ensure the following:

* The Maven Central repository is added to your project.
* For Android, `minSdk` is set to at least 23.

## Dependencies

Add only the modules you need. `compose-m2` and `compose-m3` provide Material 2 and Material 3 theming, respectively; `compose-glance` provides chart-image composables for Jetpack Glance app widgets.

```toml
[versions]
vico = "3.3.1"

[libraries]
vico-compose = { group = "com.patrykandpatrick.vico", name = "compose", version.ref = "vico" }
vico-compose-m2 = { group = "com.patrykandpatrick.vico", name = "compose-m2", version.ref = "vico" }
vico-compose-m3 = { group = "com.patrykandpatrick.vico", name = "compose-m3", version.ref = "vico" }
vico-compose-glance = { group = "com.patrykandpatrick.vico", name = "compose-glance", version.ref = "vico" }
```

```kt
dependencies {
    implementation(libs.vico.compose)
    implementation(libs.vico.compose.m2)
    implementation(libs.vico.compose.m3)
    implementation(libs.vico.compose.glance)
}
```


# Learning resources

## Guide

This guide serves as an overview, outlining Vico’s core features and providing usage guidance.

## API reference

[The API reference](https://api.vico.patrykandpatrick.com/) describes every public API element. On each of the guide’s pages, the first mention of any class, function, or property is a link to the corresponding page in the API reference. Follow these links to learn about all the features of the APIs described, as well as more APIs.

## Sample app

Included in the repository is [a sample app](https://github.com/patrykandpatrick/vico/tree/stable/sample), which consists of [sample charts](https://github.com/patrykandpatrick/vico/tree/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts).

The sample app is the most practical Vico learning resource, recommended for beginner and advanced users alike. Sample charts are referenced throughout the guide.

Follow the links above to view the code on GitHub. For Android, you can also [download the APK](https://github.com/patrykandpatrick/vico/releases/download/v3.3.1/android-sample-debug.apk). To work with the sample app locally, clone the repository, switch to the right tag, open the project in Android Studio, and navigate to the [`sample`](https://github.com/patrykandpatrick/vico/tree/stable/sample) module.

```sh
git clone https://github.com/patrykandpatrick/vico
cd vico
git checkout v3.3.1
```


# Contributing

## Issues and discussions

* To report a bug or a documentation error, [open an issue](https://github.com/patrykandpatrick/vico/issues/new/choose).
* To ask a question or share an idea, [start a discussion](https://github.com/patrykandpatrick/vico/discussions/new/choose).

## Pull requests

For pull requests, follow these guidelines:

* Use `master` as the base branch.
* To format your code, use [`ktfmt`](https://facebook.github.io/ktfmt/) with `--google-style`. For matters not handled thereby, follow the conventions described on the [“Coding conventions”](https://kotlinlang.org/docs/coding-conventions.html) page of the Kotlin documentation.
* Add documentation for all public API elements.


# Starter examples

## Column chart

The following has been adapted from the [“Basic column chart”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/BasicColumnChart.kt) sample chart.

```kt
val modelProducer = remember { CartesianChartModelProducer() }
LaunchedEffect(Unit) {
    modelProducer.runTransaction {
        columnModel { series(5, 6, 5, 2, 11, 8, 5, 2, 15, 11, 8, 13, 12, 10, 2, 7) }
    }
}
CartesianChartHost(
    rememberCartesianChart(
        rememberColumnCartesianLayer(),
        startAxis = VerticalAxis.rememberStart(),
        bottomAxis = HorizontalAxis.rememberBottom(),
    ),
    modelProducer,
)
```

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-37ac492f54958840c970679b399441fc7ff9fb93%2Fcolumn.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

## Line chart

The following has been adapted from the [“Basic line chart”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/BasicLineChart.kt) sample chart.

```kt
val modelProducer = remember { CartesianChartModelProducer() }
LaunchedEffect(Unit) {
    modelProducer.runTransaction {
        lineModel { series(13, 8, 7, 12, 0, 1, 15, 14, 0, 11, 6, 12, 0, 11, 12, 11) }
    }
}
CartesianChartHost(
    rememberCartesianChart(
        rememberLineCartesianLayer(),
        startAxis = VerticalAxis.rememberStart(),
        bottomAxis = HorizontalAxis.rememberBottom(),
    ),
    modelProducer,
)
```

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-97d02c4d2e6e789f0da1317ebba233a40601a7a4%2Fline.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

## Combo chart

The following has been adapted from the [“Basic combo chart”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/BasicComboChart.kt) sample chart.

```kt
val modelProducer = remember { CartesianChartModelProducer() }
LaunchedEffect(Unit) {
    modelProducer.runTransaction {
        columnModel { series(4, 15, 5, 8, 10, 15, 9, 10, 7, 9, 10, 12, 2, 9, 5, 14) }
        lineModel { series(1, 5, 4, 7, 3, 14, 5, 9, 9, 14, 7, 13, 14, 4, 10, 12) }
    }
}
CartesianChartHost(
    rememberCartesianChart(
        rememberColumnCartesianLayer(
            ColumnCartesianLayer.ColumnProvider.series(
                rememberLineComponent(Fill(Color(0xffffc002)), 16.dp)
            )
        ),
        rememberLineCartesianLayer(
            LineCartesianLayer.LineProvider.series(
                LineCartesianLayer.Line(
                    LineCartesianLayer.LineFill.single(Fill(Color(0xffee2b2b)))
                )
            )
        ),
        startAxis = VerticalAxis.rememberStart(),
        bottomAxis = HorizontalAxis.rememberBottom(),
    ),
    modelProducer,
)
```

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-d44bc0b3a7fc2eaae73d5cd87dbf5e46d1bdf072%2Fcombo.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

## More

For more examples, refer to [the sample app](/learning-resources#sample-app).


# CartesianChart

[`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) draws a chart based on a Cartesian coordinate plane. The chart includes one or more data layers, drawn by [`CartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-cartesian-layer/) instances. Each layer has its own data.

## Creation

Instantiate `CartesianChart` via [`rememberCartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-cartesian-chart.html).

## Ranges

A chart’s *x*- and *y*-ranges depend on those reported by its layers. The *x*-range is the narrowest one that includes all layers’ *x*-ranges. By default, there’s an analogously determined shared *y*-range, but two separate *y*-ranges can also be introduced.

*x*- and *y*-range customization is discussed in [a later subsection](/cartesian-charts/cartesianlayer#cartesianlayerrangeprovider).

## *x*-step

The *x*-step is a reference *x*-increment. Together with `CartesianLayer` settings, it determines the intrinsic mapping between data and screen units (before zoom). Other components also use it for calibration; for instance, the built-in axis-item placers use it as the default label and line spacing. An *x*-value is considered *major* if it’s a natural number of *x*-steps away from the minimum.

By default, the *x*-step is the greatest common divisor of the differences between consecutive *x*-values in the flattened *x*-series. For example, if these *x*-values are $${0, 1, 2, 3}$$, the *x*-step is 1; if the *x* values are $${0, 2, 4, 6}$$, the *x*-step is 2.

To customize the *x*-step, use `rememberCartesianChart`’s `getXStep` parameter, which accepts a `(CartesianChartModel) -> Double` lambda:

```kotlin
rememberCartesianChart(getXStep = { 1.0 }, /* ... */)
```

Consider a daily line chart whose data points may arrive at arbitrary times within a day. Setting the *x*-step to one day means that one day’s worth of *x*-distance intrinsically maps to a specific amount of screen space, and the built-in axis-item placers use a one-day interval.

For a daily column chart that may have gaps in the data, locking the *x*-step to one day causes the chart to leave room for the missing days. Without this, the default would shrink the step based on the data actually present, and columns would be packed together as though no days were missing.

For line charts, both increasing and decreasing the *x*-step relative to the default can be useful. For column and candlestick charts, only increasing it is practical; the opposite could cause overlaps.

Note that the *x*-step is different from zoom. Zoom scales the entire chart—including column widths, for example—whereas the *x*-step changes the logical interpretation of the data’s spacing. The effects described above aren’t achievable with zoom alone.


# CartesianChartModelProducer

A chart’s data is stored in its model, represented by [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/). Much like [`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) combines [`CartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-cartesian-layer/) instances, [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) combines [`CartesianLayerModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-model/) instances. Use the transaction-based [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/) to create models.

## Creation

Instantiate `CartesianChartModelProducer` via the constructor. Since data updates are performed via transactions, the producer used by a chart shouldn’t be replaced. Thus, store it in a place with sufficient persistence, such as a view model.

## `Transaction`

Use [`runTransaction`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/run-transaction.html) to perform an update in a transaction. This is a suspending function:

```kt
cartesianChartModelProducer.runTransaction { /* ... */ }
```

This function returns when the update is complete—that is, once a new model has been generated and the host has been notified. If there’s already an update in progress, the current coroutine is first suspended until the ongoing update’s completion.

How data is added in a transaction depends on the layers in use, so we cover this later, on the pages that describe the individual [`CartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-cartesian-layer/) implementations.

## Asynchrony

`runTransaction` works off the main thread, meaning that model generation and processing happen asynchronously. Moreover, during an update, two models may be dealt with at once—one in the foreground and one in the background. Thus, dynamic setup tied to model updates should be performed based on Vico-provided arguments of lambdas, interface functions, and the like. These functions may receive `CartesianChartModel` instances or related data. For such setup, external mechanisms should be avoided:

* Never directly use the data from the latest transaction.
* Never introduce a separate channel that makes setup changes as a transaction runs.

These solutions don’t have the tight coupling with the transaction mechanism that synchronization requires and may thus produce improper, unpredictable results.

For setup derived from series data, the correct, argument-based approach is straightforward, with the data being readily available in the model and its ranges. Functions may receive these directly, but they’re usually accessed via [`CartesianMeasuringContext`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-measuring-context/) and its subtypes; see [`model`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-measuring-context/model.html) and [`ranges`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-measuring-context/ranges.html).

However, changes that aren’t directly derived from series data may also need to be aligned with model updates. We thus need a means of sending additional information through the same channel that’s used for series data. This is where extras, described in the following subsection, come in.

## Extras

Extras are a means of adding auxiliary data to models. They’re stored in [`extraStore`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/extra-store.html) and use typed keys ([`ExtraStore.Key`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.data/-extra-store/-key/) instances), enabling you to save any kind of data in a type-safe manner. To add extras, use [`extras`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/-transaction/extras.html), as shown below. (This is, of course, a simplified example. Extras are used for values that change; static values don’t require synchronization.)

```kt
val UnitKey = ExtraStore.Key<String>()
```

```kt
cartesianChartModelProducer.runTransaction {
    extras { extraStore ->
        extraStore[UnitKey] = "Ω"
        // ...
    }
    // ...
}
```

Just like series data, extras can be accessed via function arguments. In [`ExtraStore`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.data/-extra-store/)-focused contexts, an `ExtraStore` instance is provided explicitly. Where this isn’t the case, use `CartesianChartModel.extraStore`, obtaining the model as described above. (That’s `context.model.extraStore` in most cases.)

Extras are read like `Map` elements. Assume you have an `ExtraStore` reference called `extraStore` and an `ExtraStore.Key` reference called `Key`. If the extra is added on every transaction, use the following:

```kt
extraStore[Key]
```

If the extra is added conditionally, meaning that it may not be present, use this:

```kt
extraStore.getOrNull(Key)
```

`ExtraStore.Key` instances are compared by identity. Given the asynchronous context in which they’re used, it’s important not to recreate or swap them more often than appropriate. Ensure the following:

* Each `ExtraStore.Key` instance used with a particular model producer is persisted at least as long as the corresponding `CartesianChartModelProducer` instance. (A universal approach is to store keys statically—at the top level, in companion objects, and so on. This can also make your code more elegant, eliminating the need for passing key references around.)
* A property’s `ExtraStore.Key` instance remains unchanged throughout the lifetime of the associated model producer.

See the following sample charts for examples of extra usage:

* [“AI test scores”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/AITestScores.kt)
* [“Daily digital-media use (USA)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/DailyDigitalMediaUse.kt)
* [“Rock–metal ratios”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/RockMetalRatios.kt)

## Manual `CartesianChartModel` creation

Using `CartesianChartModelProducer` is recommended because it offers performance benefits and supports animations. However, you can create models manually via the `CartesianChartModel` constructor, which takes a list of `CartesianLayerModel` instances. When `CartesianChartHost` receives such a model, it handles it synchronously. Any asynchronous processing is explicitly handled by the consumer. Thus, extras are unneeded.


# CartesianChartHost

[`CartesianChartHost`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart-host.html) is the entry point for Cartesian charts. It accepts [`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) and [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/) instances, facilitates communication between them, and displays the chart. It also handles scroll and zoom and shows a placeholder when no data is available.

```kt
CartesianChartHost(rememberCartesianChart(/* ... */), modelProducer, /* ... */)
```

You can also use a manually created [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) instance instead of a model producer:

```kt
CartesianChartHost(rememberCartesianChart(/* ... */), model, /* ... */)
```

## Sizing

The [`chartAreaHeight`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart-host.html) parameter sets the default height of the coordinate system. Its default value is 192 dp. Axis margins, legends, markers, and other components add to this height instead of being fitted inside it.

This default applies only when the host’s height isn’t otherwise constrained. [`Modifier.height`](https://developer.android.com/develop/ui/compose/modifiers-list#Size) and similar modifiers set the total host height, within which the chart and its components are fitted.

## Animation

For model producers, [`animationSpec`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart-host.html) defines how differences between models are animated. [`initialAnimationSpec`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart-host.html) separately defines the initial animation and defaults to `animationSpec`. Set `initialAnimationSpec` to `null` to skip the initial animation.

## Scroll

`CartesianChartHost` accepts [`VicoScrollState`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-scroll-state/) instances, enabling scroll customization and programmatic scrolling. Use [`rememberVicoScrollState`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-vico-scroll-state.html) to instantiate `VicoScrollState`:

```kt
val scrollState = rememberVicoScrollState(/* ... */)
CartesianChartHost(scrollState = scrollState, /* ... */)
```

From a coroutine, call [`VicoScrollState.scroll`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-scroll-state/scroll.html) to scroll immediately or [`VicoScrollState.animateScroll`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-scroll-state/animate-scroll.html) to animate the change.

To snap the scroll position to multiples of an *x*-step after a fling, set [`xSnapStep`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-vico-scroll-state.html). Use [`snapAnimationSpec`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-vico-scroll-state.html) to customize the animation.

When the data’s minimum *x*-value or *x*-step changes, the scroll state preserves the visible *x*-range. For example, prepending historical data doesn’t move the viewport to the new start edge.

[`Scroll`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/) represents scroll values—either absolute (from zero) or relative (from the current value). [`Scroll.Absolute`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-absolute/) and [`Scroll.Relative`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-relative/) cover the two cases. The following factory functions are available:

* [`Absolute.pixels`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-absolute/-companion/pixels.html)
* [`Absolute.x`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-absolute/-companion/x.html)
* [`Relative.pixels`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-relative/-companion/pixels.html)
* [`Relative.x`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-scroll/-relative/-companion/x.html)

[`AutoScrollCondition`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-auto-scroll-condition/) defines when to scroll automatically. There are two singletons:

* [`Never`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-auto-scroll-condition/-companion/-never.html) (default)
* [`OnModelGrowth`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-auto-scroll-condition/-companion/-on-model-growth.html)

You can create custom implementations of `Scroll` and `AutoScrollCondition` for more specific behavior.

## Zoom

`CartesianChartHost` accepts [`VicoZoomState`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-zoom-state/) instances, enabling zoom customization. Use [`rememberVicoZoomState`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-vico-zoom-state.html) to instantiate `VicoZoomState`:

```kt
val zoomState = rememberVicoZoomState(/* ... */)
CartesianChartHost(zoomState = zoomState, /* ... */)
```

From a coroutine, call [`VicoZoomState.zoom`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-zoom-state/zoom.html) to zoom immediately or [`VicoZoomState.animateZoom`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-vico-zoom-state/animate-zoom.html) to animate the change.

[`Zoom`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/) defines zoom factors. The following singletons and factory functions are available:

* [`Content`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/-companion/-content.html)
* [`max`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/-companion/max.html)
* [`min`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/-companion/min.html)
* [`fixed`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/-companion/fixed.html)
* [`x`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-zoom/-companion/x.html)

You can create custom implementations of `Zoom` for more specific behavior.


# CartesianLayer

There are three built-in [`CartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-cartesian-layer/) implementations:

* [`CandlestickCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-candlestick-cartesian-layer/)
* [`ColumnCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-column-cartesian-layer/)
* [`LineCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/)

These are discussed individually in the following sections.

## Drawing-model interpolation

The [`CartesianLayerDrawingModelInterpolator`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-drawing-model-interpolator/) interface controls how a layer is animated between drawing models. Use the factory function for the layer type:

* [`line`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-drawing-model-interpolator/-companion/line.html)
* [`column`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-drawing-model-interpolator/-companion/column.html)
* [`candlestick`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-drawing-model-interpolator/-companion/candlestick.html)

Pass the result as the layer’s `drawingModelInterpolator` argument. For more specific behavior, implement the interface.

## `CartesianLayerRangeProvider`

What *x*- and *y*-ranges a layer reports depends on its [`CartesianLayerRangeProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-range-provider/) instance. A layer passes its intrinsic *x*- and *y*-ranges—which depend on [`CartesianLayerModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-model/)—to this instance, which returns the final ranges to report. The available singletons and factory functions are listed below. For more specific behavior, implement the interface.

* [`auto`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-range-provider/-companion/auto.html) (default)
* [`fixed`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-range-provider/-companion/fixed.html)
* [`Intrinsic`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-range-provider/-companion/-intrinsic.html)

The default implementations of the `CartesianLayerRangeProvider` functions leave the *x*-range unchanged but do these two things:

* They ensure that the *y*-range includes zero.
* They apply a *y*-range of \[0, 1] if the minimum and maximum intrinsic *y*-values are both zero.

This also applies to the implementation returned by `auto`. Custom `CartesianLayerRangeProvider` implementations can override this behavior. With `fixed`, `minY` and `maxY` take precedence.

When using [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/), set the `CartesianLayerRangeProvider` instance for each layer only once. There are no restrictions on dynamic behavior, but it should be implemented as part of a single `CartesianLayerRangeProvider` instance, not by means of a mechanism that switches between `CartesianLayerRangeProvider` implementations. In particular, for charts powered by `CartesianChartModelProducer`, `fixed` should be used only for entirely static overrides.

When you need to perform calculations based on a layer’s intrinsic *x*- and *y*-ranges, use the values passed to the `CartesianLayerRangeProvider` functions. Beyond that, use extras if needed. These are important here not only for the usual synchronization reasons, but also because they’re updated via [`CartesianChartModelProducer.Transaction`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/-transaction/), and a transaction is required for a chart’s *x*- and *y*-ranges to be updated. A common use case for extras is switching between externally defined *x*- and *y*-ranges—both in synchronization with series updates and without series updates (for example, in response to changes in user-accessible range settings).

## `Axis.Position.Vertical`

A [`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) can have two separate *y*-ranges, one for the start *y*-axis and one for the end *y*-axis. (The presence of two *y*-axes isn’t strictly necessary, but it’s generally needed for unambiguity.) You can assign each layer to an [`Axis.Position.Vertical`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-axis/-position/-vertical/) subclass—either [`Start`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-axis/-position/-vertical/-start/) or [`End`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-axis/-position/-vertical/-end/). The final *y*-range for either subclass is the narrowest range that includes the *y*-ranges of all linked layers. Thus, you get two independently scaled groups of layers, and the two *y*-axes are disconnected.


# CandlestickCartesianLayer

Use [`CandlestickCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-candlestick-cartesian-layer/) to create candlestick charts. Instantiate it via [`rememberCandlestickCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-candlestick-cartesian-layer.html).

Each candle’s style is defined by its corresponding [`Candle`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-candlestick-cartesian-layer/-candle/) instance. These are provided by [`CandleProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-candlestick-cartesian-layer/-candle-provider/):

* To style candles based on their absolute price changes (closing vs. opening), use [`absolute`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/absolute.html). This is commonly used for filled candles and provides corresponding defaults.
* To style candles based on both their absolute price changes (closing vs. opening) and their relative price changes (closing vs. previous closing), use [`absoluteRelative`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/absolute-relative.html). This is commonly used for hollow candles and provides corresponding defaults.
* For custom behavior, implement `CandleProvider`.

In `rememberCandlestickCartesianLayer`, you can set the minimum body height, change the candle spacing, and toggle wick scaling. For an example, see the [“Gold prices (12/30/2024)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/GoldPrices.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-6cb478f012c866fc6f2b03fdb0330f26f0f75c65%2Fgold-prices.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>

## `Transaction.candlestickModel`

Candlestick layers use [`CandlestickCartesianLayerModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-candlestick-cartesian-layer-model/) instances. When using [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/), add them via [`candlestickModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/candlestick-model.html):

```kt
cartesianChartModelProducer.runTransaction {
    candlestickModel(
        x = listOf(1, 2, 3, 4),
        opening = listOf(2, 4, 6, 3),
        closing = listOf(4, 5, 3, 3),
        low = listOf(1, 4, 2, 2),
        high = listOf(5, 6, 7, 4),
    )
    // ...
}
```

`candlestickModel` also has an overload with no `x` parameter, which uses the indices of the prices as the *x*-values:

```kt
candlestickModel(
    opening = listOf(2, 4, 6, 3),
    closing = listOf(4, 5, 3, 3),
    low = listOf(1, 4, 2, 2),
    high = listOf(5, 6, 7, 4),
)
```

## Manual `CandlestickCartesianLayerModel` creation

When creating a [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) instance directly, you can add a candlestick-layer model by using [`build`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-candlestick-cartesian-layer-model/-companion/build.html):

```kt
CartesianChartModel(
    CandlestickCartesianLayerModel.build(
        x = listOf(1, 2, 3, 4),
        opening = listOf(2, 4, 6, 3),
        closing = listOf(4, 5, 3, 3),
        low = listOf(1, 4, 2, 2),
        high = listOf(5, 6, 7, 4),
    ),
    // ...
)
```

This function also has an overload with no `x` parameter:

```kt
CandlestickCartesianLayerModel.build(
    opening = listOf(2, 4, 6, 3),
    closing = listOf(4, 5, 3, 3),
    low = listOf(1, 4, 2, 2),
    high = listOf(5, 6, 7, 4),
)
```


# ColumnCartesianLayer

Use [`ColumnCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-column-cartesian-layer/) to create column charts. Instantiate it via [`rememberColumnCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-column-cartesian-layer.html).

Columns are drawn via [`LineComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/-line-component/) instances provided by [`ColumnProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-column-cartesian-layer/-column-provider/). [`ColumnProvider.series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-column-cartesian-layer/-column-provider/-companion/series.html) creates a `ColumnProvider` instance that uses one `LineComponent` instance per series. You can create your own implementation for custom behavior, including styling columns individually based on their *y*-values, as in the [“Temperature anomalies (June)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/TemperatureAnomalies.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-b4f02d98ed2db2eb13f5161820a2c76e59bf2e17%2Ftemperature-anomalies.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/TemperatureAnomalies.kt">“Temperature anomalies (June)”</a> sample chart, which colors each column according to its <em>y</em>-value</p></figcaption></figure>

In `rememberColumnCartesianLayer`, you can also change column spacing. Data labels are supported. When multiple series are added, columns can be grouped horizontally or stacked. The [“Daily digital-media use (USA)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/DailyDigitalMediaUse.kt) sample chart uses stacking.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-9fd8cd5ea0f778d1808070197546e887a292d4ce%2Fdaily-digital-media-use.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/DailyDigitalMediaUse.kt">“Daily digital-media use (USA)”</a> sample chart, which stacks its column series</p></figcaption></figure>

## `Transaction.columnModel`

Column layers use [`ColumnCartesianLayerModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-column-cartesian-layer-model/) instances. When using [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/), add them via [`columnModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/column-model.html):

```kt
cartesianChartModelProducer.runTransaction {
    columnModel {
        series(1, 8, 3, 7)
        series(y = listOf(6, 1, 9, 3))
        series(x = listOf(1, 2, 3, 4), y = listOf(2, 5, 3, 4))
    }
    // ...
}
```

Each [`series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-column-cartesian-layer-model/-builder-scope/series.html) invocation adds a series to the `ColumnCartesianLayerModel` instance. Above, three series are added. `series` has three overloads (each of which accepts all `Number` subtypes):

* a `vararg` overload that takes *y*-values and uses their indices as the *x*-values
* an overload that takes a collection of *y*-values and uses their indices as the *x*-values
* an overload that takes a collection of *x*-values and a collection of *y*-values of the same size

## Manual `ColumnCartesianLayerModel` creation

When creating a [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) instance directly, you can add a column-layer model by using [`build`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-column-cartesian-layer-model/-companion/build.html). This function gives you access to the same DSL that `columnModel` does.

```kt
CartesianChartModel(
    ColumnCartesianLayerModel.build {
        series(1, 8, 3, 7)
        series(y = listOf(6, 1, 9, 3))
        series(x = listOf(1, 2, 3, 4), y = listOf(2, 5, 3, 4))
    },
    // ...
)
```


# LineCartesianLayer

Use [`LineCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/) to create line charts. Instantiate it via [`rememberLineCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-line-cartesian-layer.html).

Each line is associated with a [`Line`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line/) instance. Create these via [`rememberLine`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-line.html). These are provided by [`LineProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-provider/). A base implementation of this interface can be instantiated via [`LineProvider.series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-provider/-companion/series.html). You can customize line fills, backgrounds, shapes, and other properties. You can also add data labels, points, and interpolation.

## Animation

Line animations are configured via [`CartesianLayerDrawingModelInterpolator.line`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-layer-drawing-model-interpolator/-companion/line.html). By default, a line grows from the baseline and fades in during its initial animation. Set `sweep` to `true` to instead animate the initial appearance as a clip sweeping in from the start edge:

```kt
rememberLineCartesianLayer(
    drawingModelInterpolator = CartesianLayerDrawingModelInterpolator.line(sweep = true),
    /* ... */
)
```

## `LineStroke`

Line strokes are customized via [`LineStroke`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-stroke/), which has two implementations:

* [`Continuous`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-stroke/-continuous/)
* [`Dashed`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-stroke/-dashed/)

## `LineFill` and `AreaFill`

Line fills are customized via [`LineFill`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-fill/), which has two factory functions:

* [`single`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-fill/-companion/single.html)
* [`double`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-fill/-companion/double.html)

Area fills, which are optional, are customized via [`AreaFill`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-area-fill/). This has similar factory functions to `LineFill`:

* [`single`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-area-fill/-companion/single.html)
* [`double`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-area-fill/-companion/double.html)

These cover most use cases. You can use both colors and brushes, and you can apply split styling—enabling you to create a line that’s green for positive values and red for negative values, for instance. You can, however, also create your own `LineFill` and `AreaFill` implementations.

[`LineFill.colorScale`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-line-fill/-companion/color-scale.html) and [`AreaFill.colorScale`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-area-fill/-companion/color-scale.html) provide another option. These APIs let you define multi-stop styling against the value scale instead of splitting at a single threshold.

For an example of an area fill, see the [“Electric-car sales (Norway)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/ElectricCarSales.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-3bd115859760148993151c996ca91f23b80ff844%2Felectric-car-sales.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/ElectricCarSales.kt">“Electric-car sales (Norway)”</a> sample chart, which combines an area fill with <code>catmullRom</code> interpolation</p></figcaption></figure>

## `Interpolator`

Use [`Interpolator`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-interpolator/) to define how a line passes through its points. Three built-in implementations are available:

* [`Sharp`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-interpolator/-companion/-sharp.html) uses straight line segments.
* [`cubic`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-interpolator/-companion/cubic.html) uses cubic Bézier curves.
* [`catmullRom`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-interpolator/-companion/catmull-rom.html) passes through all points and keeps collinear segments straight.

The [“Electric-car sales (Norway)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/ElectricCarSales.kt) sample chart uses `catmullRom`.

## `PointProvider`

To add points, use [`PointProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-point-provider/). [`PointProvider.single`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-line-cartesian-layer/-point-provider/-companion/single.html) instantiates a base implementation that adds a point for each entry and uses a shared point style. Once again, custom implementations can be created. A common use case for this is styling points individually based on their *y*-values. For an example, see the [“AI test scores”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/AITestScores.kt) sample chart.

## `Transaction.lineModel`

Line layers use [`LineCartesianLayerModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-line-cartesian-layer-model/) instances. When using [`CartesianChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model-producer/), add them via [`lineModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/line-model.html):

```kt
cartesianChartModelProducer.runTransaction {
    lineModel {
        series(1, 8, 3, 7)
        series(y = listOf(6, 1, 9, 3))
        series(x = listOf(1, 2, 3, 4), y = listOf(2, 5, 3, 4))
    }
    // ...
}
```

Each [`series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-line-cartesian-layer-model/-builder-scope/series.html) invocation adds a series to the `LineCartesianLayerModel` instance. Above, three series are added. `series` has three overloads (each of which accepts all `Number` subtypes):

* a `vararg` overload that takes *y*-values and uses their indices as the *x*-values
* an overload that takes a collection of *y*-values and uses their indices as the *x*-values
* an overload that takes a collection of *x*-values and a collection of *y*-values of the same size

## Manual `LineCartesianLayerModel` creation

When creating a [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) instance directly, you can add a line-layer model by using [`build`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-line-cartesian-layer-model/-companion/build.html). This function gives you access to the same DSL that `lineModel` does.

```kt
CartesianChartModel(
    LineCartesianLayerModel.build {
        series(1, 8, 3, 7)
        series(y = listOf(6, 1, 9, 3))
        series(x = listOf(1, 2, 3, 4), y = listOf(2, 5, 3, 4))
    },
    // ...
)
```


# Axis

[`Axis`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-axis/) draws an axis along an edge of a [`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) instance. There are two built-in implementations: [`HorizontalAxis`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/) and [`VerticalAxis`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/). Use [`VerticalAxis.rememberStart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/-companion/remember-start.html), [`HorizontalAxis.rememberTop`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/-companion/remember-top.html), [`VerticalAxis.rememberEnd`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/-companion/remember-end.html), and [`HorizontalAxis.rememberBottom`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/-companion/remember-bottom.html) to instantiate these:

```kt
rememberCartesianChart(
    startAxis = VerticalAxis.rememberStart(/* ... */),
    topAxis = HorizontalAxis.rememberTop(/* ... */),
    endAxis = VerticalAxis.rememberEnd(/* ... */),
    bottomAxis = HorizontalAxis.rememberBottom(/* ... */),
    // ...
)
```

Numerous customization options are available; you can change the appearance of the labels, modify the axis lines, add titles, and more.

[`BaseAxis.TickPosition`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-base-axis/-tick-position/) and [`BaseAxis.LineDrawingOrder`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-base-axis/-line-drawing-order/) let you place ticks outside, inside, or across the axis line and choose whether ticks and the axis line are drawn under or over the chart layers.

## Titles

[`BaseAxis.TitlePosition`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-base-axis/-title-position/) defines where an axis title is drawn. There are two options:

* [`Side`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-base-axis/-title-position/-side/) uses the conventional position beside the axis.
* [`End`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-base-axis/-title-position/-end/) places the title at the leading end of the axis line.

Select an option via the `titlePosition` parameter.

## `ItemPlacer`

[`HorizontalAxis.ItemPlacer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/-item-placer/) and [`VerticalAxis.ItemPlacer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/-item-placer/) let you customize for what *x*- and *y*-values labels and lines are displayed. Four factory functions are available:

* [`HorizontalAxis.ItemPlacer.aligned`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/-item-placer/-companion/aligned.html) (default)
* [`HorizontalAxis.ItemPlacer.segmented`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/-item-placer/-companion/segmented.html)
* [`VerticalAxis.ItemPlacer.step`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/-item-placer/-companion/step.html) (default)
* [`VerticalAxis.ItemPlacer.count`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/-item-placer/-companion/count.html)

Custom implementations can be created.

By default, `HorizontalAxis.ItemPlacer.aligned` reserves horizontal margins so the extreme labels fit. Set `shiftExtremeLabels` to `true` to anchor these labels to the coordinate-system edges instead, keeping them visible without shrinking the coordinate system.


# CartesianValueFormatter

*x*- and *y*-values are numerical. You can use [`CartesianValueFormatter`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-value-formatter/) to format them for display. They can remain numbers, or they can be transformed to dates, category names, and so on.

There are two factory functions for `CartesianValueFormatter`: [`decimal`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-value-formatter/-companion/decimal.html) and [`yPercent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-value-formatter/-companion/y-percent.html). For more complex use cases, create custom implementations. `CartesianValueFormatter` instances are most commonly used with [`HorizontalAxis`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-horizontal-axis/) and [`VerticalAxis`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.axis/-vertical-axis/)—see the `valueFormatter` parameters and properties. However, these aren’t the only APIs that accept `CartesianValueFormatter` instances.

When the values remain numerical, formatting is straightforward. Thus, on this page, we focus on formatting with nonnumerical results. The aim in such cases is to find a predictable mapping. The optimal approach depends on the use case. Some common situations are discussed below.

## Categories

A chart’s domain can be a list of categories. An easy way to implement this pattern is to use *x*-values that serve as indices. As previously discussed, the series-creating functions have overloads that add such *x*-values automatically.

```kt
val data = mapOf("A" to 8f, "B" to 4f, "C" to 6f)
```

```kt
val labelListKey = ExtraStore.Key<List<String>>()
```

```kt
cartesianChartModelProducer.runTransaction {
    columnModel { series(data.values) }
    extras { it[labelListKey] = data.keys.toList() }
}
```

```kt
CartesianValueFormatter { context, x, _ ->
    context.model.extraStore[labelListKey][x.toInt()]
}
```

For an example, see the [“Rock–metal ratios”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/RockMetalRatios.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-565458ad0458186860fd1ee43056b2cd6a284a10%2Frock-metal-ratios.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/RockMetalRatios.kt">“Rock–metal ratios”</a> sample chart, whose <em>x</em>-axis labels are category names</p></figcaption></figure>

## Dates

Another common use case is mapping dates to *y*-values. The dates will be spaced out proportionally. If you need nonproportional spacing, use the approach from the previous subsection. This is also worth considering if there are no gaps in your data, in which case there’s no distinction between proportional and nonproportional spacing; the category approach will be simpler.

```kt
val data =
    mapOf(
        LocalDate.parse("2022-07-01") to 2f,
        LocalDate.parse("2022-07-02") to 6f,
        LocalDate.parse("2022-07-04") to 4f,
    )
```

```kt
val xToDateMapKey = ExtraStore.Key<Map<Float, LocalDate>>()
```

```kt
val xToDates = data.keys.associateBy { it.toEpochDay().toFloat() }
cartesianChartModelProducer.runTransaction {
    lineModel { series(xToDates.keys, data.values) }
    extras { it[xToDateMapKey] = xToDates }
}
```

```kt
val dateTimeFormatter = DateTimeFormatter.ofPattern("d MMM")
```

```kt
CartesianValueFormatter { context, x, _ ->
    (context.model.extraStore[xToDateMapKey][x] ?: LocalDate.ofEpochDay(x.toLong()))
        .format(dateTimeFormatter)
}
```

For an example, see the [“Gold prices (12/30/2024)”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/GoldPrices.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-6cb478f012c866fc6f2b03fdb0330f26f0f75c65%2Fgold-prices.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/GoldPrices.kt">“Gold prices (12/30/2024)”</a> sample chart, whose <em>x</em>-axis labels are dates</p></figcaption></figure>


# CartesianMarker

[`CartesianMarker`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker/) instances highlight points on charts. There are two types:

* Standard markers are shown on tap. Add these via the `marker` parameter of [`rememberCartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/remember-cartesian-chart.html).
* Persistent markers are shown permanently at given *x*-values. Add these via the `persistentMarkers` parameter of `rememberCartesianChart`.

There are two ways of creating `CartesianMarker` instances:

* using [`DefaultCartesianMarker`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-default-cartesian-marker/), described below
* implementing the interface

## `DefaultCartesianMarker`

A common means of creating `CartesianMarker` instances is [`DefaultCartesianMarker`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-default-cartesian-marker/), instantiated via [`rememberDefaultCartesianMarker`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/remember-default-cartesian-marker.html). It accepts three main components—a label, a point indicator, and a vertical line—and offers several customization options.

`DefaultCartesianMarker` label text is created by [`ValueFormatter`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-default-cartesian-marker/-value-formatter/). A dedicated formatting contract is required here because `CartesianMarker` instances can highlight multiple points at once. The general principle is the same as with [`CartesianValueFormatter`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-value-formatter/), but the required information must first be [retrieved from `targets`](#cartesianmarkertarget).

A base `ValueFormatter` implementation can be instantiated via [`ValueFormatter.default`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-default-cartesian-marker/-value-formatter/-companion/default.html). This implementation uses `DecimalFormat` to format *y*-values. You can provide a custom `DecimalFormat` instance and toggle the color-coding of *y*-values. The former enables you not only to change how the *y*-values themselves are formatted, but also to add prefixes and suffixes.

`DefaultCartesianMarker` is open for subclassing.

## `CartesianMarkerVisibilityListener`

You can listen for visibility changes of standard markers via [`CartesianMarkerVisibilityListener`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker-visibility-listener/).

## `CartesianMarkerController`

By default, a standard marker appears on press and disappears on release. You can customize this with [`CartesianMarkerController`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker-controller/), which has built-in implementations instantiated via the following:

* [`rememberShowOnPress`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker-controller/-companion/remember-show-on-press.html) (default)
* [`rememberToggleOnTap`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker-controller/-companion/remember-toggle-on-tap.html)
* [`rememberShowOnHover`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker-controller/-companion/remember-show-on-hover.html)

For more specific behavior, create a custom implementation.

## `CartesianMarker.Target`

`CartesianMarker` instances use [`Target`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-cartesian-marker/-target/) instances, which hold information on the highlighted points. They are stored in lists (called `targets`), since several points may be highlighted at once.

`Target` itself includes only general properties. More data is found in its subtypes, each of which corresponds to a [`CartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/-cartesian-layer/): [`CandlestickCartesianLayerMarkerTarget`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-candlestick-cartesian-layer-marker-target/), [`ColumnCartesianLayerMarkerTarget`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-column-cartesian-layer-marker-target/), and [`LineCartesianLayerMarkerTarget`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.marker/-line-cartesian-layer-marker-target/).

In general, you should take the following approach when working with `targets`:

* If you know that only one point can be highlighted at once, use `targets.first()`. (This occurs when each point has a unique pixel *x*-coordinate—for example, when only a single-series `LineCartesianLayerMarkerTarget` is present.) Otherwise, iterate `targets`.
* If you know that only one kind of `Target` is present, use casting. (This occurs when only one kind of `CartesianLayer` is in use.) Otherwise, use type checking (`when` with `is`).


# Decoration

A decoration, represented by [`Decoration`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.decoration/-decoration/), adds an additional layer of data to a chart. There are two built-in implementations—[`HorizontalLine`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.decoration/-horizontal-line/) and [`HorizontalBox`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.decoration/-horizontal-box/)—and you can add your own.

For an example, see the [“AI test scores”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/AITestScores.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-d259f3d1e7d88454a84a10e5e166c49a9f0b5c17%2Fai-test-scores.png?alt=media" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/AITestScores.kt">“AI test scores”</a> sample chart, in which a <code>HorizontalLine</code> decoration marks a threshold</p></figcaption></figure>


# Stability

Pie charts are experimental; they’ll remain available, but breaking changes are more likely.


# PieChart

[`PieChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/) draws a pie chart.

## Creation

Instantiate `PieChart` via [`rememberPieChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/remember-pie-chart.html).

```kt
val chart = rememberPieChart(/* ... */)
```

`PieChart` accepts a [`SliceProvider`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice-provider/) instance, which supplies [`Slice`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice/) instances for successive entries. Use [`SliceProvider.series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice-provider/-companion/series.html) for the standard repeating-series setup.

Each pie-slice style can define fill, stroke, an offset from the center, and an optional [`SliceLabel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice-label/). There are two built-in label types:

* [`Inside`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice-label/-inside/)
* [`Outside`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/-slice-label/-outside/)

Use [`PieValueFormatter`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-value-formatter/) to format slice labels.

You can also customize slice spacing, the start angle, and the inner and outer sizes. A nonzero inner size produces a donut chart.

The chart host reserves vertical space for outside labels, so they don’t reduce the pie diameter or get clipped. For an example that combines outside labels, slice spacing, and a nonzero inner size, see the [“Basic donut chart”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/BasicDonutChart.kt) sample chart.

For an example, see the [“Basic pie chart”](https://github.com/patrykandpatrick/vico/blob/stable/sample/shared/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/BasicPieChart.kt) sample chart.

<figure><img src="https://3393134890-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F496GVhv5h6SNkAUDHhBM%2Fuploads%2Fgit-blob-bd7470ec08829e7985419decab87b9081590bbcd%2Fbasic-pie-chart.png?alt=media" alt="" width="375"><figcaption></figcaption></figure>


# PieChartHost

[`PieChartHost`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart-host.html) is the entry point for pie charts. It accepts [`PieChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/) and [`PieChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model-producer/) instances, facilitates communication between them, and displays the chart. It also shows a placeholder when no data is available.

```kt
PieChartHost(rememberPieChart(/* ... */), modelProducer, /* ... */)
```

You can also use a manually created [`PieChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model/) instance instead of a model producer:

```kt
PieChartHost(rememberPieChart(/* ... */), model, /* ... */)
```

## Sizing

The [`chartAreaHeight`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart-host.html) parameter sets the default pie diameter. Its default value is 232 dp. Legends, outside labels, and other components add to this height instead of being fitted inside it.

This default applies only when the host’s height isn’t otherwise constrained. [`Modifier.height`](https://developer.android.com/develop/ui/compose/modifiers-list#Size) and similar modifiers set the total host height, within which the pie and its components are fitted.


# PieChartModelProducer

[`PieChartModelProducer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model-producer/) creates and updates [`PieChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model/) instances for [`PieChartHost`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart-host.html).

Use [`pieModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/pie-model.html) inside a transaction:

```kt
val modelProducer = remember { PieChartModelProducer() }
LaunchedEffect(Unit) {
    modelProducer.runTransaction {
        pieModel { series(60, 20, 20) }
    }
}
```

[`PieChartModel.Builder.series`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model/-builder/series.html) accepts either a `vararg` list of values or an iterable collection. Values must be nonnegative.

For static data, you can bypass the model producer and provide a [`PieChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model/) instance directly to `PieChartHost`.


# Component

[`Component`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/-component/) instances are the basic graphical building blocks of Vico. There are several built-in implementations, which cover most use cases:

* [`TextComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/-text-component/) draws text. It supports font customization, line breaks, rotation, backgrounds, and more. In composable contexts, use [`rememberTextComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/remember-text-component.html).
* [`ShapeComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/-shape-component/) draws `Shape` instances, for which you can define a color, a stroke, and more. In composable contexts, use [`rememberShapeComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/remember-shape-component.html).
* [`LineComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/-line-component/) draws horizontal and vertical lines. In composable contexts, use [`rememberLineComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common.component/remember-line-component.html).
* [`LayeredComponent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-layered-component/?query=open%20class%20LayeredComponent\(back:%20Component,%20front:%20Component,%20padding:%20Insets%20=%20Insets.Zero,%20margins:%20Insets%20=%20Insets.Zero\)%20:%20Component) draws two `Component` instances on top of each other and lets you specify their spacing.


# Fill

[`Fill`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-fill/) defines fill properties—either a color or a brush.


# Shape

Vico’s Compose APIs use `Shape` instances. You can use Compose’s built-in implementations, including `RoundedCornerShape` and `CutCornerShape`, or provide custom shape implementations.

Vico provides the following additional `Shape` implementations:

* [`DashedShape`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-dashed-shape/) alternates a base `Shape` instance with gaps.
* [`MarkerCornerBasedShape`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-marker-corner-based-shape/) wraps a `CornerBasedShape` instance and adds a triangular marker tick.


# Legend

A legend, represented by [`Legend`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-legend/), describes the elements present on a chart. There are two built-in implementations: [`HorizontalLegend`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-horizontal-legend/) and [`VerticalLegend`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-vertical-legend/). These use [`LegendItem`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-legend-item/) instances. Instantiate `HorizontalLegend` and `VerticalLegend` via [`rememberHorizontalLegend`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/remember-horizontal-legend.html) and [`rememberVerticalLegend`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/remember-vertical-legend.html):

```kt
rememberCartesianChart(legend = rememberHorizontalLegend(/* ... */), /* ... */)
```

```kt
rememberCartesianChart(legend = rememberVerticalLegend(/* ... */), /* ... */)
```


# VicoTheme

[`VicoTheme`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-vico-theme/) houses default chart colors. Functions like [`rememberColumnCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-column-cartesian-layer.html) and [`rememberLineCartesianLayer`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.layer/remember-line-cartesian-layer.html) use these for their default arguments. You can use [`ProvideVicoTheme`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/-provide-vico-theme.html) to provide a custom instance. Use [`vicoTheme`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.common/vico-theme.html) to access the provided value (for example, `vicoTheme.textColor`).

```kt
ProvideVicoTheme(remember(/* ... */) { VicoTheme(/* ... */) }) { /* ... */ }
```


# Jetpack Glance

The `compose-glance` module lets Jetpack Glance app widgets display Vico charts. Use [`CartesianChartImage`](https://api.vico.patrykandpatrick.com/vico/compose-glance/com.patrykandpatrick.vico.compose.glance.cartesian/-cartesian-chart-image.html) and [`PieChartImage`](https://api.vico.patrykandpatrick.com/vico/compose-glance/com.patrykandpatrick.vico.compose.glance.pie/-pie-chart-image.html) in widget content. These functions render charts off-screen to bitmaps and display the result as a static Glance image.

This differs from the interactive chart hosts [`CartesianChartHost`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart-host.html) and [`PieChartHost`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart-host.html). Glance doesn’t support the Compose canvas, so the image functions are the supported entry points for app widgets. Because the result is static, chart interactions such as scroll, zoom, and markers are unavailable.

## Cartesian charts

Pass a [`CartesianChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian/-cartesian-chart/) instance and a [`CartesianChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-chart-model/) instance:

```kt
CartesianChartImage(
    chart = rememberCartesianChart(rememberLineCartesianLayer()),
    model = model,
    contentDescription = "Weekly sales",
    modifier = GlanceModifier.fillMaxSize(),
)
```

## Pie charts

Pass a [`PieChart`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie/-pie-chart/) instance and a [`PieChartModel`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.pie.data/-pie-chart-model/) instance:

```kt
PieChartImage(
    chart = rememberPieChart(),
    model = model,
    contentDescription = "Expense breakdown",
    modifier = GlanceModifier.fillMaxSize(),
)
```

## Size and scaling

By default, each image uses Glance’s current widget size. You can pass a custom [`DpSize`](https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/DpSize) value via the `size` parameter. Use the `contentScale` parameter, which accepts a [`ContentScale`](https://developer.android.com/reference/kotlin/androidx/glance/layout/ContentScale) value, to control how the bitmap is scaled within the image bounds.


# Views

[Android is now Compose-first.](https://developer.android.com/develop/ui/compose/first) Vico’s `views` module remains available but, [like the official view-based Jetpack libraries](https://developer.android.com/develop/ui/compose/first#view-based-jetpack), will receive only critical fixes. [Read the `views` guide.](https://github.com/patrykandpatrick/vico/tree/views/guide)

If your project will stay view-based for the foreseeable future and you need the latest Vico features, you can use the `compose` module with [`ComposeView`](https://developer.android.com/reference/kotlin/androidx/compose/ui/platform/ComposeView).


