Charts
The chart components draw with Chart.js, which loads the first time a chart shows, so pages without charts never fetch it. A pie or bar chart shows its values beside a legend, and a line chart draws data sets over a time axis.
Pie charts
Ui::pieChart() draws its values as a ring, size pixels across, 200 by default. centerText shows inside the ring, centered: true centers the ring above its legend, and wrapLegend: true lays the legend out in a row. Hovering a part of the ring shows its label and value.
<div class="d-flex flex-wrap align-items-start gap-5">
{{ Ui::pieChart(size: 160, centerText: '114', values: [
'Published' => [84, 'var(--bs-success-base)'],
'Drafts' => [12, 'var(--bs-warning-base)'],
'Deleted' => [18, 'var(--bs-danger-base)'],
]) }}
{{ Ui::pieChart(size: 160, centered: true, wrapLegend: true, values: [
'Search' => 412,
'Direct' => 238,
'Social' => 97,
'Email' => 64,
]) }}
</div>Values
The values of a pie or bar chart take the forms options do: a label and its value, a label and a [value, color] pair, or a definition with label, value and color keys. A color can be any CSS color, including a variable such as var(--bs-success-base), and a value without one takes the next from the palette, which is Bootstrap's colors. Labels are escaped.
{{ Ui::barChart(height: 120, values: [
// A label and its value, colored from the palette
'Monday' => 32,
// A label and a [value, color] pair, where the color can be a CSS variable
'Tuesday' => [41, 'var(--bs-violet-500)'],
// A detailed definition, for labels that are not keys
['label' => 'Wednesday', 'value' => 27, 'color' => '#00b4f8'],
]) }}Bar charts
Ui::barChart() draws one bar per value, rounded at the top, height pixels tall, 100 by default, scaled to the largest value. fullWidth: true spreads the bars across their container, with the legend below.
{{ Ui::barChart(height: 100, fullWidth: true, wrapLegend: true, values: [
'Jan' => 18, 'Feb' => 24, 'Mar' => 31, 'Apr' => 27, 'May' => 35, 'Jun' => 42,
'Jul' => 39, 'Aug' => 44, 'Sep' => 51, 'Oct' => 48, 'Nov' => 56, 'Dec' => 61,
]) }}Line charts
Ui::lineChart() draws its datasets over a time axis, height pixels tall, 250 by default, or any CSS length, such as '20rem'. Each data set is its points keyed by its name, or a definition with a color, which takes the next from the palette when it has none, its data, and the Flot style lines and points options, such as 'lines' => ['fill' => false] for a line without the area under it.
Lines are smooth, without overshooting their points, and the area under them fades out toward the bottom. Points show on hover, where the tooltip lists the value of every data set at that date. 'lines' => ['smooth' => false] draws straight lines, and 'points' => ['show' => true] shows the points always.
The points are values keyed by date, as above, or [date, value] pairs, as in the next example. A date is a date string, a DateTimeInterface, such as a Carbon date, or a timestamp in milliseconds. Dates show as they are written, whatever the visitor's timezone, so a sale at 9am on the 3rd shows at 9am on the 3rd. timeMode: 'weeks' shades the weekends.
@php
$visits = [];
$orders = [];
foreach (range(0, 27) as $day) {
$date = now()->startOfMonth()->subMonth()->addDays($day)->toDateString();
$visits[$date] = 400 + (int) (120 * sin($day / 3)) + ($day * 6);
$orders[$date] = 40 + (int) (18 * cos($day / 4)) + $day;
}
@endphp
{{ Ui::lineChart(height: 260, timeMode: 'weeks', datasets: [
'Visits' => ['color' => 'var(--bs-blue-500)', 'data' => $visits],
'Orders' => ['color' => 'var(--bs-green-500)', 'data' => $orders, 'lines' => ['fill' => false]],
]) }}Zooming
zoomable: true lets the visitor drag across a line chart to zoom in on the range they cover. resetZoomLink takes a selector for a link that shows while the chart is zoomed and returns it to the whole range when clicked.
@php
$signups = [];
foreach (range(0, 89) as $day) {
$signups[] = [now()->startOfDay()->subDays(89 - $day), 30 + (int) round(10 * sin($day / 8)) + intdiv($day, 4)];
}
@endphp
<p>
Drag across the chart to zoom in.
<a href="#" id="chartResetZoom" style="display: none">
Reset zoom
</a>
</p>
{{ Ui::lineChart(height: 220, zoomable: true, resetZoomLink: '#chartResetZoom', datasets: [
'Signups' => ['color' => 'var(--bs-violet-500)', 'data' => $signups, 'points' => ['show' => false]],
]) }}Chart.js options
config takes Chart.js options, merged over the chart's own, for anything the arguments do not cover, such as the axis range or the tick unit. Every chart takes it.
{{ Ui::lineChart(height: 220, datasets: [
'Temperature' => ['color' => 'var(--bs-red-500)', 'data' => [
'2026-11-01' => 18, '2026-11-02' => 21, '2026-11-03' => 19, '2026-11-04' => 24, '2026-11-05' => 26,
]],
], config: [
'scales' => [
'x' => ['time' => ['unit' => 'day']],
'y' => ['min' => 0, 'max' => 30, 'ticks' => ['stepSize' => 10]],
],
'plugins' => ['legend' => ['display' => false]],
]) }}Events
A chart dispatches chart-pie:init, chart-bar:init or chart-line:init before it draws, with the Chart.js config in event.detail.config, which a listener may change, and chart-pie:ready, chart-bar:ready or chart-line:ready after, with the Chart.js instance in event.detail.chart. The instance is also on the control:
jax.fetchControl(element, 'chart-line').chart{{ Ui::barChart(id: 'chartEvents', height: 80, values: ['Mon' => 12, 'Tue' => 19, 'Wed' => 9]) }}
<p class="mb-0" id="chartEventsLog">
Waiting for the chart...
</p>
<script>
document.getElementById('chartEvents').addEventListener('chart-bar:ready', (event) => {
const chart = event.detail.chart;
document.getElementById('chartEventsLog').textContent = `Chart.js ${chart.constructor.version} drew ${chart.data.datasets[0].data.length} bars.`;
});
</script>A line chart's control also has addDataSet(), which adds a data set and draws the chart again, and clearZoom(), which returns it to the whole range.
Markup
The components write the chart controls' markup, which you can also write by hand. A line chart reads its data sets from data-chart="dataset" spans, whose data-set-data lists [timestamp, value] points, and takes Flot style options in data-chart-options.
<div
data-control="chart-line"
data-chart-options="xaxis: {mode: 'time', minTickSize: [1, 'day']}, legend: {show: false}"
style="height: 200px">
<span
data-chart="dataset"
data-set-name="Amount"
data-set-color="var(--bs-blue-500)"
data-set-data="[1793491200000, 400], [1793577600000, 380], [1793664000000, 340], [1793750400000, 540], [1793836800000, 440]">
</span>
</div>data-chart-options reads these keys, and data-chart-config takes Chart.js options as JSON for anything else:
| Key | Description |
|---|---|
| xaxis.mode | time, the default, or any other value for a plain number axis. |
| xaxis.minTickSize | the smallest tick unit, such as [1, 'day']. |
| xaxis.tickSize | the tick unit and step, such as [2, 'month']. |
| xaxis.timeformat | the tick label format, a strftime pattern such as %b %d. |
| xaxis.min, xaxis.max, yaxis.min, yaxis.max | the axis range. |
| xaxis.ticks, yaxis.ticks | the most ticks to show. |
| yaxis.tickDecimals | the decimal places of the value ticks. |
| legend.show | false hides the legend. |
| series.lines, series.points | the lines and points options of every data set, such as smooth and show. |
| grid.hoverable, tooltip | false turns off the tooltip. |
| colors | the colors of data sets that set none. |
A pie or bar chart reads its values from a list, each item a label with its value in a span and an optional data-color:
<div class="control-chart" data-control="chart-pie" data-size="160" data-center-text="114">
<ul>
<li data-color="#95b753">Published <span>84</span></li>
<li data-color="#e5a91a">Drafts <span>12</span></li>
</ul>
</div>Methods
| Method | Description |
|---|---|
| Ui::pieChart($values, $size, $centerText, $centered, $wrapLegend, $config) | a ring of values with a legend. |
| Ui::barChart($values, $height, $fullWidth, $wrapLegend, $config) | a bar per value with a legend. |
| Ui::lineChart($datasets, $height, $timeMode, $zoomable, $resetZoomLink, $config) | data sets over a time axis. |
Any other named argument, such as id or class, is added to the chart's element.