Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Generate Chart Images From Data

ASecurity

Generate publication-quality chart images from data. Supports line, bar, area, point, histogram, candlestick, pie/donut, heatmap, multi-series, and stacked charts. Use when visualizing data, creating graphs, plotting time series, showing distributions, or generating chart images…

19 stars
0 votes
0 copies
1 views
Added 9/19/2026
ai-agentsgobashnodedockerapi

Works with

api

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add rondoflow/rondoflow --skill generate-chart-images-from-data --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Generate Chart Images From Data?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Generate Chart Images From Data
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rondoflow-generate-chart-images-from-data/badge)](https://www.skillsdirectory.com/skills/rondoflow-generate-chart-images-from-data)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: generate-chart-images-from-data
description: "Generate publication-quality chart images from data. Supports line, bar, area, point, histogram, candlestick, pie/donut, heatmap, multi-series, and stacked charts. Use when visualizing data, creating graphs, plotting time series, showing distributions, or generating chart images…"
category: "Media"
author: community
version: "2.6.35"
icon: image
---

# Chart Image Generator

Generate PNG chart images from data using Vega-Lite. Perfect for headless server environments.

## Why This Skill?

**Built for Fly.io / VPS / Docker deployments:**
- ✅ **No native compilation** - Uses Sharp with prebuilt binaries (unlike `canvas` which requires build tools)
- ✅ **No Puppeteer/browser** - Pure Node.js, no Chrome download, no headless browser overhead
- ✅ **Lightweight** - ~15MB total dependencies vs 400MB+ for Puppeteer-based solutions
- ✅ **Fast cold starts** - No browser spinup delay, generates charts in <500ms
- ✅ **Works offline** - No external API calls (unlike QuickChart.io)

## Setup (one-time)

```bash
cd /data/clawd/skills/chart-image/scripts && npm install
```

## Quick Usage

```bash
node /data/clawd/skills/chart-image/scripts/chart.mjs \
  --type line \
  --data '[{"x":"10:00","y":25},{"x":"10:30","y":27},{"x":"11:00","y":31}]' \
  --title "Price Over Time" \
  --output chart.png
```

## Chart Types

### Line Chart (default)
```bash
node chart.mjs --type line --data '[{"x":"A","y":10},{"x":"B","y":15}]' --output line.png
```

### Quantitative X-domain clamp
Useful when you want a fixed numeric or temporal window without editing Vega-Lite by hand:
```bash
node chart.mjs --type line \
  --data '[{"minute":0,"value":12},{"minute":1,"value":18},{"minute":2,"value":14},{"minute":3,"value":20}]' \
  --x-field minute --y-field value --x-type quantitative \
  --x-domain 0,2 --title "First 3 Minutes" \
  --output x-domain.png
```

### Bar Chart
```bash
node chart.mjs --type bar --data '[{"x":"A","y":10},{"x":"B","y":15}]' --output bar.png
```

### Area Chart
```bash
node chart.mjs --type area --data '[{"x":"A","y":10},{"x":"B","y":15}]' --output area.png
```

### Histogram
Use this for numeric distributions instead of pre-binned bar charts:
```bash
node chart.mjs --type histogram \
  --data '[{"value":12},{"value":18},{"value":19},{"value":24},{"value":31}]' \
  --x-field value --x-title "Response Time (ms)" --y-title "Count" \
  --bins 8 --tick-min-step-y 1 --x-label-angle -30 \
  --output hist.png
```

### Pie / Donut Chart
```bash
# Pie
node chart.mjs --type pie --data '[{"category":"A","value":30},{"category":"B","value":70}]' \
  --category-field category --y-field value --output pie.png

# Donut (with hole)
node chart.mjs --type donut --data '[{"category":"A","value":30},{"category":"B","value":70}]' \
  --category-field category --y-field value --output donut.png
```

### Candlestick Chart (OHLC)
```bash
node chart.mjs --type candlestick \
  --data '[{"x":"Mon","open":100,"high":110,"low":95,"close":105}]' \
  --open-field open --high-field high --low-field low --close-field close \
  --title "Stock Price" --output candle.png
```

### Heatmap
```bash
node chart.mjs --type heatmap \
  --data '[{"x":"Mon","y":"Week1","value":5},{"x":"Tue","y":"Week1","value":8}]' \
  --color-value-field value --color-scheme viridis \
  --y-label-overlap greedy \
  --title "Activity Heatmap" --output heatmap.png
```

### Multi-Series Line Chart
Compare multiple trends on one chart:
```bash
node chart.mjs --type line --series-field "market" \
  --data '[{"x":"Jan","y":10,"market":"A"},{"x":"Jan","y":15,"market":"B"}]' \
  --title "Comparison" --output multi.png
```

### Stacked Bar Chart
```bash
node chart.mjs --type bar --stacked --color-field "category" \
  --data '[{"x":"Mon","y":10,"category":"Work"},{"x":"Mon","y":5,"category":"Personal"}]' \
  --title "Hours by Category" --output stacked.png
```

### Volume Overlay (Dual Y-axis)
Price line with volume bars:
```bash
node chart.mjs --type line --volume-field volume \
  --data '[{"x":"10:00","y":100,"volume":5000},{"x":"11:00","y":105,"volume":3000}]' \
  --title "Price + Volume" --output volume.png
```

### Sparkline (mini inline chart)
```bash
node chart.mjs --sparkline --data '[{"x":"1","y":10},{"x":"2","y":15}]' --output spark.png
```
Sparklines are 80x20 by default, transparent, no axes.

## Options Reference

### Basic Options
| Option | Description | Default |
|--------|-------------|---------|
| `--type` | Chart type: line, bar, area, point, histogram, pie, donut, candlestick, heatmap | line |
| `--data` | JSON array of data points | - |
| `--output` | Output file path | chart.png |
| `--title` | Chart title | - |
| `--width` | Width in pixels | 600 |
| `--height` | Height in pixels | 300 |

### Axis Options
| Option | Description | Default |
|--------|-------------|---------|
| `--x-field` | Field name for X axis | x |
| `--y-field` | Field name for Y axis | y |
| `--x-title` | X axis label | field name |
| `--y-title` | Y axis label | field name |
| `--x-type` | X axis type: ordinal, temporal, quantitative | ordinal |
| `--x-domain` | Clamp/zoom the X scale with `min,max` bounds for quantitative or temporal charts | auto |
| `--x-format` | Temporal X axis label format (d3-time-format, e.g. `%b %d`, `%H:%M`) | auto |
| `--x-sort` | X axis order: ascending, descending, or none (preserve input order) | auto |
| `--series-order CSV` | Explicit series/category order for multi-series and stacked legends (e.g. `Critical,High,Medium`) | data order |
| `--x-label-limit PX` | Max pixel width for X axis labels before Vega truncates them | auto |
| `--y-label-limit PX` | Max pixel width for Y axis labels before Vega truncates them | auto |
| `--x-ticks N` | Target X-axis tick count for dense or sparse charts | auto |
| `--y-ticks N` | Target primary/left Y-axis tick count for dense or sparse charts | auto |
| `--bins N` | Histogram bin count (`--type histogram` only) | Vega auto |
| `--tick-min-step N` | Minimum step between ticks on quantitative axes (great for counts / whole-number charts) | Vega auto |
| `--tick-min-step-x N` | Minimum step between ticks on quantitative X axes only | Vega auto |
| `--tick-min-step-y N` | Minimum step between ticks on quantitative Y axes only | Vega auto |
| `--x-label-angle N` | Rotate X-axis labels (for dense categories / timestamps) | -45 |
| `--y-label-angle N` | Rotate Y-axis labels (useful for horizontal bars / heatmaps) | 0 / Vega default |
| `--x-label-overlap MODE` | Force Vega X-axis overlap handling (`parity`, `greedy`, `true`, `false`) for crowded labels | Vega auto |
| `--y-label-overlap MODE` | Force Vega Y-axis overlap handling (`parity`, `greedy`, `true`, `false`) for crowded labels | Vega auto |
| `--y2-ticks N` | Target secondary/right Y-axis tick count for dual-axis and volume charts | auto |
| `--y-domain` | Y scale as "min,max" | auto |
| `--y-pad` | Add vertical padding as a fraction of range (e.g. `0.1` = 10%) | 0 |

### Visual Options
| Option | Description | Default |
|--------|-------------|---------|
| `--color` | Line/bar color | #e63946 |
| `--dark` | Dark mode theme | false |
| `--svg` | Output SVG instead of PNG | false |
| `--font-family` | CSS font-family string for chart text/legend/title theming | Helvetica, Arial, sans-serif |
| `--title-align` | Title alignment: `start`, `middle`, `end` | start |
| `--title-size N` | Title font size override in px | auto |
| `--subtitle-size N` | Subtitle font size override in px | auto |
| `--title-weight W` | Title font weight override (`normal`, `bold`, `100`-`900`) | auto |
| `--subtitle-weight W` | Subtitle font weight override (`normal`, `bold`, `100`-`900`) | auto |
| `--title-color` | Title text color override | theme text |
| `--subtitle-color` | Subtitle text color override | theme grid |
| `--grid-dash A,B` | Dash pattern for gridlines (for example `4,2`) | solid |

**Font examples:** `"Inter, Helvetica, Arial, sans-serif"`, `"Georgia, serif"`, `"JetBrains Mono, Consolas, monospace"`
| `--no-points` | Hide point markers on line charts | false |
| `--line-width N` | Set line thickness in pixels for line charts | 2 |
| `--point-size N` | Set point marker size for line/point charts | 60 |
| `--bar-radius N` | Round bar corners in pixels for bar-based charts | 0 |
| `--color-scheme` | Vega color scheme (category10, viridis, etc.) | - |
| `--legend-columns N` | Wrap legend entries into N columns for crowded multi-series/pie charts | auto |
| `--legend-label-limit PX` | Max pixel width for legend labels before Vega truncates them | auto |

### Alert/Monitor Options
| Option | Description | Default |
|--------|-------------|---------|
| `--show-change` | Show +/-% change annotation at last point | false |
| `--focus-change` | Zoom Y-axis to 2x data range | false |
| `--focus-recent N` | Show only last N data points | all |
| `--show-values` | Label min/max peak points | false |
| `--last-value` | Label the final data point value | false |

### Multi-Series/Stacked Options
| Option | Description | Default |
|--------|-------------|---------|
| `--series-field` | Field for multi-series line charts | - |
| `--stacked` | Enable stacked bar mode | false |
| `--color-field` | Field for stack/color categories | - |

### Candlestick Options
| Option | Description | Default |
|--------|-------------|---------|
| `--open-field` | OHLC open field | open |
| `--high-field` | OHLC high field | high |
| `--low-field` | OHLC low field | low |
| `--close-field` | OHLC close field | close |

### Pie/Donut Options
| Option | Description | Default |
|--------|-------------|---------|
| `--category-field` | Field for pie slice categories | x |
| `--donut` | Render as donut (with center hole) | false |

### Heatmap Options
| Option | Description | Default |
|--------|-------------|---------|
| `--color-value-field` | Field for heatmap intensity | value |
| `--y-category-field` | Y axis category field | y |

### Dual-Axis Options (General)
| Option | Description | Default |
|--------|-------------|---------|
| `--y2-field` | Second Y axis field (independent right axis) | - |
| `--y2-title` | Title for second Y axis | field name |
| `--y2-color` | Color for second series | #60a5fa (dark) / #2563eb (light) |
| `--y2-type` | Chart type for second axis: line, bar, area | line |
| `--y2-format` | Right-axis format: percent, dollar, compact, integer, decimal4, or d3-format string | auto |

**Example:** Revenue bars (left) + Churn area (right):
```bash
node chart.mjs \
  --data '[{"month":"Jan","revenue":12000,"churn":4.2},...]' \
  --x-field month --y-field revenue --type bar \
  --y2-field churn --y2-type area --y2-color "#60a5fa" --y2-format ".1f" \
  --y-title "Revenue ($)" --y2-title "Churn (%)" \
  --x-sort none --dark --title "Revenue vs Churn"
```

### Volume Overlay Options (Candlestick)
| Option | Description | Default |
|--------|-------------|---------|
| `--volume-field` | Field for volume bars (enables dual-axis) | - |
| `--volume-color` | Color for volume bars | #4a5568 |

### Formatting Options
| Option | Description | Default |
|--------|-------------|---------|
| `--y-format` | Y axis format: percent, dollar, compact, decimal4, integer, scientific, or d3-format string | auto |
| `--subtitle` | Subtitle text below chart title | - |
| `--hline` | Horizontal reference line: "value" or "value,color" or "value,color,label" (repeatable) | - |

### Annotation Options
| Option | Description | Default |
|--------|-------------|---------|
| `--annotation` | Static text annotation | - |
| `--annotations` | JSON array of event markers | - |

## Alert-Style Chart (recommended for monitors)

```bash
node chart.mjs --type line --data '[...]' \
  --title "Iran Strike Odds (48h)" \
  --show-change --focus-change --show-values --dark \
  --output alert.png
```

For recent action only:
```bash
node chart.mjs --type line --data '[hourly data...]' \
  --focus-recent 4 --show-change --focus-change --dark \
  --output recent.png
```

## Timeline Annotations

Mark events on the chart:
```bash
node chart.mjs --type line --data '[...]' \
  --annotations '[{"x":"14:00","label":"News broke"},{"x":"16:30","label":"Press conf"}]' \
  --output annotated.png
```

## Temporal X-Axis

For proper time series with date gaps:
```bash
node chart.mjs --type line --x-type temporal \
  --data '[{"x":"2026-01-01","y":10},{"x":"2026-01-15","y":20}]' \
  --output temporal.png
```

Use `--x-type temporal` when X values are ISO dates and you want spacing to reflect actual time gaps (not evenly spaced).

## Y-Axis Formatting

Format axis values for readability:
```bash
# Dollar amounts
node chart.mjs --data '[...]' --y-format dollar --output revenue.png
# → $1,234.56

# Percentages (values as decimals 0-1)
node chart.mjs --data '[...]' --y-format percent --output rates.png
# → 45.2%

# Compact large numbers
node chart.mjs --data '[...]' --y-format compact --output users.png
# → 1.2K, 3.4M

# Crypto prices (4 decimal places)
node chart.mjs --data '[...]' --y-format decimal4 --output molt.png
# → 0.0004

# Custom d3-format string
node chart.mjs --data '[...]' --y-format ',.3f' --output custom.png
```

Available shortcuts: `percent`, `dollar`/`usd`, `compact`, `integer`, `decimal2`, `decimal4`, `scientific`

## Chart Subtitle

Add context below the title:
```bash
node chart.mjs --title "MOLT Price" --subtitle "20,668 MOLT held" --data '[...]' --output molt.png
```

`--subtitle` works across standard charts plus pie/donut, heatmap, candlestick, stacked, multi-series, volume-overlay, and dual-axis layouts.

## Theme Selection

Use `--dark` for dark mode. Auto-select based on time:
- **Night (20:00-07:00 local)**: `--dark`
- **Day (07:00-20:00 local)**: light mode (default)

## Social Size Presets

Use `--output-size` when the chart is meant for a specific surface:

```bash
# Bluesky / OG-style landscape post
node chart.mjs --type line --data '[...]' --output-size bluesky --output bluesky-chart.png

# Instagram / Threads portrait post
node chart.mjs --type line --data '[...]' --output-size portrait --output portrait-chart.png
```

Available presets include `twitter`, `discord`, `slack`, `linkedin`, `bluesky` (`bsky` alias), `youtube`, `instagram`, `portrait`, `story`, `thumbnail`, `wide`, and `square`.

## Piping Data

```bash
echo '[{"x":"A","y":1},{"x":"B","y":2}]' | node chart.mjs --output out.png
```

## Custom Vega-Lite Spec

For advanced charts:
```bash
node chart.mjs --spec my-spec.json --output custom.png
```

## ⚠️ IMPORTANT: Always Send the Image!

After generating a chart, **always send it back to the user's channel**.
Don't just save to a file and describe it — the whole point is the visual.

```bash
# 1. Generate the chart
node chart.mjs --type line --data '...' --output /data/clawd/tmp/my-chart.png

# 2. Send it! Use message tool with filePath:
#    action=send, target=<channel_id>, filePath=/data/clawd/tmp/my-chart.png
```

**Tips:**
- Save to `/data/clawd/tmp/` (persistent) not `/tmp/` (may get cleaned)
- Use `action=send` with `filePath` — `thread-reply` does NOT support file attachments
- Include a brief caption in the message text
- Auto-use `--dark` between 20:00-07:00 Israel time

---
*Updated: 2026-04-06 - added `--y-label-angle` for crowded categorical/heatmap charts and documented per-axis label rotation; version bumped to 2.6.33*

Attribution

rondoflowrondoflow
View sourceMore from rondoflow →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

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 (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Caveman

Ultra-compressed communication mode that cuts output tokens while keeping technical accuracy. Levels: lite, full, ultra and the wenyan variants. Use for /caveman, "caveman mode", "talk like caveman", "be brief" or "less tokens".

1066601 votes

Hyperplan

Adversarial multi-agent planning skill. Self-orchestrates 5 hostile category members (unspecified-low, unspecified-high, deep, ultrabrain, artistry) via team-mode for ruthless cross-critique debate, distills only the defensible insights, then MANDATORILY hands the distilled insight bundle to the `plan` agent for executable plan formalization. Use when planning needs maximum rigor and surfacing of weak assumptions, blind spots, and over-engineering. Triggers: 'hyperplan', 'hpp', '/hyperplan', ...

693161 votes

Mcp Code Execution

Routes multi-tool workflows through MCP servers for large datasets and pipelines. Use when Bash tool overhead is limiting throughput on data-heavy tasks.

3351 votes

catchup

Recovers the conversation and failed tool calls of a previous Codex, Claude Code, Antigravity, Cline, Copilot CLI, Cursor, DeepSeek Harness, Kimi, OpenCode, Pi Agent, or ZCode session. Use when the user says "catch up", "what did the last session do", "get me up to speed", "I switched agents", asks to recover/summarize a previous session before continuing, or asks to diagnose or report a catchup failure. Do NOT use for the current conversation, git history, or any non-agent log.

691 votes

math-skill

A comprehensive mathematical reasoning skill for AI assistants — handles arithmetic to research-level problems with rigorous step-by-step reasoning, systematic verification, and transparent uncertainty handling

381 votes
View all in ai-agents →