Stacked Sparklines web component
Turning an SVG chart into a general purpose web component
Web components are finally viable! Well, I think they've been viable for a long time but I'm only just discovering how fun and useful they can be. I've just published a new one: a stacked sparklines component.
Overview
My recent SVG recreation of the Unknown Pleasures album cover quickly expanded into a resusable JSX component. That worked well for this site, because all my components are rendered to static HTML at build-time. But what about those folks who don't want to add the wieght of React to their projects? This was a perfect excuse to experiment with stripping out all the React from a compoment and turning it into a web component.
The <stacked-sparklines>
component is available on npm (npmjs.com/package/stacked-sparklines) or you can download the source directly from the GitHub repository (github.com/tomhazledine/stacked-sparklines), and the total uncompressed size is 30kb (the lion's share of which is the D3 scale and line functions).
yarn install stacked-sparklines
import 'stacked-sparklines';
<stacked-sparklines data-data="DATA_GOES_HERE"></stacked-sparklines>
Demo Gallery
Click on an example to view the full-size version and see the code used to generate it.
Example 1: Using all the options to generate a pulsar chart
This example recreates the original pulsar chart that inspired the Unknown Pleasures album cover. It makes use of all three text labels: data-label-left
and data-label-right
, as well as the data-caption-html
attribute (an alternative option to a plain-text data-caption
) that allows the inclusion of HTML elements in the caption.
Because the data is so dense (~80 lines stacked together), the data-scale
and data-row-height
attributes have been manualy set.
Full details on the available options are available in the Stacked Sparklines README on GitHub.
Note: The web component expects the data to be passed as a string. This is because web components can only accept strings as attributes. To pass an array of data, you'll need to stringify it first and inject it using whatever templating language you're using.
const DATA_STRING = JSON.stringify(pulsarData);
<stacked-sparklines
class="kp-pulsar-wc"
data-data="{{DATA_STRING}}"
data-row-height="0.2"
data-size="600"
data-baseline="0"
data-scale="4"
data-margin="0.4"
data-label-left="CP 1919"
data-label-right="318 MHz"
data-caption-html="<strong>Fig #1:</strong> Extract from <em>Radio Observations of the Pulse Profiles and Dispersion Measures of Twelve Pulsars</em> by Harold D. Carft, Jr."
></stacked-sparklines>
Example 2: My daily steps for 2023
The code for this example uses
JSX
to show how the component can be used in a React-like environment. Thekey
attribute is React-specific, and the self-closing tag is JSX-specific. The component itself is a standard web component and can be used in any environment that supports them.
import stepsData from "./data/2023-steps.js";
const monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
];
export default () => (
<div className="yearly-steps">
{stepsData.map((month, i) => (
<stacked-sparklines
key={`month_${i}`}
class={`yearly-steps__${monthNames[i].toLowerCase()}`}
data-data={JSON.stringify(month)}
data-caption={monthNames[i]}
data-background="#00b7c6"
data-foreground="#fdfdfa"
data-size="300"
data-margin="0.2"
data-scale="1.5"
data-row-height="0.1"
data-baseline="0"
/>
))}
</div>
);
This example renders multiple <stacked-sparklines>
components into a grid, each representing a month of the year. The data is passed as a stringified array, and the data-caption
attribute is used to label each chart with the month name. data-background
and data-foreground
are used to set the colours of the chart. The SVGs rendered by the component are fully styleable with CSS, but these attributes allow for quick and easy customisation.
I'll keep adding to this gallery as-and-when I create new examples. If you have any ideas for cool things to do with this component, let me know over on Mastodon: @thomashazledine@mastodon.social!
Related posts
If you enjoyed this article, RoboTom 2000™️ (an LLM-powered bot) thinks you might be interested in these related posts:
Known Pleasures: SVG line art
Recreating classic Joy Division album-art with SVG
Similarity score: 75% match . RoboTom says:
Line graphs with React and D3.js
Generating a dynamic SVG visualisation of audio frequency data.
Similarity score: 73% match . RoboTom says: