Chart.js 없이 마크다운에 차트 포함: SVG, 데이터 URI 및 실제 작동 방식

작성자

카테고리:

← 피드로
DEV Community · FSCSS · 2026-08-24 개발(SW)

Markdown is great until you want a real chart in a README or docs site. Most people reach for a screenshot, a hosted PNG, or a heavy client library. ProvChart takes another path: POST /api/v1/generate-svg returns a self-contained SVG (and optional data URI) from your data—no js on the page, no image CDN required.

This article covers what different Markdown platforms allow, practical embed patterns, and when pure SVG is the better default.

The idea

  1. Send series data to ProvChart’s SVG endpoint.
  2. Get back:
    • svg — full <svg xmlns="...">...</svg> string
    • dataUridata:image/svg+xml;base64,...
  3. Embed with whatever your platform supports.

Platform reality: not every Markdown engine is equal

Approach GitHub README Many static docs Personal / controlled MD Notes Data URI ![](data:image/svg+xml;...) Often fragile Sometimes OK Often OK Long base64 can break or get sanitized <img src="data:..."> Limited Varies Often OK Same length / sanitize issues File ![](./chart.svg) ✅ Reliable ✅ Reliable ✅ Best default Commit the SVG; no key in the repo Inline <svg> ❌ Usually stripped Sometimes ✅ If HTML allowed Great for MDX / some SSGs Raster PNG/WebP ✅ ✅ ✅ Use only if the host blocks SVG

Takeaway: Prefer a committed .svg file for GitHub and public docs. Use data URIs for quick demos. Use inline SVG only where the engine allows raw HTML (MDX, some wikis, your own site).

Pattern 1 — Generate SVG (API)

curl -s -X POST "https://provchart-api.devtem.org/api/v1/generate-svg" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{
    "type": "line",
    "series": [
      { "name": "Stars", "color": "#8b7bff", "points": [12, 18, 25, 40, 55] }
    ],
    "axisX": ["Jan", "Feb", "Mar", "Apr", "May"],
    "width": 640,
    "height": 280
  }'

Enter fullscreen mode Exit fullscreen mode

Response shape:

{
  "success": true,
  "svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" ...>...</svg>",
  "dataUri": "data:image/svg+xml;base64,..."
}

Enter fullscreen mode Exit fullscreen mode

Keep the key in CI secrets.

Pattern 2 — Embed options

A. Image from file (recommended for README)

![Stars over time](./docs/charts/stars.svg)

Enter fullscreen mode Exit fullscreen mode

Save the svg field from the API into that path and commit it.

B. Data URI (quick, not always portable)

![Stars over time](data:image/svg+xml;base64,AAAA...)

Enter fullscreen mode Exit fullscreen mode

If the preview is blank, the host likely truncated or blocked the URI—switch to a file.

C. Inline SVG (when HTML is allowed)

<!-- MDX / some static generators -->
<div>
  <!-- paste the svg string from the API -->
</div>

Enter fullscreen mode Exit fullscreen mode

GitHub README will generally not render arbitrary inline SVG.

D. Raster only if you must

If a platform blocks SVG entirely, convert once in your pipeline (e.g. local tool) and commit PNG. That’s a fallback—not the default for your docs site, where SVG is usually better.

Advantages of the SVG path

  1. No chart runtime in the doc UI — readers don’t download Chart.js to see a trend.
  2. No third-party image host — nothing uploaded to a random CDN for a badge.
  3. Sharp at any zoom — useful for docs and retina displays.
  4. Same data model as HTML chartstype, series, axisX match ProvChart’s generate API.
  5. CI-friendly — regenerate docs/charts/*.svg when metrics change; commit the artifact.
  6. Fits the “pipeline” story — compile data → paint geometry; for Markdown the paint target is SVG instead of CSS-in-page.

When pure SVG is the better choice

  • Personal knowledge bases, Notion-export-style vaults, and static doc sites you control
  • GitHub/GitLab asset charts (versioned next to the repo)
  • Design systems / architecture READMEs that should stay dependency-light
  • Agent or cron jobs that refresh charts without opening a browser

Use HTML + CSS (/api/v1/generate) when the chart lives inside a web app where theme tokens and layout already use CSS.

Minimal Node helper (write a file)

import fs from "node:fs";

const res = await fetch("https://provchart-api.devtem.org/api/v1/generate-svg", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-Key": process.env.PROVCHART_API_KEY,
  },
  body: JSON.stringify({
    type: "area",
    series: [{ name: "Views", color: "#4fd8c4", points: [10, 25, 40, 55, 48] }],
    axisX: ["Mon", "Tue", "Wed", "Thu", "Fri"],
    width: 640,
    height: 240,
  }),
});

const data = await res.json();
if (!data.success) throw new Error(data.error);
fs.writeFileSync("docs/charts/views.svg", data.svg);

Enter fullscreen mode Exit fullscreen mode

Point Markdown at ./docs/charts/views.svg.

Troubleshooting

Symptom Likely cause Fix Broken image in README Data URI too long / blocked Commit .svg + relative path 401 Bad or revoked key New key in Dashboard → Developer API 429 Monthly limit Upgrade plan or wait for reset Empty graphic Bad payload Check series[].points and axisX

Links

Markdown support for data: URIs is inconsistent. For public README and most docs, generate SVG – save file – ![](./chart.svg). Use data URIs for experiments; use inline SVG only where your engine allows HTML. That’s how you get charts in docs.

원문에서 계속 ↗