> For the complete documentation index, see [llms.txt](https://guide.vico.patrykandpatrick.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guide.vico.patrykandpatrick.com/cartesian-charts/cartesianvalueformatter.md).

# 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) and [`yPercent`](https://api.vico.patrykandpatrick.com/vico/compose/com.patrykandpatrick.vico.compose.cartesian.data/-cartesian-value-formatter/-companion/y-percent). 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/charts/compose/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/compose/RockMetalRatios.kt) sample chart.

<figure><img src="/files/9Wymw9vMXo8QmzMdWVH2" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/charts/compose/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/compose/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/charts/compose/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/compose/GoldPrices.kt) sample chart.

<figure><img src="/files/H42PRcnBL88MSwLzqJWv" alt="" width="375"><figcaption><p>The <a href="https://github.com/patrykandpatrick/vico/blob/stable/sample/charts/compose/src/commonMain/kotlin/com/patrykandpatrick/vico/sample/charts/compose/GoldPrices.kt">“Gold prices (12/30/2024)”</a> sample chart, whose <em>x</em>-axis labels are dates</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://guide.vico.patrykandpatrick.com/cartesian-charts/cartesianvalueformatter.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
