Back
Standalone v1.0.3 Star on GitHub

vois-dataviz

Picks the right chart, then builds or reviews dashboards you can trust.

Vois Dataviz decides how data should look on a screen: which chart, which colors, how filters and date ranges behave, and what the empty, loading and error states say. It builds new charts and dashboards from a decision tree and reviews existing ones against 114 rules, each with a do and a don't. Everything is machine-readable, so an agent can check its own work before anyone else has to.

  • Screen, ticket, or data question

    A dashboard brief, a chart you need to choose a type for, or a plain question like what the viewer needs to see. Say who reads it: an executive, an analyst, or someone watching live state.

  • Existing chart or dashboard

    A screenshot, a Figma frame, or chart code to review and improve. The skill lists what it could not check from the format you gave it.

  • Chart spec and form choice

    For each visualization: the question it answers, the form the decision tree lands on with alternatives considered, the color job, and a spec checked against the rules before any code is written.

  • Dashboard structure and states

    A dashboard template, one filter row with date presets and a named comparison, and the loading, four kinds of empty, error, and partial states for every card.

  • Review findings

    Failures and warnings in a fixed JSON shape, ordered by what excludes or misleads people first, each with the rule, what is wrong on this screen, and the concrete fix.

Load the vois-dataviz skill. I'm working on [a dashboard / a chart / a KPI row]. The audience is [executive / analyst / operator]. Pick the right forms and build it, or review this existing screen: [attach screenshot or code].

Skills that call into or pair with this one. Click a node to open it. Expand the reference files node to browse them on GitHub.

Get this skill

Download the SKILL.md file and install it in Claude or Cursor.

  1. Download the SKILL.md file using the button above.
  2. Open claude.ai and go to Settings.
  3. Select Skills from the sidebar.
  4. Click Add skill and upload the SKILL.md file.
  5. Give the skill a name and save. Claude loads it automatically when relevant.

Skills installed in Claude persist across conversations. Claude reads the skill when the trigger conditions match your message.

Vois Data Visualization Skill

A chart is read by people and built by you. This skill makes the result right by construction: it picks the form from the viewer’s job, assigns color by the job it does, builds the states most dashboards forget, and gives you something to check against.

It answers “what should this data look like, and is it honest and usable?” Page structure is vois-patterns, container components are vois-components, token values and motion are vois-tokens, and every word on the screen is righter.

Two modes. BUILD: you’re creating a visualization or dashboard. REVIEW: you’re evaluating or improving an existing one. The steps differ; the rules are the same.


BUILD: the order of work

  1. Write the spec. One per visualization, following data/chart-spec.schema.json: the question it answers, the audience, the job, the form. If you can’t write the question, the chart shouldn’t exist [DV-PURPOSE-001].
  2. Walk the decision tree (below, in full in references/decision-tree.md). Land on a result node and a form id from data/chart-catalog.json.
  3. Check the spec: node scripts/check-spec.mjs spec.json. Fix every FAIL before you write code. --tree <job> lists the forms a job can reach.
  4. Record the choice. If a vois_record_component_choice tool is available, call it with job (the viewer’s question), componentName (such as ChartContainer + LineChart), alternativesConsidered (other forms from the tree) and reasoning (the tree result id, e.g. CHART-R-LINE-MULTI). If nothing in the tree fits and vois_report_pattern_gap is available, call it with the closest result as attemptedFallback; otherwise say so in your answer.
  5. Get tokens. Get the chart roles in references/implementation.md from the workspace tokens (vois_get_tokens if available). Never write a color value, and never invent a missing role: report the gap.
  6. Build from one typed config [DV-SUSTAIN-001], following references/implementation.md. Build the dashboard from DASH-* templates and pieces (references/dashboard-patterns.md).
  7. Build the states: skeleton, four kinds of empty, error, refetch, partial [DV-STATE-001] through [DV-STATE-007]. Copy goes through righter.
  8. Check the code: node scripts/detect.mjs <files>. Then look at it at 320, 640 and 1280px, light and dark, with a keyboard.
  9. Record usage (optional): if vois_record_rule_usage is available, call it with the DV-* ids you applied (violated or ambiguous where they weren’t met). These calls are telemetry; if one is missing or errors, carry on.

REVIEW: the order of work

Follow references/review-protocol.md: inventory, infer each job, check the form against the tree, run the mechanical checks, run the judgment checks in triage order, check the page as a whole, propose the upgrade, report in data/review-output.schema.json. data/review-checklist.json has a symptom to fix playbook for the 20 most common problems. Don’t flag what passes, and list what you couldn’t check.


Decision tree, at a glance

Start with the viewer’s job, not the chart. Full tree with every branch: references/decision-tree.md and data/decision-tree.json.

The viewer needs to…Default formBranch
Read one numberStat tile with delta, sparkline if the trend matters. Meter if it’s a ratio against a limitCHART-Q-SINGLE
See change over timeLine (continuous), column (12 or fewer discrete periods), area (volume, zero baseline), step (holds between events)CHART-Q-TIME
Compare or rank categoriesSorted horizontal bar. Top 10 plus Other past about 12CHART-Q-COMPARE
See parts of a wholeDonut for 3 to 6 parts, stacked bar to compare across groups, sorted bar past 6CHART-Q-PART
See how two measures relateScatter, heatmap for two categoriesCHART-Q-RELATE
See spread or outliersHistogram for general audiences; box plot only for analystsCHART-Q-DIST
See stages or flowsFunnel as aligned bars with step conversion; Sankey for 15 or fewer nodesCHART-Q-FLOW
See whereChoropleth for rates only; ranked bar for countsCHART-Q-GEO
Look up exact valuesTable, with inline sparklines or barsCHART-R-TABLE

Then run the gates on the result: audience, simpler form, series count, scale, table twin, volume.

Quick reference

SituationUseNot
A single current numberStat tile with a named deltaA one-bar chart, a 2-slice pie [DV-FORM-003]
2 to 4 series, same unitMulti-line with a legend and end labelsDual axis [DV-HONEST-002]
Different units or scalesSmall multiples with a shared crosshairTwo y-axes on one plot
6 or more series and one is the storyEmphasis: one accent, rest gray [DV-COLOR-009]Eight hues competing
More than 8 groupsTop 8 plus Other, table for the tail [DV-FILTER-007]A 16-hue stack with ‘+11 more’
Part-to-whole, 3 to 6 partsDonut with the total in the holeA 9-slice pie [DV-FORM-004]
BarsZero baseline, one color for one series [DV-HONEST-001] [DV-COLOR-007]A truncated axis, a hue per bar
Line that curvesMonotone or linear; step for state [DV-HONEST-005]Natural spline overshoot
Current period still openHatched bar or dashed line, labeled [DV-HONEST-004]A cliff that is just an unfinished day
Delta on a KPIArrow, sign, number, named baseline [DV-CONTEXT-002]A bare percent, color-only meaning
Value is zero because nothing was collectedA ‘collecting data’ state [DV-STATE-002]A flat zero line [DV-HONEST-008]
Trend inside a table rowAxisless muted sparkline [DV-FORM-008]A mini chart with axes and a legend
Date rangePresets first, comparison beside, timezone shown [DV-FILTER-002]A calendar only
Every chart needs reading without sight or colorText alternative, accessibilityLayer, Chart or Table toggle [DV-A11Y-003] [DV-A11Y-004]A tooltip as the only readout [DV-A11Y-006]

Which dashboard?

Walk DASH-Q-TYPE in references/dashboard-patterns.md.

ReaderTemplate
A leader scanning in 30 secondsDASH-EXEC
An operator watching live stateDASH-MONITOR
An analyst asking new questionsDASH-EXPLORER
A weekly or monthly narrative that gets exportedDASH-REPORT
Users assembling their own widgetsDASH-BUILDER
Someone who drilled into one metricDASH-METRIC-DETAIL

Reusable pieces: DASH-KPI-TILE, DASH-CHART-CARD, DASH-FILTER-BAR, DASH-DATE-RANGE, DASH-STATE-MATRIX, DASH-TABLE-SPARK, DASH-DRILLDOWN, DASH-TOOLTIP.


The 14 principles

Each one has a full do and don’t list in references/principles.md. The headline:

PrincipleOne lineDoDon’t
DV-PURPOSE Question and audienceOne question, one readerWrite the question before the formAdd a chart because the data exists
DV-FORM Simplest formThe viewer’s job picks the formWalk the tree; stat tile for one numberPie to compare close values; 22-type pickers
DV-HONEST TruthfulOne honest axis, marked partialsZero baseline for bars; hatch the open periodDual axes, spline overshoot, flat zero for missing
DV-CLARITY Data, not inkRemove what doesn’t help readingLabel the end and the extremeA number on every point; truncated axis titles
DV-COLOR Color by jobIdentity, magnitude, polarity, statusTokens in fixed order; entity keeps its colorHex values; a hue per bar; a 9th hue
DV-CONSIST ConsistentSame metric, same look everywhereOne formatter and one period per filter$1.2M here, 1,200,000 there
DV-CONTEXT FramedCompare, scope, dateDelta against a named period; labeled targetsA bare number; a hidden chart filter
DV-A11Y AccessibleWorks without color, mouse, sight, motionText alternative, table twin, 3:1 marksTooltip as the only readout; red and green alone
DV-INTERACT InteractiveCrosshair, shared tooltip, legend toggleVisible click affordance, one card menuNeeding to hit a 2px line
DV-FILTER One sliceOne row of filters above the cardsPresets, comparison, URL statePer-card pickers; skeleton flash on refetch
DV-STATE Every stateLoading, empty (4 kinds), error, staleSkeleton in final geometryFull-page spinner; one generic ‘No data’
DV-LAYOUT HierarchyFilters, hero KPIs, trend, breakdowns, tableOne card anatomyA grid of equal-weight cards
DV-SUSTAIN Built for live dataTyped config, ugly cases handledOne config feeds chart, table and exportHardcoded demo data
DV-IMPL Vois stackPrimitives, tokens, accessibility defaultsshadcn Chart with a typed configInline colors, fixed pixel widths

Non-negotiables

These are required rules a reviewer will FAIL. Everything else is a WARN with a fix.

  • One y-axis per chart [DV-HONEST-002]; bars and areas start at zero [DV-HONEST-001].
  • Categorical hues in fixed order, never cycled, eight at most [DV-COLOR-003]; chart colors are tokens [DV-COLOR-001]; an entity keeps its color [DV-COLOR-004].
  • Color is never the only signal [DV-A11Y-001]; marks 3:1 and text 4.5:1 [DV-A11Y-002].
  • Every chart has a text alternative and a table view [DV-A11Y-003] [DV-A11Y-004]; tooltips enhance and never gate [DV-A11Y-006].
  • Partial periods, forecasts and missing data look different from the real thing [DV-HONEST-004] [DV-HONEST-008].
  • Every KPI has a delta against a named period [DV-CONTEXT-002].
  • One filter row above what it scopes, and every card obeys it [DV-FILTER-001] [DV-FILTER-004].
  • Skeleton in final geometry on first load, held frame on refetch, errors isolated to the card [DV-STATE-001] [DV-FILTER-008] [DV-STATE-003].
  • No hardcoded data in a chart component [DV-SUSTAIN-005].

Taste dials

When the project defines the three taste dials in VOIS.md or DESIGN.md: DENSITY moves the per-view cap from about 6 to 8 up to 10 visualizations and allows analyst forms for analyst audiences; MOTION never exceeds 300ms and always yields to reduced motion [DV-A11Y-008]; VARIANCE can vary card composition but never the form choice or any honesty rule. Dials tune within the rules, never against them.


Reference files

Generated from data/*.json by scripts/build-reference.mjs, so they can’t drift:

FileUse it for
references/principles.mdDo’s and don’ts for each principle, and all 114 rules with do, don’t, check and evidence
references/decision-tree.mdThe full chart-selection tree with a diagram per branch and the gates
references/chart-catalog.md48 forms: when to use, when not, baseline, limits, color job, build hint
references/dashboard-patterns.mdSix page templates and eight reusable pieces
references/evidence.md57 real-product screens from Mobbin: what to adopt, what to avoid

Written by hand:

FileUse it for
references/implementation.mdChart token roles, shadcn Chart and Recharts code, states, table twin, MCP calls
references/review-protocol.mdHow to review and improve existing work, with a worked example
references/sources.mdWhat each source contributed, and what wasn’t read

Structured data (query these instead of scanning prose)

FileKeyed byHolds
data/dataviz-rules.jsonDV-<AREA>-NNN14 principles and 114 rules: severity, enforcement, do, don’t, check, sources, evidence
data/decision-tree.jsonquestion and result node idsThe tree as a graph, job entry points, gates
data/chart-catalog.jsonFORM-*48 forms with fit, audience, baseline, color job, build hint
data/dashboard-patterns.jsonDASH-*Templates and pieces: structure, components, rules, evidence
data/evidence.jsonMOB-NNMobbin observations with lesson and rule ids
data/review-checklist.jsonReview steps, severity map, triage order, fix playbook, the loop checklist
data/chart-spec.schema.jsonThe spec you fill in before coding
data/review-output.schema.jsonThe shape of a review

Source of truth. The JSON is canonical and the generated references restate it. scripts/dataviz.test.mjs fails CI if an ID in prose has no JSON entry or the reverse.

Scripts

ScriptDoes
scripts/check-spec.mjs <spec.json>Checks a chart spec: the 9 spec rules plus form-versus-job reachability in the tree
scripts/check-spec.mjs --tree <job>Lists every form a job can reach
scripts/detect.mjs <files>Finds the 15 auto rules in chart code (13 detectors). Add // dataviz-allow: <detector> for a deliberate exception
scripts/build-reference.mjs [--check]Regenerates, or checks, the generated references
scripts/dataviz.test.mjs58 tests: detectors, spec checker, data integrity

Relationship to other skills

vois-patterns first. It decides that the screen is a dashboard or contains data. Come here for what’s inside it. vois-components (JOB-VISUALIZE-DATA) routes data jobs here, then picks the containers: Card, Tabs, Popover, Calendar, Table, Skeleton. vois-tokens supplies live token values, motion and hit-area rules. This skill adds chart roles on top and cites DS-A11Y-001, DS-A11Y-002, DS-ANIMATION-001 and DS-ANIMATION-004. righter writes every title, subtitle, tooltip label, empty state and error. This skill says what the state is, never the words. metrics-tagging instruments chart interactions (range change, legend toggle, drill-down, export) when asked. design-rationale explains why a form or color choice is right when someone pushes back.

Checklist before handoff

  • Spec written for each visualization and check-spec has no FAIL
  • Form reached through the tree (and vois_record_component_choice called, if available)
  • Colors are chart tokens in fixed order, checked per mode
  • Text alternative, accessibilityLayer, table view, keyboard path
  • Tooltip and crosshair, legend for 2 or more series, drill-down affordance
  • One filter row with date presets and a named comparison
  • Skeleton, four empty cases, error, refetch and partial states built
  • detect.mjs run and clean, or each finding justified
  • Checked at 320, 640 and 1280px, light and dark
  • vois_record_rule_usage called, if available