Sparkline
v0.0.10
mix mishka.ui.gen.headless sparkline
Overview of the Phoenix and LiveView Headless Sparkline Component
The Mishka Chelekom Headless Sparkline draws a small trend line as server-rendered SVG. In a Phoenix template you pass a list of numbers with values and it renders one inline svg, with no JavaScript, no hook and no npm package. Because it is only markup, it works anywhere HEEx renders, from a stat card to a table cell to a line of text, and it stays correct through a LiveView patch.
The sparkline draws with currentColor, so it takes the text color around it. Set the color with a text class such as text-emerald-500 on the sparkline or on a parent. There are three types: line, area and bar. Size it with width and height, or with Tailwind size classes. It does not depend on the Chart component, and you can use either one without the other. class goes on the SVG itself.
Base UI Sparkline example - trend line with the last point marked (Phoenix headless)
Base UI Sparkline example - trend line with the last point marked (Phoenix headless)
<.sparkline
values={[4, 7, 5, 9, 8, 12, 10, 14]}
last_point
aria_label="Weekly signups, trending up"
class="h-10 w-40 text-neutral-950 dark:text-white"
/>This is the markup it renders for the example above. The line is one path, and the last point is a circle:
<svg viewBox="0 0 120 36" width="120" height="36" fill="none" preserveAspectRatio="none" role="img" aria-label="Weekly signups, trending up" class="chelekom-sparkline h-10 w-40 text-neutral-950 dark:text-white">
<path d="M 2.5 33.5 L 18.93 24.2 L 35.36 30.4 L 51.79 18.0 L 68.21 21.1 L 84.64 8.7 L 101.07 14.9 L 117.5 2.5" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" vector-effect="non-scaling-stroke"></path>
<circle cx="117.5" cy="2.5" r="2.0" fill="currentColor"></circle>
</svg>Base UI Sparkline example - line, area and bar types (Phoenix headless)
Base UI Sparkline example - line, area and bar types (Phoenix headless)
<div class="flex flex-wrap items-center gap-6 text-neutral-950 dark:text-white">
<.sparkline
:for={type <- ~w(line area bar)}
values={[4, 7, 5, 9, 8, 12, 10, 14]}
type={type}
aria_label={"Weekly signups (#{type})"}
class="h-10 w-32"
/>
</div>Type, scale and markers
values is required: the numbers to plot, oldest first. A numeric string is read as a number, and anything else counts as 0. type is line (the default), area (the line plus a faded fill) or bar. width and height set the intrinsic size in pixels and default to 120 and 36. The SVG uses preserveAspectRatio="none", so a w-* or h-* class stretches it, and the line keeps its thickness because the stroke does not scale.
The line is scaled to the lowest and highest value in the data, which shows the shape and not the level. Set min and max to pin the scale, for example to compare several sparklines on one range. If every value is the same, the line runs through the middle and the bars fill the height. smooth rounds the line with a curve and needs at least three points. stroke_width sets the line thickness (default 1.5). fill_opacity sets the area fill (default 0.15). rounded sets the bar corner radius and gap the space between bars (default 2), both in SVG units. last_point draws a dot on the final value, and baseline draws a faint line at zero when the value range includes zero.
Type, scale and markers
<.sparkline values={@revenue} type="area" smooth last_point class="h-8 w-24 text-emerald-500" />
<.sparkline values={@deltas} type="bar" baseline rounded={1} class="h-8 w-24 text-sky-500" />
<.sparkline values={@a} min={0} max={100} class="h-8 w-24" />
<.sparkline values={@b} min={0} max={100} class="h-8 w-24" />color sets the whole sparkline's color from a CSS color string. It is written to the SVG as an inline style attribute, so prefer a text color class when your content security policy restricts inline styles.
Accessibility
A sparkline is decorative by default and renders with aria-hidden="true". Pass aria_label and it renders with role="img" and that label instead. Write the label as the summary a reader needs, such as "Revenue, up 12% over 8 weeks", because the individual points are not exposed. It has no keyboard behavior.
Attributes
| Name | Type | Default | Values | Required | Description |
|---|---|---|---|---|---|
values
|
list
| — | — | Yes | The numbers to plot, oldest → newest |
type
|
string
|
line
|
lineareabar
| No | `line`, `area` (line + faded fill) or `bar` |
width
|
integer
|
120
| — | No | Intrinsic SVG width in px (override responsively with a `w-*` class) |
height
|
integer
|
36
| — | No | Intrinsic SVG height in px |
stroke_width
|
any
|
1.5
| — | No | Line thickness (non-scaling, stays crisp when the SVG is resized) |
smooth
|
boolean
|
false
| — | No | Round the line with a Catmull-Rom curve instead of straight segments |
fill_opacity
|
any
|
0.15
| — | No | Opacity of the area fill (type="area") |
rounded
|
any
|
0
| — | No | Bar corner radius in SVG units (type="bar") |
gap
|
any
|
2
| — | No | Gap between bars in SVG units (type="bar") |
last_point
|
boolean
|
false
| — | No | Draw a dot on the final value |
baseline
|
boolean
|
false
| — | No | Draw a faint line at zero when the value range crosses it |
min
|
any
| — | — | No | Force the low end of the value domain (default: the data min) |
max
|
any
| — | — | No | Force the high end of the value domain (default: the data max) |
color
|
string
| — | — | No | CSS color for the whole sparkline (default: inherit `currentColor`) |
aria_label
|
string
| — | — | No | Expose a text summary; makes the SVG `role="img"` instead of `aria-hidden` |
class
|
any
| — | — | No | Extra classes for the SVG |
rest
|
global
| — | — | No | — |
Options
Each option takes one or more of its values, separated by commas.
| Option | Values |
|---|---|
--type
|
sparkline
|
--module
| A module name of your own |
What it generates
mix mishka.ui.gen.headless sparkline