DEV Community

Cover image for Charts that look finished the moment you add them
Shaz M
Shaz M

Posted on

Charts that look finished the moment you add them


Every dashboard I've built has had the same moment: the numbers are right, and the chart still looks like it came free with a printer.

So I built Bezel Charts, a set of free, open-source chart web components that look polished with no setup. Add one script, write one tag, and you get a labelled, animated chart that follows the viewer's light or dark mode.

<script type="module" src="https://cdn.jsdelivr.net/gh/ShazMoghaddam/bezel-charts@1/dist/bezel-charts.min.js"></script>

<bezel-bars heading="Commits this week" values="4,9,6,3,8,5,3" labels="M,T,W,T,F,S,S" stat="total"></bezel-bars>
Enter fullscreen mode Exit fullscreen mode

That's the whole setup. No build step, no config object, no dependencies.

What's in it

Ten chart types: sparkline, line, bars, grouped bars, scatter, rings, donut, gauge, progress and a GitHub-style heatmap. Every one takes a title, labels, units like £ or %, your own colours, a goal line and notes pinned to key points ("Launch day").

Three things I wanted that most chart libraries don't do

1. Charts in a GitHub README. READMEs can't run JavaScript, so live charts are out. Every Bezel chart exports as a clean, self-contained SVG, so you can commit stars.svg and show a real chart in your README.

2. A Studio for people who don't want to write code. Pick a chart, import a CSV, Excel or JSON file (or paste cells straight from a spreadsheet), and it works out which column is the labels and which are the numbers. Then copy the HTML or save the SVG. It even reads units from your columns, so Distance (km) gets " km" on every value. Nothing is uploaded; files stay in your browser.

3. A scatter plot that does a bit of statistics. Turn on trend and you get a least-squares line with Pearson's r per group. I'm a data scientist by trade, and I wanted that to be one attribute.

How it's built

Each chart is a pure function: options in, SVG string out. That means the same code draws the live chart in the browser and the static SVG in Node:

import { toSVG } from 'bezel-charts';
import { writeFileSync } from 'node:fs';

writeFileSync('downloads.svg', toSVG('bars', { values: [120, 340, 410], labels: 'Jan,Feb,Mar' }));
Enter fullscreen mode Exit fullscreen mode

The custom element on top handles sizing (it fills its container and redraws on resize), theming, tooltips and accessibility: every chart labels itself for screen readers and respects reduced motion. The whole thing is about 12 kB gzipped, with a size budget, unit tests and a browser test that clicks through every Studio control in CI.

What's next

A Python companion package, so the same charts come straight out of a pandas DataFrame in a notebook.

If you try it, I'd love to hear which chart you reach for first, and what's missing.

Studio: https://shazmoghaddam.github.io/bezel-charts/site/
GitHub: https://github.com/ShazMoghaddam/bezel-charts
Website: https://shazmoghaddam.github.io
LinkedIn: https://linkedin.com/in/shazmoghaddam

Top comments (0)