Bar Chart
Grouped and stacked bars with sub-cell precision, axes, and legend.
Overview
The BarChart control renders one or more ChartSeries as
categorical bars. Series can be laid out grouped (side by side) or
stacked, in either vertical or horizontal
orientation. Bar lengths use Unicode eighth-blocks for smooth sub-cell resolution, and a
"nice-number" value axis, dotted grid, category labels, and a legend are drawn automatically.
Provide data inline with <ChartSeries>/<ChartDataPoint>
elements, or bind a collection to SeriesSource.
Properties
| Property | Type | Description |
|---|---|---|
Series | IList<ChartSeries> | Inline series collection (content property). |
SeriesSource | IEnumerable | Bound series collection; overrides Series. |
BarMode | BarMode | Grouped or Stacked. |
Orientation | Orientation | Vertical (default) or Horizontal. |
ShowValues | bool | Draw each bar's numeric value at its tip. |
ShowAxes / ShowGrid / ShowLegend | bool | Toggle chart chrome. |
SelectedIndex | int | Selected category index (-1 = none). Two-way bindable. |
SelectedItem | object | The selected category's label, kept in sync with SelectedIndex. Two-way bindable. |
Interactivity
The chart is focusable. Give it focus (Tab, or click) and use the arrow keys to move the
category selection — ←/→ for vertical bars, ↑/↓ for
horizontal — plus Home/End; or click a category directly. The selected
category is highlighted (brighter while focused) and SelectedIndex/
SelectedItem update two-way.
Data Binding
Instead of declaring points inline, bind a collection from a ViewModel to
SeriesSource. The chart subscribes to INotifyCollectionChanged,
so adding or removing a series re-renders automatically. Data classes and ViewModels must
be public or internal (never private) so the AOT
source generator can emit their binding accessors.
public sealed class RevenueViewModel : ViewModelBase
{
public ObservableCollection<ChartSeries> Revenue { get; } =
[
new ChartSeries { Name = "2024",
Values = { new() { Label = "Q1", Value = 42 },
new() { Label = "Q2", Value = 55 } } },
];
// Adding or removing a whole series re-renders the chart automatically.
public void AddForecast() => Revenue.Add(new ChartSeries
{
Name = "2025",
Values = { new() { Label = "Q1", Value = 35 },
new() { Label = "Q2", Value = 60 } }
});
}
<BarChart SeriesSource="{Binding Revenue}" BarMode="Grouped" />
Note: ChartSeries.Values is a plain list, so mutating points inside
an existing series does not auto-refresh — add/remove at the series level, or replace the
series, to trigger a redraw.
Key Concepts
ChartSeries.ValuesholdsChartDataPointitems (Label + Value).- Bars use eighth-block characters (
▁▂▃▄▅▆▇█) for sub-cell precision. - The value axis is auto-scaled to "nice" round numbers with a dotted grid.
- Series colors come from the theme-aware palette, overridable via
ChartSeries.Color. - Bind live data through
SeriesSourcewith anObservableCollection.