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)
CODEBLOCK0
Quick Usage
CODEBLOCK1
Chart Types
Line Chart (default)
CODEBLOCK2
Quantitative X-domain clamp
Useful when you want a fixed numeric or temporal window without editing Vega-Lite by hand:
CODEBLOCK3
Bar Chart
CODEBLOCK4
Area Chart
CODEBLOCK5
Histogram
Use this for numeric distributions instead of pre-binned bar charts:
CODEBLOCK6
Pie / Donut Chart
CODEBLOCK7
Candlestick Chart (OHLC)
CODEBLOCK8
Heatmap
CODEBLOCK9
Multi-Series Line Chart
Compare multiple trends on one chart:
CODEBLOCK10
Stacked Bar Chart
CODEBLOCK11
Volume Overlay (Dual Y-axis)
Price line with volume bars:
CODEBLOCK12
Sparkline (mini inline chart)
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 |
|---|
| INLINECODE1 | Chart type: line, bar, area, point, histogram, pie, donut, candlestick, heatmap | line |
| INLINECODE2 |
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 |
|---|
| INLINECODE7 | Field name for X axis | x |
| INLINECODE8 |
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 |
|---|
| INLINECODE45 | Line/bar color | #e63946 |
| INLINECODE46 |
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 |
|---|
| INLINECODE79 | Show +/-% change annotation at last point | false |
| INLINECODE80 |
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 |
|---|
| INLINECODE84 | Field for multi-series line charts | - |
| INLINECODE85 |
Enable stacked bar mode | false |
|
--color-field | Field for stack/color categories | - |
Candlestick Options
| Option | Description | Default |
|---|
| INLINECODE87 | OHLC open field | open |
| INLINECODE88 |
OHLC high field | high |
|
--low-field | OHLC low field | low |
|
--close-field | OHLC close field | close |
Pie/Donut Options
| Option | Description | Default |
|---|
| INLINECODE91 | Field for pie slice categories | x |
| INLINECODE92 |
Render as donut (with center hole) | false |
Heatmap Options
| Option | Description | Default |
|---|
| INLINECODE93 | Field for heatmap intensity | value |
| INLINECODE94 |
Y axis category field | y |
Dual-Axis Options (General)
| Option | Description | Default |
|---|
| INLINECODE95 | Second Y axis field (independent right axis) | - |
| INLINECODE96 |
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):
CODEBLOCK14
Volume Overlay Options (Candlestick)
| Option | Description | Default |
|---|
| INLINECODE100 | Field for volume bars (enables dual-axis) | - |
| INLINECODE101 |
Color for volume bars | #4a5568 |
Formatting Options
| Option | Description | Default |
|---|
| INLINECODE102 | Y axis format: percent, dollar, compact, decimal4, integer, scientific, or d3-format string | auto |
| INLINECODE103 |
Subtitle text below chart title | - |
|
--hline | Horizontal reference line: "value" or "value,color" or "value,color,label" (repeatable) | - |
Annotation Options
| Option | Description | Default |
|---|
| INLINECODE105 | Static text annotation | - |
| INLINECODE106 |
JSON array of event markers | - |
Alert-Style Chart (recommended for monitors)
CODEBLOCK15
For recent action only:
CODEBLOCK16
Timeline Annotations
Mark events on the chart:
CODEBLOCK17
Temporal X-Axis
For proper time series with date gaps:
CODEBLOCK18
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:
CODEBLOCK19
Available shortcuts: percent, dollar/usd, compact, integer, decimal2, decimal4, INLINECODE115
Chart Subtitle
Add context below the title:
CODEBLOCK20
INLINECODE116 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): INLINECODE118
- Day (07:00-20:00 local): light mode (default)
Social Size Presets
Use --output-size when the chart is meant for a specific surface:
CODEBLOCK21
Available presets include twitter, discord, slack, linkedin, bluesky (bsky alias), youtube, instagram, portrait, story, thumbnail, wide, and square.
Piping Data
CODEBLOCK22
Custom Vega-Lite Spec
For advanced charts:
CODEBLOCK23
⚠️ 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.
CODEBLOCK24
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
图表图像生成器
使用Vega-Lite从数据生成PNG图表。完美适用于无头服务器环境。
为什么选择此技能?
专为Fly.io / VPS / Docker部署打造:
- - ✅ 无需本地编译 - 使用预构建二进制文件的Sharp(不同于需要构建工具的canvas)
- ✅ 无需Puppeteer/浏览器 - 纯Node.js,无需下载Chrome,无无头浏览器开销
- ✅ 轻量级 - 总依赖约15MB,而基于Puppeteer的解决方案超过400MB
- ✅ 冷启动快速 - 无需浏览器启动延迟,生成图表<500ms
- ✅ 离线可用 - 无需外部API调用(不同于QuickChart.io)
设置(一次性)
bash
cd /data/clawd/skills/chart-image/scripts && npm install
快速使用
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 价格随时间变化 \
--output chart.png
图表类型
折线图(默认)
bash
node chart.mjs --type line --data [{x:A,y:10},{x:B,y:15}] --output line.png
定量X轴域限制
当您希望固定数值或时间窗口而无需手动编辑Vega-Lite时非常有用:
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 前3分钟 \
--output x-domain.png
柱状图
bash
node chart.mjs --type bar --data [{x:A,y:10},{x:B,y:15}] --output bar.png
面积图
bash
node chart.mjs --type area --data [{x:A,y:10},{x:B,y:15}] --output area.png
直方图
用于数值分布而非预分组的柱状图:
bash
node chart.mjs --type histogram \
--data [{value:12},{value:18},{value:19},{value:24},{value:31}] \
--x-field value --x-title 响应时间(ms) --y-title 计数 \
--bins 8 --tick-min-step-y 1 --x-label-angle -30 \
--output hist.png
饼图/环形图
bash
饼图
node chart.mjs --type pie --data [{category:A,value:30},{category:B,value:70}] \
--category-field category --y-field value --output pie.png
环形图(带孔)
node chart.mjs --type donut --data [{category:A,value:30},{category:B,value:70}] \
--category-field category --y-field value --output donut.png
K线图(OHLC)
bash
node chart.mjs --type candlestick \
--data [{x:周一,open:100,high:110,low:95,close:105}] \
--open-field open --high-field high --low-field low --close-field close \
--title 股票价格 --output candle.png
热力图
bash
node chart.mjs --type heatmap \
--data [{x:周一,y:第1周,value:5},{x:周二,y:第1周,value:8}] \
--color-value-field value --color-scheme viridis \
--y-label-overlap greedy \
--title 活动热力图 --output heatmap.png
多系列折线图
在一个图表中比较多个趋势:
bash
node chart.mjs --type line --series-field market \
--data [{x:一月,y:10,market:A},{x:一月,y:15,market:B}] \
--title 比较 --output multi.png
堆叠柱状图
bash
node chart.mjs --type bar --stacked --color-field category \
--data [{x:周一,y:10,category:工作},{x:周一,y:5,category:个人}] \
--title 按类别统计小时数 --output stacked.png
成交量叠加(双Y轴)
价格线加成交量柱:
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 价格+成交量 --output volume.png
迷你图(小型内联图表)
bash
node chart.mjs --sparkline --data [{x:1,y:10},{x:2,y:15}] --output spark.png
迷你图默认80x20,透明背景,无坐标轴。
选项参考
基本选项
| 选项 | 描述 | 默认值 |
|---|
| --type | 图表类型:line, bar, area, point, histogram, pie, donut, candlestick, heatmap | line |
| --data |
数据点的JSON数组 | - |
| --output | 输出文件路径 | chart.png |
| --title | 图表标题 | - |
| --width | 宽度(像素) | 600 |
| --height | 高度(像素) | 300 |
坐标轴选项
| 选项 | 描述 | 默认值 |
|---|
| --x-field | X轴字段名 | x |
| --y-field |
Y轴字段名 | y |
| --x-title | X轴标签 | 字段名 |
| --y-title | Y轴标签 | 字段名 |
| --x-type | X轴类型:ordinal, temporal, quantitative | ordinal |
| --x-domain | 使用min,max边界限制/缩放X轴范围(适用于定量或时间图表) | auto |
| --x-format | 时间X轴标签格式(d3-time-format,例如%b %d、%H:%M) | auto |
| --x-sort | X轴排序:ascending, descending, 或 none(保留输入顺序) | auto |
| --series-order CSV | 多系列和堆叠图例的显式系列/类别顺序(例如Critical,High,Medium) | 数据顺序 |
| --x-label-limit PX | Vega截断前X轴标签的最大像素宽度 | auto |
| --y-label-limit PX | Vega截断前Y轴标签的最大像素宽度 | auto |
| --x-ticks N | 密集或稀疏图表的X轴目标刻度数 | auto |
| --y-ticks N | 密集或稀疏图表的主/左Y轴目标刻度数 | auto |
| --bins N | 直方图分箱数(仅--type histogram) | Vega自动 |
| --tick-min-step N | 定量轴上刻度之间的最小步长(适用于计数/整数图表) | Vega自动 |
| --tick-min-step-x N | 仅定量X轴上刻度之间的最小步长 | Vega自动 |
| --tick-min-step-y N | 仅定量Y轴上刻度之间的最小步长 | Vega自动 |
| --x-label-angle N | 旋转X轴标签(适用于密集类别/时间戳) | -45 |
| --y-label-angle N | 旋转Y轴标签(适用于水平柱状图/热力图) | 0 / Vega默认 |
| --x-label-overlap MODE | 强制Vega X轴重叠处理(parity, greedy, true, false)用于拥挤标签 | Vega自动 |
| --y-label-overlap MODE | 强制Vega Y轴重叠处理(parity, greedy, true, false)用于拥挤标签 | Vega自动 |
| --y2-ticks N | 双轴和成交量图表的次/右Y轴目标刻度数 | auto |
| --y-domain | Y轴范围min,max | auto |
| --y-pad | 添加垂直内边距,范围为范围的分数(例如0.1