Skip to content
Back to skills

Chart Dashboard

ASecurity

Build a self-contained HTML dashboard, data-story report, slide deck, printable one-pager, email-safe chart snapshot, or Teams post from supplied information (metrics, tables, notes, pasted data, a topic), rendered with the bundled zero-dependency charts-lib SVG chart library. Use whenever the user asks for a dashboard, analytics page, KPI/bento view, illustrated report, a presentation, slides or a deck, a one-page handout or brief to print, charts to paste into an email (Outlook, Gmail, a we...

  • 2 stars
  • 0 votes
  • 1 copy
  • 5 views
  • Added October 18, 2026
datagobashnodeawsapi

Works with

  • claude code
  • cli
  • api

Security analysis

A100/100

Pro scans all 18 files and shows the line behind each finding

Scanned October 18, 2026

npx -y skills add raghuramsirigiri/raghuram-skills --skill chart-dashboard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Chart Dashboard?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Chart Dashboard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/raghuramsirigiri-chart-dashboard/badge)](https://www.skillsdirectory.com/skills/raghuramsirigiri-chart-dashboard)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: chart-dashboard
description: Build a self-contained HTML dashboard, data-story report, slide deck, printable one-pager, email-safe chart snapshot, or Teams post from supplied information (metrics, tables, notes, pasted data, a topic), rendered with the bundled zero-dependency charts-lib SVG chart library. Use whenever the user asks for a dashboard, analytics page, KPI/bento view, illustrated report, a presentation, slides or a deck, a one-page handout or brief to print, charts to paste into an email (Outlook, Gmail, a weekly update), or an insights post to share in a Microsoft Teams chat or channel, built from data they provide or describe.
---

# Chart dashboard

Turn whatever information the user gives — a table, pasted numbers, a set of
metrics, notes, or just a topic and some facts — into a single self-contained
HTML page of SVG charts rendered with `charts-lib`: a dashboard, a report, a
slide deck, a one-pager that prints on a single sheet, an email snapshot
whose charts survive being pasted into Outlook or Gmail, or a Teams post that
pastes into a chat or channel as rich text with its charts.

`<skill-dir>` below is the directory holding this file
(`${CLAUDE_SKILL_DIR}` where the agent expands it). Resolve `templates/`,
`references/`, `scripts/` and `assets/` against it, never against the working
directory or a hard-coded home path.

This file is the route; the detail lives in `references/`, and each step says
which file to read and when. Read a reference when its step comes up — not all
of them up front, and not from memory of an earlier page.

## Rules that hold on every page

These apply for the whole build, including after a long conversation.

1. **Never invent numbers that read as real measurements.** A topic with no data
   gets figures labelled illustrative *on the page*. A missing value is a gap
   (`null`), not a zero, drawn with `type: 'line'` so the spline doesn't bridge
   it — a zero draws a collapse that never happened. An interpolated or modelled
   value never joins a measured trend as another point, however it is dashed or
   footnoted: readers remember the shape, not the caveat. Give estimates their
   own panel or leave the hole visible. Numbers carried forward from an older page
   are labelled as such; nudging them to look current is fabrication even though
   each figure came from somewhere real.
2. **One standalone file.** No CDN, no `<script src>`/`<link href>` to anything,
   no webfont, images only as `data:` URIs. `scripts/finalize.js` inlines the
   library and its exit code is the gate (step 8).
3. **`theme.js` loads before `charts.js`.** Leave the template's placeholder tags
   in their order; the inliner preserves it.
4. **The input contract decides the chart.** A line needs an ordered x — dates,
   numbers, or a complete rising run like `'Jan'…'Dec'`, `'Q1'…'Q4'`,
   `'Week 1'…'Week 12'`; named categories (regions, browsers, departments)
   render an error panel, so use `Charts.column`. Donut and pie options
   (`centerText`, `valueSuffix`, `variableRadius`, `startAngle`/`endAngle`,
   `showPercentages`) live under `plotOptions.pie`, not at the top level.
5. **One finding per panel, and the count follows the findings** — no padding a
   grid, no compressing unrelated series onto shared axes.
6. **The finding goes in the title, units and scope in the subtitle** — and the
   title's arithmetic is checked against the numbers before it is written. A
   chart that contradicts its own title is worse than one with a dull title.
7. **A wired control or no control.** A filter re-filters the data, redraws
   every dependent panel and KPI, and recomputes any title that states a finding.
8. **One design system; only the colours change.** No second card style, no
   home-made KPI strip, no banners, emoji or "key insight" strips, legends where
   charts-lib puts them.

Rules 5–8 in full, with emphasis, legends, data labels and the KPI-tile rules:
`references/design-rules.md`. Read it once per page before writing titles and
configs.

## Workflow

1. **Extract the data.** Pull every number, category, and time series out of the
   user's input into a short plan: for each planned panel note *title, data
   shape, chart type, the data it takes, and how many values run across or down
   it* (categories, points, rows, slices). Note the data shape *before* the
   chart type, and the value count before any layout, because step 4 sizes the
   cell from it. The shape says what one item carries: one number, a number per period,
   several measures, a number plus a note, a trend plus a figure, a flow, or raw
   values. Skip that and every row with several things in it becomes a column
   chart. A pasted table with three or more numeric columns, a note against each
   row, or the words *scorecard*, *QBR*, *P&L*, *KPI review* or *vs target* point
   at `table`, `barInsightTable` and `reportTable` first. If the user gave a
   topic with no numbers, say plainly that figures are illustrative (rule 1).

2. **Pick the format by what the data has to say.** Does the page state a
   conclusion, or let the reader draw their own? Read `references/layout.md`,
   then the one `layout-<format>.md` for the format you pick.

   | Format | When | Template | Read |
   |:--|:--|:--|:--|
   | Dashboard | Monitoring; panels stand alone, no prose. The default for metrics with no argument attached. | `dashboard.html` | `layout-dashboard.md` |
   | Report | An argument with evidence: "write up", "for the board", "retrospective", "analysis", or the user stated the conclusion. | `report.html` | `layout-report.md` |
   | Deck | An argument delivered *by someone*, one claim per slide: presentation, slides, deck, "present this", "walk them through it", a named meeting. | `slides.html` | `layout-deck.md` |
   | One-pager | A report on one printed sheet: "print it", "one page", "a handout", "for the board pack", "pin it up", "a PDF to attach". Columns of prose and figures — a page of charts with no sentences is a dashboard — never a KPI tile row; pack it. | `onepager.html` | `layout-onepager.md` |
   | Email snapshot | 1–3 findings pasted into an email body: "the weekly update", "drop it into an email", Outlook/Gmail, "email-safe". Mail clients delete SVG, strip styles and run no script, so: a 600px inline-styled table; charts freeze to PNG with alt text; **Copy for email** button. | `email.html` | `layout-email.md` |
   | Teams post | 1–3 findings in a Teams chat or channel: "post it in the channel", "share in Teams". Plain semantic HTML, charts frozen to PNG; **Copy as picture** and **Copy as text**. | `teams.html` | `layout-teams.md` |

   When it's ambiguous, ask who reads it, whether you'll be in the room, and
   whether it ends up on paper — nobody presents a bento grid to a board, and
   nobody watches a five-section narrative to see if last night's numbers moved.
   The deck is the one format that assumes a presenter: a page that must stand alone with nobody
   narrating is a report, however much the user said "slides". A one-pager,
   email and Teams post are budgets: past one sheet build a report, past three
   findings build the page they belong in and snapshot its lead finding. A
   request naming both email and Teams gets both blocks — each is wrong for the
   other client.

   **Static unless asked.** Build an *editable* page (charts as JSON, an **Edit
   page** button) only when the user asked; read `references/editable.md` first
   and start from `dashboard-editable.html`, `report-editable.html`,
   `slides-editable.html` or `email-editable.html`. A one-pager and a Teams post
   have no editable form. If they didn't ask, offer it once at handover (Output).

3. **Copy the template** from `<skill-dir>/templates/<name>.html` to
   `./index.html` (or where the user asked). Do **not** copy
   `assets/charts-lib/` beside it: the template's `charts-lib/…` tags are
   placeholders (the email and Teams templates have a fourth, for their freeze
   runtime). Leave them exactly as written; step 8 folds the library in.

4. **Derive the structure from the findings and the charts, not from the
   template.** The dashboard template ships a placeholder two-cell grid on
   purpose. Two passes, in this order:
   - **Size each panel's cell first, from its chart type and its values**,
     before any row exists. Round charts (donut, pie, radar, waffle) want a
     square-ish `w4`. Lines, columns and scatters want `w4`/`w6`, or `w8 h2`
     when they lead, and only a long x-axis earns a one-row `w8`/`w12` strip.
     Horizontal bars take their height from the row count. Tables are wide in
     a flow row. Write the cell into the step-1 plan
     (`layout-dashboard.md` § First, the cell each chart wants).
   - **Then pack those cells into rows**: name the dominant shape of the
     analysis (one trend, a head-to-head, a ranking, a funnel, a distribution,
     parallel equal measures, geography) and whether one panel is genuinely the
     reason the page exists (`layout-dashboard.md` § Then compose the rows). A
     lead gets room by going `h2`, never by stretching across a row. If the
     cells won't pack, change the panel or the chart, not the cell.

   Then check:
   - **A hero must be earned.** `w8 h2` only when one finding dominates.
   - **A wide line + a donut + a small panel** on top is this skill's reflex;
     keep it only if the data put it there.
   - **All lines, columns, bars and donuts?** Go back to the data-shape notes:
     `barInsightTable`, `table`, `reportTable` and `panels` exist for a reason.
   - **A table that reprints a chart is padding.** Add one only for measures no
     panel shows, or rows the reader looks up.
   - **Tables size themselves** — a `<div class="bento flow">` row, never a fixed
     cell or `.h2` (`layout-dashboard.md` § Tables size themselves).
   - **No chart stretched out of shape**: no donut in a `w6`+ one-row card, no
     12-point line or 4-bar list across a `w8`/`w12` strip.

   *One-pager:* write the claims as sentences first, then pick `--cols` and each
   figure's `--fig-h` from the content and do the budget in
   `layout-onepager.md` § The budget. Charts go in the columns; under-filling
   the sheet is how this format fails (1660px of column run is about five
   figures and eight text blocks). *Deck:* lay the spine first — `l-cover`,
   `l-agenda`, an `l-section` per section when there are two or more, an
   `l-statement` last with the recap and the ask — then a layout per claim
   (`layout-deck.md` § Compose the sequence). Spine first because scaffolding
   added at the end gets forgotten — an agenda one run and none the next. The
   template's example slides are
   a catalogue, never a running order.

5. **Choose a chart per panel, then write each config against the API** — never
   guess an option name.
   - `references/chart-selection.md` — start at § First: what is one item of
     this data?, and check § Input contract (rule 4).
   - `references/chart-api.md` — always: factories, shared options, sizing.
   - `references/charts/<type>.md` — only the types in your plan.
   - `references/charts/lifecycle.md` only when the page redraws charts;
     `references/charts/theme-tokens.md` only when you recolour or name a token.
   - `references/narrative.md` before writing titles; `references/controls.md`
     before adding any filter or dropdown; `references/annotation.md` when a
     panel marks an intervention, projection, target or anomaly (actual vs.
     forecast is two series).

   **Read them in one call**, not one file per call — every call re-sends the
   conversation, so ten small reads cost several times one combined read. The
   same goes for steps 2–4: `layout.md`, your `layout-<format>.md`,
   `chart-selection.md` and the template in one command, not four:
   ```bash
   cd <skill-dir>/references && cat chart-api.md charts/line.md charts/table.md narrative.md design-rules.md
   ```
   For one fact about one engine (refusals, self-sizing, grid tracks, minimum
   size) read its entry in `assets/charts-lib/charts.manifest.json` — the same
   index the library carries as `Charts.meta`, with the shared `plotBox` and
   `grid` rules. Don't read
   `assets/charts-lib/charts.js` (14,000 lines) or the inlined `examples/` pages
   to learn an option; search them for one name only when the references are
   silent.

   **Check any claim that does arithmetic** — "more than the next two combined",
   "half of all", "double the nearest" — the shape sounds right while the numbers
   say otherwise, and nobody re-adds the column before presenting. Add up the numbers first; if the shape
   doesn't hold, state the comparison that does.

6. **If the user pointed at a brand** (site, stylesheet, screenshot, hex codes),
   recolour and change nothing else. Read `references/theming.md`, then run
   `node <skill-dir>/scripts/extract-theme.js <their-css-or-html>`, or with only
   one colour `node <skill-dir>/scripts/generate-theme.js '#2323FF'`. Apply its
   `Charts.applyPalette` block once, before the first chart call; fix anything
   it marks FAIL; check the series hue it picked is really the brand's. Keep the
   template's font stack unless the brand face is genuinely loadable.

7. **Verify before reporting done.** Read `references/verify-and-ship.md` and
   follow it. In short: `node <skill-dir>/scripts/finalize.js index.html --stage`
   to put the library beside the page; `node <skill-dir>/scripts/check-page.js
   index.html` and fix what it reports; then in a browser at 1440x900, load
   `charts-lib/audit.js` and run `ChartsAudit.run()` until `ok` is true, and
   `ChartsAudit.tryControl()` on every control; one screenshot at the end. Each
   format adds its own check (deck and one-pager paper checks, the email and
   Teams freeze lint) — they're in that file. Without a browser, the static
   check is the floor; say the layout wasn't checked in one.

8. **Fold the library in and ship one file:**
   `node <skill-dir>/scripts/finalize.js index.html`. It checks, inlines,
   removes the staged copy and re-checks with `--final`; a non-zero exit means
   you are not done. The library is inlined verbatim — never minify or hand-edit
   it. Re-running is a safe no-op. Keep the split form only when the user asked
   for it (`verify-and-ship.md` § Step 8).

## Output

One HTML file, standalone (step 8), written to the working directory or where
the user asked. Surface it however your environment does — attach or render it
(in Claude Code: `SendUserFile` with `display: "render"`), otherwise print the
absolute path. State which figures came from the user's data and which, if
any, were illustrative. Per format, also say:

- **Deck** — Print → Save as PDF gives one slide per page.
- **One-pager** — it prints on exactly one sheet, A4 or US Letter, untouched.
- **Email snapshot** — open it and click **Copy for email**; the paste hasn't
  been tried in their client, so send a test first (`layout-email.md` § Hand it
  over).
- **Teams post** — what **Copy as picture** and **Copy as text** each give, with
  the per-chart copy and PNG files as fallbacks (`layout-teams.md` § Hand it
  over).

On the **first** page in a conversation, if the user didn't ask for an editable
page, end with a one-line offer, such as: *"Want an editable version, so you can
switch chart types and change the text or numbers yourself without rerunning
this?"* Once only, and never for a one-pager. Build it only on a yes.

An editable page ships as **two files**: `<name>.html` (final, no editor, safe
to share) and `<name> (working copy).html` (editable, with a "Working copy"
banner, DRAFT print watermark and "Draft ·" tab title). Hand over both and say
which is which.

## Environment notes

Nothing here requires a specific agent or vendor: it needs file reads from this
directory, writing an HTML file, and Node for `finalize.js` and the checks.
If you are not sure Node is installed, run `sh <skill-dir>/scripts/finalize.sh`
(or `scripts/finalize.ps1` on Windows) with the same arguments: it hands over to
`finalize.js` when Node is there, and otherwise stages, inlines and splits the
page identically but cannot run `check-page.js` — it prints `UNCHECKED`, and
you say the static checks were skipped. Browser preview, the audit, screenshots
and file attachment are used when available and degrade gracefully when not.

Files in this skill

  • SKILL.md16.1 KB
  • assets/audit.js18.8 KB
  • assets/chart-convert.js54.7 KB
  • assets/charts-lib/charts.css1.5 KB
  • assets/charts-lib/charts.manifest.json29.8 KB
  • assets/charts-lib/theme.js27.3 KB
  • assets/email-snapshot.js46.4 KB
  • assets/page-runtime.js32.5 KB
  • references/annotation.md12.7 KB
  • references/chart-api.md13.4 KB
  • references/chart-selection.md35.9 KB
  • references/charts/bar-insight-table.md3.5 KB
  • references/charts/bar-list.md2 KB
  • references/charts/column-bar.md4.7 KB
  • references/charts/donut-pie.md2.7 KB
  • references/charts/dumbbell.md2.7 KB
  • references/charts/geofacet.md3.3 KB
  • references/charts/heatmap.md3.4 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.