Skip to content

Commit ac63383

Browse files
author
charts-release-bot
committed
docs(snapshot): sync release notes, wiki docs, GIF baselines, and hero image
1 parent dc01b24 commit ac63383

2 files changed

Lines changed: 216 additions & 457 deletions

File tree

Lines changed: 74 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
# Customization
22

3-
General patterns for styling, sizing, and interaction that apply across chart types.
3+
Customize charts through the style factories that accompany each chart. Start with the defaults and
4+
override the properties that support the result your screen needs. Style APIs vary by chart family;
5+
use the chart guides for chart-specific capabilities.
46

5-
## Style Customization
7+
## Style, Labels, and Formatting
68

7-
To customize chart appearance, start from each chart's `*ChartDefaults.style(...)` factory and override only the fields you need.
9+
This complete example styles a cash-flow chart with a teal bar color, quiet axes, a subtitle, and
10+
currency in selected-value readouts. The selected-value formatter does not change axis tick labels;
11+
each formatter has a separate role.
812

13+
<!-- BEGIN WIKI EXAMPLE: sample/androidApp/src/main/kotlin/io/github/hdcharts/app/docs/CustomizationGuideExample.kt#customization-styled-cash-flow -->
914
```kotlin
10-
import androidx.compose.foundation.background
11-
import androidx.compose.foundation.shape.RoundedCornerShape
15+
import androidx.compose.foundation.layout.fillMaxWidth
16+
import androidx.compose.foundation.layout.height
1217
import androidx.compose.runtime.Composable
1318
import androidx.compose.ui.Modifier
1419
import androidx.compose.ui.graphics.Color
@@ -19,247 +24,93 @@ import io.github.hdcharts.core.model.ChartValueFormatters
1924
import io.github.hdcharts.core.model.toChartData
2025
import io.github.hdcharts.core.style.AxesDefaults
2126
import io.github.hdcharts.core.style.AxisLinesDefaults
22-
import io.github.hdcharts.core.style.GridDefaults
2327
import io.github.hdcharts.core.style.BarChartDefaults
28+
import io.github.hdcharts.core.style.ChartContainerDefaults
29+
import io.github.hdcharts.core.style.GridDefaults
2430

2531
@Composable
26-
private fun ShowStyledBar() {
27-
val data = listOf(45.0, -12.0, 38.0, 27.0, -19.0, 42.0, 31.0).toChartData(
28-
categories = listOf("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"),
29-
seriesName = "Net cash flow",
30-
)
31-
32-
val bars = BarChartDefaults.bars(
33-
color = Color(0xFF0F766E),
34-
alpha = 0.78f,
35-
space = 14.dp,
36-
minBarWidth = 10.dp,
37-
)
38-
val grid = GridDefaults.style(color = Color(0xFF94A3B8), lineWidth = 1.dp)
39-
val selection = BarChartDefaults.selection(
40-
color = Color(0xFFEA580C),
41-
width = 1.dp,
42-
unselectedAlpha = 0.7f,
43-
)
44-
val xLabels = BarChartDefaults.xLabels(color = Color.Gray, size = 11.sp, maxCount = 6)
45-
val yLabels = BarChartDefaults.yLabels(color = Color.Gray, size = 11.sp, maxCount = 6)
46-
val axes = AxesDefaults.style(
47-
lines = AxisLinesDefaults.style(color = Color.Gray, lineWidth = 1.dp),
48-
grid = grid,
49-
xLabels = xLabels,
50-
yLabels = yLabels,
51-
)
32+
fun StyledCashFlowChart() {
33+
val data =
34+
listOf(45.0, -12.0, 38.0, 27.0, -19.0).toChartData(
35+
categories = listOf("Mon", "Tue", "Wed", "Thu", "Fri"),
36+
seriesName = "Net cash flow",
37+
)
38+
val axes =
39+
AxesDefaults.style(
40+
lines = AxisLinesDefaults.style(color = Color(0xFF64748B)),
41+
grid = GridDefaults.style(color = Color(0xFFCBD5E1)),
42+
xLabels = BarChartDefaults.xLabels(color = Color(0xFF475569), size = 12.sp),
43+
yLabels = BarChartDefaults.yLabels(color = Color(0xFF475569), size = 12.sp),
44+
)
5245

5346
BarChart(
5447
data = data,
55-
modifier = Modifier.background(Color(0xFFF8FAFC), RoundedCornerShape(18.dp)).padding(20.dp),
56-
title = "Daily Net Cash Flow",
57-
style = BarChartDefaults.style(bars = bars, axes = axes, selection = selection),
58-
selectedValueFormatter = ChartValueFormatters.prefix("$"),
59-
)
60-
}
61-
```
62-
63-
Chart chrome (background, shape, shadow, and outer padding) lives on the caller-supplied `modifier`; sizing is fully modifier-driven. The `chartContainerStyle` block carries `contentPadding` and the title and subtitle text styles.
64-
65-
Here `selectedValueFormatter` adds currency to selected raw values only; Y ticks keep the independent `axisValueFormatter` default. Titles do not generate labels: omitting `categories` hides X labels and leaves only the formatted value in selected readouts.
66-
67-
Several charts can paint their shapes with a gradient instead of a solid color, covered in
68-
[Gradients](/{{version}}/wiki/gradients).
69-
70-
## Axes
71-
72-
Bar, histogram, line, stacked bar, and stacked area charts share `AxesStyle`. Its `lines`, `grid`,
73-
`xLabels`, and `yLabels` blocks control each element separately. `lines` means the X- and Y-axis
74-
strokes, including the chart baseline.
75-
76-
Set `axes = AxesDefaults.style(visible = false)` to hide all four elements and reclaim label space.
77-
This also hides the grid on a sparkline. To keep labels and grid while hiding just the axis strokes,
78-
use `AxesDefaults.style(lines = AxisLinesDefaults.style(visible = false))`.
79-
80-
## Axis Labels
81-
82-
Cartesian charts take `xLabels(...)` and `yLabels(...)` from their `*ChartDefaults`. Their `maxCount` is null by default, which lets the chart choose:
83-
84-
- X labels show as many categories as fit, evenly spaced from the first item, and never overlapping. Wider charts show more labels.
85-
- Y labels show up to five values, evenly spaced from the lowest to the highest value. Short charts show fewer, so labels never overlap.
86-
87-
Set `maxCount` to cap the number of labels; it must be in 2..1000. Labels never overlap, so a chart can show fewer than `maxCount`:
88-
89-
- X labels use the densest even grid from the first item with at most `maxCount` labels. When the chart scrolls, the cap applies per screen. Without scrolling, a grid that ends on the last item wins when it shows at most one label fewer.
90-
- Y labels show `maxCount` values when they fit.
91-
92-
```kotlin
93-
val style =
94-
BarChartDefaults.style(
95-
axes =
96-
AxesDefaults.style(
97-
xLabels = BarChartDefaults.xLabels(maxCount = 4),
98-
yLabels = BarChartDefaults.yLabels(maxCount = 6),
48+
modifier = Modifier.fillMaxWidth().height(280.dp),
49+
title = "Daily net cash flow",
50+
subtitle = "Revenue minus costs · 14–18 October",
51+
style =
52+
BarChartDefaults.style(
53+
bars = BarChartDefaults.bars(color = Color(0xFF0F766E)),
54+
axes = axes,
55+
chartContainerStyle =
56+
ChartContainerDefaults.style(
57+
styleSubtitle = ChartContainerDefaults.style().styleSubtitle.copy(fontSize = 16.sp),
58+
contentPadding = 12.dp,
59+
),
9960
),
100-
)
101-
```
102-
103-
## Grid Lines
104-
105-
Bar, histogram, line, stacked bar, and stacked area charts draw horizontal grid lines. Configure `axes.grid` with `GridDefaults.style(...)`: `visible`, `steps`, `color`, and `lineWidth`. When Y labels show, the grid draws one line on each label, so it keeps matching them on short plots and with `yLabels(maxCount = ...)`. With Y labels hidden, `steps` sets the number of intervals; the default 4 steps draw 5 evenly spaced lines.
106-
107-
```kotlin
108-
val style =
109-
LineChartDefaults.style(
110-
axes = AxesDefaults.style(grid = GridDefaults.style(color = Color.LightGray)),
111-
)
112-
```
113-
114-
Pass `GridDefaults.style(visible = false)` to hide only the grid.
115-
116-
## Sizing
117-
118-
The chart composable's `modifier` is the only sizing control. A bounded `modifier` becomes a rectangular plot; a one-axis bounded `modifier` derives a square fallback; a fully unbounded `modifier` falls back to a 200.dp default.
119-
120-
```kotlin
121-
val dataSet = listOf(42.0, 38.0, 45.0, 51.0, 47.0, 54.0, 49.0).toChartData()
122-
123-
LineChart(
124-
data = dataSet,
125-
modifier = Modifier
126-
.fillMaxWidth()
127-
.height(260.dp),
128-
)
129-
```
130-
131-
## Surrounding Chrome
132-
133-
Background, shadow, shape, and outer spacing are not applied by the chart. Wrap the chart in any Compose surface to add chrome.
134-
135-
```kotlin
136-
val dataSet = listOf(42.0, 38.0, 45.0, 51.0, 47.0, 54.0, 49.0).toChartData()
137-
138-
Card(modifier = Modifier.padding(16.dp)) {
139-
LineChart(
140-
data = dataSet,
141-
modifier = Modifier
142-
.fillMaxWidth()
143-
.height(260.dp),
61+
selectedValueFormatter = ChartValueFormatters.prefix("$"),
14462
)
14563
}
14664
```
65+
<!-- END WIKI EXAMPLE: customization-styled-cash-flow -->
14766

148-
## Title and Subtitle
149-
150-
Every chart accepts optional `title` and `subtitle` text. The subtitle appears below the title
151-
with a 4 dp gap and stays visible when selection changes the title. A subtitle also works on its
152-
own. Null or blank subtitles reserve no space.
153-
154-
```kotlin
155-
LineChart(
156-
data = dataSet,
157-
title = "Daily Support Tickets",
158-
subtitle = "Resolved tickets per day · October 2026",
159-
)
160-
```
161-
162-
Use `ChartContainerDefaults.style(styleTitle = ..., styleSubtitle = ...)` to customize each text
163-
style. The subtitle defaults to 14 sp text with the theme's `onSurfaceVariant` color.
164-
165-
```kotlin
166-
val container = ChartContainerDefaults.style()
167-
LineChart(
168-
data = dataSet,
169-
subtitle = "Resolved tickets per day",
170-
style = LineChartDefaults.style(
171-
chartContainerStyle = ChartContainerDefaults.style(
172-
styleSubtitle = container.styleSubtitle.copy(fontSize = 16.sp),
173-
),
174-
),
175-
)
176-
```
177-
178-
## Content Spacing
179-
180-
`ChartContainerDefaults.style()` returns a `ChartContainerStyle` with `styleTitle`, `styleSubtitle`, and `contentPadding`. Set `contentPadding` to change the internal spacing reserved for axes, title, and legend.
67+
## Titles and Typography
18168

182-
```kotlin
183-
val dataSet = listOf(42.0, 38.0, 45.0, 51.0, 47.0, 54.0, 49.0).toChartData()
69+
Every chart accepts a title and subtitle. A subtitle appears below the title and can also appear by
70+
itself. Set `styleTitle` and `styleSubtitle` through `ChartContainerDefaults.style(...)` to customize
71+
their `TextStyle`s. The container style also controls internal `contentPadding`, which reserves room
72+
for chart content such as labels and legends.
18473

185-
LineChart(
186-
data = dataSet,
187-
modifier = Modifier.fillMaxWidth().height(260.dp),
188-
style = LineChartDefaults.style(
189-
chartContainerStyle = ChartContainerDefaults.style(contentPadding = 8.dp),
190-
),
191-
)
192-
```
74+
## Size and Surrounding Layout
19375

194-
## Selection
76+
Use the chart composable's `modifier` to set its size. Standard Compose layout modifiers such as
77+
`fillMaxWidth()` and `height(...)` work with charts. Bounded width and height define the chart size;
78+
when one axis is unbounded the chart uses a square fallback based on the bounded axis, and when both
79+
are unbounded the default plot size is 200 dp. Put a chart in a `Card`, `Column`, or other container
80+
to add a background, shape, shadow, or outer spacing; those belong to the caller's layout.
19581

196-
Use `rememberChartSelection()` to hoist selection. The chart calls back into it; you read `selectedIndex` to drive external UI such as legends or summary cards.
82+
## Axes, Colors, and Palettes
19783

198-
```kotlin
199-
val selection = rememberChartSelection()
200-
val values = listOf(42.0, 38.0, 45.0, 51.0, 47.0, 54.0, 49.0)
84+
Bar, histogram, line, stacked bar, and stacked area charts provide `AxesStyle` for axis lines, grid lines, and X and Y labels. `AxesDefaults.style(visible = false)` hides those elements together; set an individual block's visibility when only one element needs to change. The pie and ring chart families expose different labels and style options.
20185

202-
LineChart(
203-
data = values.toChartData(),
204-
modifier = Modifier.fillMaxWidth().height(260.dp),
205-
selection = selection,
206-
)
86+
Axis labels are evenly spaced and avoid overlap. By default the chart chooses how many X labels fit; Y axes show up to five values and short charts can show fewer. Set a label block's `maxCount` to cap the count (valid values are 2 through 1000); the chart can still show fewer when labels do not fit. When Y labels are visible, grid lines align with them. When they are hidden, `GridStyle.steps` controls the horizontal intervals; the default four steps produce five lines.
20787

208-
val selected = values.getOrNull(selection.selectedIndex ?: 0)
209-
Text("Selected: $selected")
210-
```
88+
Use each chart family's style factory to choose shape colors, line widths, label text styles, spacing,
89+
or palettes. Default colors follow the Material theme. Multi-series chart families can use a palette in series order; palette support and
90+
legend behavior vary by chart. A gradient can replace a shape's solid color on supported chart families; see the
91+
[Gradients guide](/{{version}}/wiki/gradients). For chart-specific palette and legend behavior, see
92+
[pie](/{{version}}/wiki/pie-chart), [radar](/{{version}}/wiki/radar-chart), [stacked bar](/{{version}}/wiki/stacked-bar-chart), and [stacked area](/{{version}}/wiki/stacked-area-chart).
21193

212-
## Legend
94+
## Formatting and Selection
21395

214-
Line, live line, radar, stacked bar, and stacked area charts list their series in a legend, and pie
215-
and ring gauge charts list their categories. The legend shows when there are at least two items and at least one has a name.
216-
Hide it with the chart's `legend` style:
96+
Axis tick formatters and selected-value formatters are separate. Use `axisValueFormatter` for numeric
97+
axis labels and `selectedValueFormatter` for selection readouts; the supported parameters vary by
98+
chart. `ChartValueFormatters` provides common prefix and suffix formatters. See [bar formatting](/{{version}}/wiki/bar-chart), [stacked bar formatting](/{{version}}/wiki/stacked-bar-chart), and [ring gauge formatting](/{{version}}/wiki/ring-gauge-chart) for examples matched to those chart APIs.
21799

218-
```kotlin
219-
StackedBarChart(
220-
data = data,
221-
style = StackedBarChartDefaults.style(
222-
legend = StackedBarChartDefaults.legend(visible = false),
223-
),
224-
)
225-
```
226-
227-
While a point is selected, a chart with several series shows each series' value in its legend item,
228-
and the title shows the selected category. A chart with one series shows `Category: value` in the
229-
title instead. Pass `selectedValueFormatter` to format these values. A pie shows `Category: share` in the title,
230-
with the share in percent formatted by its `selectedValueFormatter`, and its legend does not change. A ring gauge is one series, so it
231-
shows `Category: value` in the title, and its legend does not change either. A hidden legend hides the values
232-
too; read `selectedIndex` from a hoisted selection to show them in your own UI.
100+
Charts that support selection can expose it to surrounding Compose UI through
101+
`rememberChartSelection()`. Legend contents and selection behavior differ between chart families;
102+
the [legend guide](/{{version}}/wiki/dev/internals/legend) describes the shared behavior, and individual
103+
chart guides show supported interactions.
233104

234105
## Animation and Interaction
235106

236-
`animateOnStart` controls the initial reveal animation; `interactionEnabled` disables gestures, selection, and zoom controls together. Disable interaction to embed a chart inside a tappable card without conflicts.
237-
238-
```kotlin
239-
val dataSet = listOf(42.0, 38.0, 45.0, 51.0, 47.0, 54.0, 49.0).toChartData()
240-
241-
LineChart(
242-
data = dataSet,
243-
modifier = Modifier.fillMaxWidth().height(260.dp),
244-
animateOnStart = true,
245-
interactionEnabled = false,
246-
)
247-
```
248-
249-
## Responsive Layout
107+
Where offered, `animateOnStart` controls the initial reveal and `interactionEnabled` controls chart
108+
gestures. Their availability and effects depend on the chart family. Check that chart's guide before
109+
using either parameter.
250110

251-
Compose the chart with any layout, including `Row`, `Column`, `LazyColumn`, or `BoxWithConstraints`. A bounded `modifier` is always honored; an unbounded one falls back to the documented defaults.
111+
## API Reference
252112

253-
```kotlin
254-
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
255-
LineChart(
256-
data = lineData,
257-
modifier = Modifier.fillMaxWidth().height(220.dp),
258-
)
259-
Spacer(modifier = Modifier.height(16.dp))
260-
BarChart(
261-
data = barData,
262-
modifier = Modifier.fillMaxWidth().height(220.dp),
263-
)
264-
}
265-
```
113+
- [ChartContainerDefaults](/static/api/{{version}}/charts/io.github.hdcharts.core.style/-chart-container-defaults/index.html)
114+
- [AxesStyle](/static/api/{{version}}/charts/io.github.hdcharts.core.style/-axes-style/index.html)
115+
- [BarChartDefaults](/static/api/{{version}}/charts/io.github.hdcharts.core.style/-bar-chart-defaults/index.html)
116+
- [ChartValueFormatters](/static/api/{{version}}/charts/io.github.hdcharts.core.model/-chart-value-formatters/index.html)

0 commit comments

Comments
 (0)