DEV Community

Cover image for Pure CSS Charts + Drop-in Interactivity: ProvChart API & Runtime
FSCSS tutorial for ProvChart

Posted on

Pure CSS Charts + Drop-in Interactivity: ProvChart API & Runtime

Most chart libraries tax every page: 40–150 KB of JS, hydration delay, and markup crawlers never see. ProvChart takes another path—data becomes HTML and CSS (custom properties + clip-path). ProvChart Runtime is an optional script that adds tooltips, motion, and legend focus without changing how charts are generated.

This post walks through a minimal setup: generate an area chart from the API, inject it, and let the runtime enhance it.


What you get

Layer Role
ProvChart API POST /api/v1/generate{ html, css } — zero chart-library runtime on the page
ProvChart Runtime Scans [data-provchart], adds hover tooltips, scroll reveal, legend dimming
SVG API (optional) POST /api/v1/generate-svg for README/docs — runtime skips pure SVG by design

Repo / install:

Product: chart.devtem.org


1. Get an API key

  1. Sign in at chart.devtem.org
  2. Open Dashboard → Developer API
  3. Create a key

Signed-up free accounts get a monthly test quota. HTML and SVG generations share the same pool.


2. Minimal page

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>ProvChart + Runtime</title>
  <style>
    body {
      margin: 0;
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #0c0a16;
      font-family: system-ui, sans-serif;
    }
    #chart { width: min(640px, 92vw); }
    .err { color: #ff5e7d; font-size: 14px; padding: 16px; }
  </style>

  <script>
    window.ProvChartRuntimeConfig = {
      animation: true,
      revealOnScroll: true,
      tooltips: true,
      perPointTooltips: true,
      observe: true,
      selector: '[data-provchart]',
      excludeSvg: true,
    };
  </script>
  <script src="https://cdn.jsdelivr.net/npm/provchart-runtime@1.0.0/dist/provchart-runtime.min.js"></script>
</head>
<body>
  <div id="chart"></div>

  <script type="module">
    const API = 'https://provchart-api.devtem.org/api/v1/generate';
    const API_KEY = 'YOUR_API_KEY';

    const payload = {
      type: 'area',
      series: [
        { name: 'Traffic', color: '#4fd8c4', points: [30, 45, 40, 60, 55, 70, 65] },
        { name: 'Signups', color: '#f0a860', points: [8, 12, 11, 18, 16, 22, 20] },
      ],
      axisX: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
    };

    const mount = document.getElementById('chart');

    try {
      const res = await fetch(API, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-API-Key': API_KEY,
        },
        body: JSON.stringify(payload),
      });
      const data = await res.json();
      if (!data.success) throw new Error(data.error || 'Generate failed');

      let style = document.getElementById('provchart-style');
      if (!style) {
        style = document.createElement('style');
        style.id = 'provchart-style';
        document.head.appendChild(style);
      }
      style.textContent = data.css || '';
      mount.innerHTML = data.html || '';

      // Optional: only if your build exposes it
      // window.ProvChartRuntime?.scan?.();
    } catch (err) {
      mount.innerHTML = `<p class="err">${err.message}</p>`;
    }
  </script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Replace YOUR_API_KEY. After load you should see a two-series area chart; hover legend/points if the runtime attached correctly.


3. How the runtime finds charts

Generated roots look like:

<div class="pc-chart-…" data-provchart="area"></div>
Enter fullscreen mode Exit fullscreen mode

The runtime:

  1. Queries [data-provchart]
  2. Skips pure SVG embeds when excludeSvg: true
  3. Uses a MutationObserver so charts injected via fetch still get enhanced
  4. Reads series points from CSS variables like --pc-{id}-s1-p1 for per-point tooltips

You don’t call into ProvChart’s core from the client for paint—the browser already painted CSS.


4. Config worth knowing

window.ProvChartRuntimeConfig = {
  animation: true,
  revealOnScroll: true,
  tooltips: true,
  perPointTooltips: true,
  countUp: true,      // gauge / stat numbers
  observe: true,      // watch DOM for new charts
  excludeSvg: true,   // leave README SVGs alone
};
Enter fullscreen mode Exit fullscreen mode

Define this before the runtime script tag.


5. HTML/CSS vs SVG

Use case Endpoint Runtime
App UI, dashboard, marketing page /api/v1/generate Yes
GitHub README, static docs asset /api/v1/generate-svg No (commit .svg or data URI)

Same payload shape (type, series, axisX); different output.


6. Why this split matters

  • Performance: no Chart.js-sized dependency to parse before first paint
  • SEO: chart structure is in HTML/CSS on first response
  • Progressive enhancement: runtime is optional; charts work without it
  • Docs vs apps: SVG for Markdown hosts; HTML/CSS + runtime for product UI

Links

generate charts as HTML and CSS, ship them with almost no client chart code, and add interactivity only when you want it—with a single script tag

Top comments (0)