TallStackUI 4.0 is here! Seven new components and thousand of improvements. See what's new .

Powerful suite of Blade components for TALL Stack apps

Chart

Chart component.

<x-chart :series="[10, 40, 25, 60, 30, 80]" />

The chart works on its own or inside a card . This first example is shown without a card. Later previews wrap the chart in a card only so they are easier to read.

area (default), line, bar, pie and donut. Pie and donut need labels.

<x-chart :series="[10, 40, 25, 60, 30, 80]" area />
 
<x-chart :series="[10, 40, 25, 60, 30, 80]" line />
 
<x-chart :series="[10, 40, 25, 60, 30, 80]" bar />
 
<x-chart :series="[35, 25, 20, 20]"
:labels="['Direct', 'Organic', 'Social', 'Referral']"
pie
legend />
 
<x-chart :series="[35, 25, 20, 20]"
:labels="['Direct', 'Organic', 'Social', 'Referral']"
donut
legend />

Each type is also a flag, so line is the same as type="line" . Using two flags at once, or a flag next to a type that contradicts it, throws.

Named series share one scale. grid, legend, tooltip and markers are opt-in. Clicking a legend entry toggles its series.

0 20 40 60 80

Jan Feb Mar Apr May Jun
<x-chart :labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
:series="[
['name' => '2026', 'data' => [10, 40, 25, 60, 30, 80]],
['name' => '2025', 'data' => [8, 30, 33, 41, 22, 55]],
]"
grid
legend
tooltip
markers />

An option to stack series on top of each other, instead of overlapping.

0 50 100 150 200
Jan Feb Mar Apr
<x-chart :labels="['Jan', 'Feb', 'Mar', 'Apr']"
bar
stacked
:series="[
['name' => 'Active', 'data' => [12, 18, 15, 22]],
['name' => 'Inactive', 'data' => [30, 26, 34, 28]],
['name' => 'Recurring', 'data' => [18, 41, 12, 62]],
]"
grid
legend />

An option to combine different chart types within the same visualization.

0 20 40 60 80

Jan Feb Mar Apr
<x-chart :labels="['Jan', 'Feb', 'Mar', 'Apr']"
bar
stacked
:series="[
['name' => 'New', 'data' => [12, 18, 15, 22]],
['name' => 'Returning', 'data' => [30, 26, 34, 28]],
['name' => 'Total', 'data' => [42, 44, 49, 50], 'type' => 'line'],
]"
grid
legend
tooltip />

An option to plot a series against a second vertical axis on the right.

$1,000 $1,500 $2,000 $2,500 $3,000
8 un 10 un 12 un 14 un 16 un
Jan Feb Mar Apr
<x-chart :labels="['Jan', 'Feb', 'Mar', 'Apr']"
:series="[
['name' => 'Revenue', 'data' => [1200, 1900, 1500, 2100]],
['name' => 'Orders', 'data' => [8, 14, 11, 16], 'axis' => 'right'],
]"
grid
legend
:prefix="['left' => '$']"
:suffix="['right' => ' un']" />

Use color for a single series. Use colors when there are several.

Jan Feb Mar Apr
<x-chart :series="[10, 40, 25, 60, 30, 80]" color="emerald" />
 
<x-chart :labels="['Jan', 'Feb', 'Mar', 'Apr']"
:colors="['red', 'blue', 'amber']"
:series="[
['name' => 'A', 'data' => [10, 40, 25, 60]],
['name' => 'B', 'data' => [22, 18, 40, 30]],
['name' => 'C', 'data' => [5, 30, 15, 45]],
]"
legend />

prefix, suffix and decimals cover the common case. A closure wins over all three and receives the axis as a second argument.

$0.00 $2,000.00 $4,000.00 $6,000.00 $8,000.00
R$ 0,00 R$ 2.000,00 R$ 4.000,00 R$ 6.000,00 R$ 8.000,00
R$ 0,00 R$ 2.000,00 R$ 4.000,00 R$ 6.000,00 R$ 8.000,00

0 un 20 un 40 un 60 un 80 un
<!-- prefix, suffix and decimals cover the common case -->
<x-chart :series="$revenue" grid prefix="$" :decimals="2" />
 
<!-- Anything beyond it takes a closure -->
<x-chart :series="$revenue"
grid
:formatter="fn (float $value) => Number::currency($value, 'BRL', 'pt_BR')" />
 
<!-- The axis arrives as a second argument -->
<x-chart :formatter="fn (float $value, string $axis) => $axis === 'right'
? $value.' un'
: Number::currency($value, 'BRL', 'pt_BR')"
:series="[
['name' => 'Revenue', 'data' => $revenue],
['name' => 'Orders', 'data' => $orders, 'axis' => 'right'],
]"
grid
legend
tooltip />

How a line joins its points: smooth, straight or step.

Jan Feb Mar Apr May Jun
Jan Feb Mar Apr May Jun
<x-chart :series="[10, 40, 25, 60, 30, 80]" :labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']" curve="straight" />
 
<x-chart :series="[10, 40, 25, 60, 30, 80]" :labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']" curve="step" />
 
<!-- Per series. The chart default stays smooth. -->
<x-chart :series="[
['name' => 'Actual', 'data' => [10, 40, 25, 60, 30, 80]],
['name' => 'Target', 'data' => [12, 35, 28, 55, 32, 75], 'curve' => 'step'],
]" line legend />
Curve Behaviour
smooth A monotone cubic through every point, which never overshoots the data. Default
straight A line segment between consecutive points
step Holds each value until the next index, then jumps

A series can pick its own through a curve key next to type and axis . A stacked band walks its lower edge with the same shape, so steps stack without cutting across each other's corners. A radial type has no line to shape and refuses the attribute.

A null in the data is a gap, not a zero.

<x-chart :series="[44, 31, 38, null, 32, 55, 51, 67, 22, 34]" markers />

The line and the area break on either side of a null . A lone value between two gaps keeps its marker. No bar is drawn at a gap, unlike a zero, which keeps its hairline. The tooltip skips that series at the index and the scale ignores it. A pie or donut counts it as zero.

An option to set the corner radius of the bars.

Jan Feb Mar Apr May Jun
<x-chart :series="[12, 18, 15, 22, 30, 26]"
:labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
bar
round="md"
corners="end" />
Corners Behaviour
all Every corner of a bar, and both ends of a stacked column. Default
end Only the end away from the axis: the top of a positive bar, the bottom of a negative one, the far end of a stack

round accepts none , sm (the radius bars already had), md or lg . Both attributes also answer to the configuration. A radial type refuses them when they are passed explicitly; a configured default is ignored there, the way grid already behaves.

How the horizontal axis labels avoid overlapping on narrow plots.

Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
<x-chart :series="[10, 40, 25, 60, 30, 80, 45, 20, 55, 35, 70, 15]"
:labels="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']"
fit="rotate" />
Fit Behaviour
thin Shows every n-th label from the first one. The axis keeps its height. Default
rotate Slants every label by -45°, then thins only what still collides
stagger Alternates the labels over two rows, thinning each row on its own

Whenever labels exist, the axis measures itself in the browser and hides or rearranges captions so the visible ones never touch. It re-measures on resize, after a Livewire update and once fonts load. The default comes from fit in the configuration file.

An option to insert content above and below the plot.

Monthly Balance
0 20 40 60 80
Updated 2 minutes ago
<x-chart :series="[10, 40, 25, 60, 30, 80]" grid>
<x-slot:header>Monthly Balance</x-slot:header>
<x-slot:footer>
<div class="flex justify-end">
Updated 2 minutes ago
</div>
</x-slot:footer>
</x-chart>

An option to display a lazy loading skeleton indicator.

<x-chart skeleton />
 
<x-chart skeleton="10" bar />
 
<x-chart skeleton="5" donut />

There are a few things that can be configured using the configuration file. Height, grid, legend, tooltip, markers, fit , curve , round and corners all fall back to that file when the matching attribute is absent. The default height is 240 . A radial type ignores a configured grid , curve , round or corners rather than throwing; passing any of them explicitly on a pie or donut still throws.

Using soft customization you can paint the SVG. It does not redraw it. Every plot.* block works like any other, but the shapes are computed server-side. The curve and the corners answer to curve , round and corners . The donut hole and the tick count stay fixed.

What happens when the data cannot be drawn.

Input Result
Absent series Throws, unless skeleton is set
Empty array Full height, no path
Single value Spans the plot as a constant series
Negative values on pie or donut Clamped to zero
More than one series on pie or donut Throw an exception
null inside data A gap: the line breaks, no bar is drawn. A pie or donut counts it as zero
Non-numeric, NAN, INF Throw an exception. null is a gap, not an error
Unknown type, axis, curve, round or corners Throw an exception
curve, round or corners on pie or donut Throw when passed explicitly. A configured default is ignored
Two type flags at once Throw an exception
A type flag that contradicts type Throw an exception
stacked on line or radial type Throw an exception
stacked with a secondary axis Throw an exception
grid on pie or donut Throw an exception
Negative or non-integer decimals Throw an exception
Formatting array keyed other than left/right Throw an exception

Code highlighting provided by Torchlight