Skip to content
Barua UI v0.2
Components

Data Visualization

Lightweight charts built from CSS and inline SVG — no charting library, no build step. Bars, pies, gauges and heatmaps are pure CSS driven by custom properties; lines, areas, scatters and radars are hand-written SVG that the stylesheet colors for you. Every series pulls from the --b-chart-1…6 tokens, and every chart pairs with .b-legend and .b-axis.

Chart Anatomy

.b-chart is the frame: a titled column that stacks .b-chart__title, a .b-chart__canvas (position-relative, so gridlines and tooltips can float inside it), and a .b-legend. Axes sit beside or below the canvas. Everything below is this one recipe, swapping the middle.

Accessibility. A chart is an image to assistive tech. Give the composed figure role="img" with a concise aria-label that states the takeaway (“peaking Thursday at 4,120”), or use <figure> + <figcaption>. For data people need to act on, follow the chart with a .b-sr-only (or disclosed) table of the numbers, and mark decorative internals — gridlines, axes, sparklines — with aria-hidden="true".

Column Chart

.b-columns lays vertical bars on a flex baseline. Each .b-columns__bar takes its height from --v (a percentage of the chart height, --b-chart-h, default 10rem) and its x-label from data-label. Recolor any bar with --b-chart-color — here Thursday's peak.

Rounded

.b-columns--rounded turns bars into capsules — the Screen Time look. Best with generous gaps and a dozen bars or fewer.

Stacked segments

Nest an <i> inside a bar for a bottom-aligned segment: the bar is the total, the segment its share. The segment defaults to --b-chart-2; both accept --b-chart-color.

  • Sent
  • Opened
Start bar and column value axes at zero. Length is the encoding — a truncated axis turns a 4% difference into a visual cliff. If small deltas matter, plot the delta itself.
Don't pour more than ~5 slices into a pie. Thin wedges are unreadable and uncomparable; reach for a horizontal .b-bars chart instead, which ranks and compares precisely.

Bar Chart

Horizontal bars for ranked categories with long labels. Each .b-bars__row is a three-column grid: label, track, value. Fill width comes from --v; widen the label column with --b-bars-label-w when city names need room.

Dar es Salaam
$120k
Nairobi
$100k
Kampala
$72k
Kigali
$56k
Zanzibar
$36k

Line Chart

Lines are plain inline SVG — you own the coordinates, the stylesheet owns the look. Give the polyline path class="b-series" inside an svg.b-line-svg; add dashed .b-svg-grid lines and .b-svg-axis-label texts. The stroke stays 2px at any size thanks to vector-effect: non-scaling-stroke.

New subscribers — six months
Mar Apr May Jun Jul Aug

Area Chart

An svg.b-area-svg with two paths: a closed .b-area-fill underneath (same points, dropped to the baseline) and the .b-series stroke on top. The fill is an 18% tint of the series color, so one --b-chart-color on the <svg> retints both.

Weekly active readers
Mar May Jul

Pie Chart

A single div and a conic-gradient. Pass color stops through --b-pie as color start end triplets covering 0–100%; size it with --b-pie-size (default 9rem). Always pair with a legend — the wedges carry no text of their own.

  • Mobile · 45%
  • Desktop · 33%
  • Tablet · 22%

Donut Chart

Wrap a .b-pie in .b-donut: a radial mask punches the hole and .b-donut__center stacks on the same grid cell for a headline stat. The hole radius is --b-donut-hole, default 62% — raise it for a thinner ring.

18.2k
sends
  • Newsletter · 52%
  • Product updates · 29%
  • Digests · 19%

Scatter Plot

An svg.b-scatter-svg full of circle.b-dot elements — you supply cx, cy and r. Dots default to --b-chart-1; put --b-chart-color on individual circles for a second series. Session length against pages read, mobile vs desktop:

Session length vs pages read
0 min 15 min 30 min
  • Mobile
  • Desktop

Data points

.b-dot is reusable on any SVG chart — drop circles onto a line chart to mark readings. Dots wear a hairline ring of var(--b-bg) so they cut cleanly out of gridlines, and grow from r="4" to 6 on hover as a pointer affordance. Actual hit-testing and value display is app-side wiring — see Chart Tooltip.

Radar Chart

Concentric polygon.b-web rings and line.b-web spokes form the web; the filled polygon.b-series plots the values. Five axes on a 200×200 viewBox, center (100,100), outer radius 80.

Design Code Data Ops Docs

Heatmap

A CSS grid of <i> cells. Column count comes from --b-heatmap-cols; each cell's --v is an intensity from 0 to 1, mixed into the series color with color-mix() — 0 renders the empty fill, 1 the full --b-chart-color. Twelve months of commits, one row per week of the month:

JanJunDec

Gauge

A half-donut for a single 0–100 reading. Set --b-progress as a unitless number (here 68 — note the linear progress bar takes a percentage instead), size with --b-gauge-size, and recolor with --b-chart-color. The label hangs below the arc, so leave it some room.

Sparkline

A word-sized trend for stat cards and table cells: svg.b-sparkline stretches its single path across a 2rem-tall box (preserveAspectRatio="none" lets it fill; the stroke never distorts). Purely decorative — keep it aria-hidden and let the stat carry the numbers.

Messages sent 12,480 ↑ 8.2% this week
Open rate 38.4% ↓ 2.1 pts this week

Progress Chart

Stacked .b-progress-chart__rows, each a __head (label left, value right) over a standard .b-progress bar from Feedback. Here --b-progress is a width percentage on the fill — 96%, unit included.

Newsletter96%
Product updates88%
Onboarding series72%
Win-back41%

Legend

A wrapping ul.b-legend of swatch + label pairs. The .b-legend__swatch defaults to --b-chart-1; set the others inline. The six series tokens resolve to accent blue, teal, purple, orange, pink and green — and re-tune automatically in dark mode.

  • Email
  • Push
  • In-app
  • SMS
  • Social
  • Webhooks
Accessibility. Never let color be the only channel. Keep the legend adjacent to the chart, print values directly on rows and slices where space allows, and order legend items to match the visual order of the series. The six chart tokens are chosen to differ in lightness, not just hue — but a swatch plus a text label is what actually guarantees the mapping for everyone.

Axis & Gridlines

.b-axis spreads tick labels across a row in tabular figures; .b-axis--y stacks them beside a canvas. .b-gridlines floats dashed rules through a position-relative canvas — one <i> per line. Columns reserve a 1.4rem label strip at the bottom, so give the gridlines inset-block-end: 1.4rem and the y-axis the same bottom padding to keep “0” on the baseline.

The horizontal axis also works standalone — under heatmaps, area charts or timeline strips:

00:0006:0012:0018:0024:00

Chart Tooltip

.b-chart-tip is a floating value bubble for the nearest data point: absolutely positioned inside the relative .b-chart__canvas, self-centered above its anchor via translate, with a small caret. Barua ships the look only — tracking the pointer, picking the point and setting left/top is app-side JavaScript. Shown pinned over Thursday:

Thu · 4,120

Rule Mark

Swift Charts' RuleMark: a dashed goal or threshold line laid over any chart canvas. Position with bottom as a percentage of the scale; --accent recolors it for targets rather than limits.

SLA 70%

Linear Gauge

SwiftUI's linear Gauge style: a graded track with a marker at the current value (--v) and min/max labels beneath. Use __track--plain for a neutral track.

0 GB15 GB
MinMax