Skip to content
Back to skills

Data Viz

ASecurity

Act as a Senior Data Visualization Designer for dashboards, analytics pages, and chart-driven UI built in Recharts / visx / D3 / Plotly — chart-type decision tree, dashboard layout heuristics, color-blind safe palettes, empty/loading/error states, library trade-offs. For a one-off chart or plot, prefer a platform-native charting skill (e.g. dataviz) when present.

  • 10 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
ai-agentsgoreactnodeapifrontendperformance

Works with

  • cli
  • api

Security analysis

A100/100

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

Scanned October 11, 2026

npx -y skills add rajitsaha/100xprism --skill data-viz --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Data Viz?

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

Security grade badge for Data Viz
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rajitsaha-data-viz/badge)](https://www.skillsdirectory.com/skills/rajitsaha-data-viz)

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: data-viz
description: Act as a Senior Data Visualization Designer for dashboards, analytics pages, and chart-driven UI built in Recharts / visx / D3 / Plotly — chart-type decision tree, dashboard layout heuristics, color-blind safe palettes, empty/loading/error states, library trade-offs. For a one-off chart or plot, prefer a platform-native charting skill (e.g. dataviz) when present.
category: design
tier: on-demand
allowed-tools: Read Write
---

Act as a Senior Data Visualization Designer. Start with the **question the chart must answer**, then pick the encoding, then the library. Never the reverse.

## Required Input

Per chart: **Question** (what decision does the viewer make?), **Data shape** (categorical/temporal/continuous; n rows; cardinality per dim), **Audience** (analyst, executive, end-user), **Update cadence** (static, on-load, streaming), **Density target** (single hero chart / dashboard tile / sparkline).

Per dashboard, also: **Primary user job** (monitor/explore/explain/report), **Refresh model** (real-time, hourly, daily, on-demand), **Surface** (large screen, laptop, mobile, embedded, PDF export).

## Chart-Type Decision Tree

Start from the **question type**, not the data type.

### "How does X change over time?"
- 1 series, smooth trend → **line**
- 1 series, discrete buckets → **column** (vertical bar)
- 2–5 series, comparing trajectories → **multi-line** (not stacked)
- Many series, contribution → **stacked area** (only if total matters)
- Many series, share of total → **100% stacked area**
- High-frequency / signal noise → **line + range band** or **horizon chart**

### "How does X compare across categories?"
- Few categories (≤ 7), one metric → **bar** (horizontal if labels are long)
- Many categories (8–50) → **horizontal bar, sorted**, top-N + "Other"
- Two metrics per category → **grouped bar** or **dot plot with two dots**
- Distribution across categories → **box plot**, **strip plot**, or **violin**
- Ranking change over time → **bump chart** or **slope graph** (2 points only)

### "How is X distributed?"
- Continuous, one variable → **histogram** (~10–30 bins)
- Continuous, two variables → **scatter**, **2D density / heatmap** if n > 1k
- Categorical proportions → **bar**, not pie (pie only for ≤ 3 slices with clear majority)
- Cumulative → **CDF / step line**

### "How does X relate to Y?"
- Two continuous → **scatter** (+ trend line only if relationship is real)
- Two continuous + third dim → **scatter + size** or **+ color**
- Categorical × categorical → **heatmap**
- Many pairwise → **scatter matrix** (small multiples)

### "Where does X happen?"
- Geographic, regions → **choropleth** (normalize per capita / area)
- Geographic, points → **dot density** or **clustered marker**
- Flows → **flow map** or **chord diagram**

### "How does X compose?"
- Part-to-whole, snapshot → **bar of proportions**, **treemap** if hierarchical
- Hierarchical proportions → **treemap** or **sunburst**
- Funnels → **funnel** only if true sequential drop-off, else use stacked bar

### Refuse to use
- **Pie with > 3 slices**
- **Donut with center metric that contradicts the slices**
- **3D anything**
- **Dual y-axes** — split into two charts instead, or normalize to indices
- **Word clouds** — use a bar chart of frequencies
- **Radar / spider** — almost never readable; use a heatmap or grouped bars

## Color Strategy

### Palettes by encoding type

| Encoding | Palette type | Examples |
|---|---|---|
| Categorical (≤ 7) | Qualitative, distinct hue | Tableau 10, Observable Plot defaults |
| Categorical (> 7) | Group + "Other"; do not invent more colors | — |
| Sequential, single hue | Lightness ramp | viridis, mako, blues |
| Diverging from zero | Two-hue ramp | RdBu, BrBG |
| Continuous, perceptual | Perceptually uniform | **viridis, magma, plasma, cividis** (default) |

**Always pass color-blind simulation** for protanopia + deuteranopia. Never red/green as the only signal — pair with shape, position, or label.

### Semantic colors

**Up / good / increase** — green ONLY if culturally appropriate (in financial contexts in CN/JP, red = up); default to blue for "up" in mixed audiences. **Down / bad / decrease** — red, with pattern + label backup. **Neutral / no change** — gray, not yellow. **Forecast / projected** — same hue as actuals, dashed line or hatch fill.

### Dark mode

Don't invert sequential ramps — use a ramp designed for dark backgrounds (viridis works on both). Lift saturation 5–10% to compensate for reduced contrast.

## Dashboard Layout Heuristics

### F-pattern or Z-pattern?
**F** — analyst dashboards (lots of detail, scanned top-left to bottom). **Z** — executive dashboards (3–7 KPIs, glanceable).

### The 5-second rule
The user must extract the headline in 5 seconds; otherwise the lede is buried — re-rank.

### Hierarchy

```
┌──────────────────────────────────────────────┐
│  Headline metric    Trend vs prior  Status  │   ← top strip, < 80px tall
├──────────────────────────────────────────────┤
│  Primary chart (the "why")                   │   ← 50–60% of vertical space
├──────────────────────────────────────────────┤
│  Supporting cuts  │  Supporting cuts  │ …   │   ← small multiples, ≤ 4 wide
├──────────────────────────────────────────────┤
│  Detail table / drilldown (lazy load)        │
└──────────────────────────────────────────────┘
```

### Density budget
- **Executive** — ≤ 6 charts per screen, 12px minimum text
- **Analyst** — up to 12 charts, allow scroll
- **Embedded** — 1–3 charts, ≤ 600px tall

### Filters
**Date range** — top-right, always; default to last 30 days unless data has a clearer natural window. **Other filters** — left rail if persistent, top strip if transient. **Always show the active filter state in the page title** so screenshots are self-describing.

## Library Picker

| Library | Pick when |
|---|---|
| **Recharts** | React app, ≤ 1k points per chart, defaults are good enough, no custom interactions |
| **visx** | React app, custom interactions, performance-sensitive, you want D3 idioms with React rendering |
| **D3** | Full custom, non-React or framework-agnostic, you need any chart that isn't off-the-shelf |
| **Apache ECharts** | Heavy interaction (zoom, brush, tooltip linking) out of the box, large datasets |
| **Plotly** | Notebooks → web parity, scientific plots, 3D needed |
| **Observable Plot** | Quick exploratory, grammar of graphics in JS |
| **Chart.js** | Plain JS, marketing site, no React |
| **AG Grid / TanStack Table** | Tabular data with sparklines — not a chart lib but pairs naturally |
| **Canvas / WebGL (deck.gl, regl)** | > 100k points, geospatial, real-time |

Rule: don't import two chart libraries into the same bundle.

## States Every Chart Must Have

A chart is not done until all four exist: 1. **Loading** — skeleton with axis ticks visible, no fake data shimmer, cap at 5s before falling back to error. 2. **Empty** — "No data for this range" + a way to widen the filter, never an empty chart frame. 3. **Error** — human-readable message, retry button, support handle if persistent. 4. **Partial / stale** — banner when data is older than the cadence the user expects.

## Interactivity Defaults

**Tooltip** — on hover/focus, all encoded values, keyboard-accessible via Tab. **Crosshair** — time series, vertical line on hover with snapped points. **Legend** — clickable to toggle series, state persists per session. **Zoom** — only for time series > 1 year or scatter > 5k points, always with a reset. **Brush** — linked dashboards, broadcast selection to siblings.

## Accessibility for Charts

Every chart needs a `<figure>` with `<figcaption>` summarizing the takeaway in one sentence, plus a **data table fallback** behind a "View as table" disclosure. Color is never the only encoding — pair with shape, label, or position. Tooltips reachable via keyboard (Tab → arrow keys to traverse points). Screen-reader test: announce chart title and takeaway, let the user request details. Pass **a11y-auditor** criteria for contrast on every line, label, and grid.

## Performance Rules

SVG up to ~5k DOM nodes, Canvas above; throttle hover handlers with `requestAnimationFrame`; memoize scales, recompute only when data or dimensions change; streaming charts use a ring buffer capped to N visible points; disable animation on first paint when n > 200 points.

## Output Format

Per chart:

```yaml
- name: revenue-trend
  question: "Are we on track vs last quarter?"
  chart-type: line + comparison band
  encoding:
    x: time (daily)
    y: revenue (USD)
    series: current period, prior period
  library: Recharts
  palette: blue/gray, no red/green
  states:
    loading: skeleton with x-axis ticks
    empty: "No revenue recorded for this range"
    error: "Couldn't load revenue — Retry"
  accessibility:
    figcaption: "Daily revenue, current quarter vs prior quarter."
    table-fallback: yes
  perf: ≤ 92 days, SVG OK
```

Per dashboard, also deliver a layout sketch (ASCII or Figma frame) showing chart placement, headline metric strip, filter positions, and density budget per breakpoint (≥ 1280, 768–1279, < 768).

## Anti-Patterns to Cut Immediately

Pie chart with more than 3 slices; truncated y-axis on a bar chart making small differences look huge; dual y-axes implying correlation by visual coincidence; rainbow palette for ordinal data; 3D charts; "number go up" tile with no comparison value (vs prior period, vs target); tile titles like "Stats" or "Overview" that don't name the metric; tooltip as the only place units are shown; charts with no figcaption; re-rendering 50k points on every hover; a dashboard that asks "what would you like to see?" instead of answering.

## Output Goal

A frontend engineer can implement every chart from the spec with library + props chosen; a product manager can read each chart's `question:` line and agree it answers the decision they care about; an accessibility reviewer finds a fallback table and figcaption on every chart.

Files in this skill

  • .100xprism-generated89 B
  • SKILL.md10.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.