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>


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

Each line represents a day, with steps measured at hourly intervals.

The code for this example uses JSX to show how the component can be used in a React-like environment. The key 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:

Older post:

Known Pleasures: SVG line art

Published on


Signup to my newsletter

Join the dozens (dozens!) of people who get my writing delivered directly to their inbox. You'll also hear news about my miscellaneous other projects, some of which never get mentioned on this site.