/graphic-chart
Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph",
$ npx -y skills add Varnan-Tech/opendirectory --skill graphic-chart --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/graphic-chart
Context preview
The summary Claude sees to decide when to auto-load this skill.
Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph",
SKILL.md
graphic-chart.SKILL.mdname: graphic-chart
description: Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers".
compatibility: [claude-code, gemini-cli, github-copilot]
author: OpenDirectory
version: 2.0.0
graphic-chart
Generates data visualization charts as PNG. Renders HTML with Apache ECharts v6 in headless Chromium via Playwright → screenshots at 2× retina quality.
CDN: `https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.min.js`
---
Critical Rules (read before every generation)
1. **`area` type → `type: 'line'` + `areaStyle: {}`** — ECharts has no `type: 'area'`. 2. **`doughnut` → `type: 'pie'` + `radius: ['40%', '70%']`** — ECharts has no `type: 'doughnut'`. 3. **Readiness signal: register `chart.on('finished', fn)` BEFORE `chart.setOption()`** — ECharts bug #14101/#17500: if listener is registered after setOption, it silently never fires. Always register both `finished` and `rendered` events before setOption. 4. **`xAxis.type: 'category'` must be explicit** — ECharts does not infer it from the data. Forgetting this produces a blank chart. 5. **Category labels go in `xAxis.data`**, not in a `data.labels` array. ECharts structure is flat: `{ xAxis, yAxis, series, grid, title, legend }` — not nested under `data` or `options`. 6. **Data labels are fully built-in** — use `label: { show: true }` on any series. No plugin needed. 7. **Highlight a specific bar/point via per-item `itemStyle`** — put `{ value: N, itemStyle: { color: '#...' } }` directly in the `data` array. Do NOT use Chart.js-style `backgroundColor` arrays. 8. **ECharts init uses a `<div>` container, not `<canvas>`** — `echarts.init(document.getElementById('chart'))`. The container div needs explicit dimensions. 9. **`animation: false` in option** — disables animation for instant render. Still register `finished` + `rendered` events before setOption for the readiness signal. 10. **Never dump HTML in chat.** Save to file, show summary only. 11. **Title states the insight, not the subject.** "Revenue grew 3× in 12 months" not "Monthly Revenue". 12. **Pie/doughnut: use body `padding: 64px 80px` and `.chart-container { max-height: 860px }`** — prevents edge-to-edge fill when no title.
---
Step 1: Intake
**Required:** `chart_type`, `data`
**Optional parameters and defaults:**
| Parameter | Default | Description | |---|---|---| | chart_type | — | bar / line / area / pie / doughnut / scatter / radar / treemap | | data | — | JSON array or CSV — required | | title | — | States the insight, ≤10 words | | subtitle | — | 1-sentence context line | | style | clean-slate | clean-slate / midnight-editorial / matt-gray / electric-burst / brutalist | | dimensions | 1080x1080 | WxH pixels (output PNG = 2× via deviceScaleFactor) | | x_label | — | X-axis label text | | y_label | — | Y-axis label text | | source | — | Data source shown in footer | | highlight | — | Data label to highlight (e.g. "Q4", "Dec", index 3) |
**If `chart_type` or `data` is missing, ask exactly:**
> "To create the chart, I need: > 1. **Chart type** — bar / line / area / pie / doughnut / scatter / radar / treemap > 2. **Data** — provide as JSON array or CSV (e.g. `[12, 18, 22, 25, 31]` with labels `['Q1','Q2','Q3','Q4','Q5']`) > > Optional: title, style (default: clean-slate), dimensions (default: 1080×1080), highlight a specific data point"
If both present → skip to Step 2.
---
Step 2: Internal Architecture (never shown to user)
**1. Normalize chart type:**
- `area` → `line` + `areaStyle: {}` on series
- `doughnut` → `pie` + `radius: ['40%', '70%']` on series
- `horizontal bar` → `bar` + swap xAxis/yAxis (category axis on y)
- All others: use as-is
**2. Read `references/chart-library.md`** — load full config spec for this chart type.
**3. Read `references/style-presets.md`** — load CSS tokens + data palette for chosen style.
**4. Commit to design direction:**
| Decision | Derive from | |---|---| | Tone | Professional / editorial / bold / technical — match the data's audience | | Data story | Single insight this chart proves (becomes the title) | | Highlight strategy | Which data point needs visual emphasis and why? | | Background | Light (clean-slate, matt-gray) or dark (midnight-editorial, electric-burst, brutalist) |
**5. Parse data:**
- Simple array `[12, 18, 22]` → series.data, labels provided separately
- Object array `[{x: 'Jan', y: 12}]` → xAxis.data from x keys, series.data from y values
- CSV: parse header row as xAxis.data, value row as series.data
- Multi-series: multiple `series` entries each with `type`, `name`, `data`
- Scatter: `series.data: [[x1,y1], [x2,y2], ...]` format
**6. Parse dimensions:** `"1080x1080"` → W=1080, H=1080. Body = WxH. Output PNG = 2W × 2H.
---
Step 3: HTML Generation
Read ALL before generating:
- `references/chart-library.md` for this chart type's full ECharts config spec
- `references/style-presets.md` for the chosen style's CSS tokens + palette
**Required HTML structure:**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from style preset]
<style>
:root {
[all CSS tokens from style preset]
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: [W]px; height: [H]px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
}
body {
display: flex;
flex-direction: column;
padding: 40px 48px 32px; /* pie/doughnut: use 64px 80px */
}
/* ECharts container must have explicit size */
.chart-container {
flex: 1;
min-height: 0;
/* pie/doughnut only: max-height: 860px; */
}
.chart-header { margin-bottom: 24px; }
.chart-title {
font-family: var(--font-display);
font-size: cRead more
name: graphic-chart description: Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6. 1080×1080px default, 5 style presets, highlight annotations. Trigger when user says "create a chart", "visualize data", "make a bar chart", "line graph", "pie chart", "data visualization", "chart this data", "plot", "graph", or "visualize these numbers". compatibility: [claude-code, gemini-cli, github-copilot] author: OpenDirectory version: 2.0.0
graphic-chart
Generates data visualization charts as PNG. Renders HTML with Apache ECharts v6 in headless Chromium via Playwright → screenshots at 2× retina quality.
CDN: `https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.min.js`
---
Critical Rules (read before every generation)
1. **`area` type → `type: 'line'` + `areaStyle: {}`** — ECharts has no `type: 'area'`. 2. **`doughnut` → `type: 'pie'` + `radius: ['40%', '70%']`** — ECharts has no `type: 'doughnut'`. 3. **Readiness signal: register `chart.on('finished', fn)` BEFORE `chart.setOption()`** — ECharts bug #14101/#17500: if listener is registered after setOption, it silently never fires. Always register both `finished` and `rendered` events before setOption. 4. **`xAxis.type: 'category'` must be explicit** — ECharts does not infer it from the data. Forgetting this produces a blank chart. 5. **Category labels go in `xAxis.data`**, not in a `data.labels` array. ECharts structure is flat: `{ xAxis, yAxis, series, grid, title, legend }` — not nested under `data` or `options`. 6. **Data labels are fully built-in** — use `label: { show: true }` on any series. No plugin needed. 7. **Highlight a specific bar/point via per-item `itemStyle`** — put `{ value: N, itemStyle: { color: '#...' } }` directly in the `data` array. Do NOT use Chart.js-style `backgroundColor` arrays. 8. **ECharts init uses a `<div>` container, not `<canvas>`** — `echarts.init(document.getElementById('chart'))`. The container div needs explicit dimensions. 9. **`animation: false` in option** — disables animation for instant render. Still register `finished` + `rendered` events before setOption for the readiness signal. 10. **Never dump HTML in chat.** Save to file, show summary only. 11. **Title states the insight, not the subject.** "Revenue grew 3× in 12 months" not "Monthly Revenue". 12. **Pie/doughnut: use body `padding: 64px 80px` and `.chart-container { max-height: 860px }`** — prevents edge-to-edge fill when no title.
---
Step 1: Intake
**Required:** `chart_type`, `data`
**Optional parameters and defaults:**
| Parameter | Default | Description | |---|---|---| | chart_type | — | bar / line / area / pie / doughnut / scatter / radar / treemap | | data | — | JSON array or CSV — required | | title | — | States the insight, ≤10 words | | subtitle | — | 1-sentence context line | | style | clean-slate | clean-slate / midnight-editorial / matt-gray / electric-burst / brutalist | | dimensions | 1080x1080 | WxH pixels (output PNG = 2× via deviceScaleFactor) | | x_label | — | X-axis label text | | y_label | — | Y-axis label text | | source | — | Data source shown in footer | | highlight | — | Data label to highlight (e.g. "Q4", "Dec", index 3) |
**If `chart_type` or `data` is missing, ask exactly:**
> "To create the chart, I need: > 1. **Chart type** — bar / line / area / pie / doughnut / scatter / radar / treemap > 2. **Data** — provide as JSON array or CSV (e.g. `[12, 18, 22, 25, 31]` with labels `['Q1','Q2','Q3','Q4','Q5']`) > > Optional: title, style (default: clean-slate), dimensions (default: 1080×1080), highlight a specific data point"
If both present → skip to Step 2.
---
Step 2: Internal Architecture (never shown to user)
**1. Normalize chart type:**
- `area` → `line` + `areaStyle: {}` on series
- `doughnut` → `pie` + `radius: ['40%', '70%']` on series
- `horizontal bar` → `bar` + swap xAxis/yAxis (category axis on y)
- All others: use as-is
**2. Read `references/chart-library.md`** — load full config spec for this chart type.
**3. Read `references/style-presets.md`** — load CSS tokens + data palette for chosen style.
**4. Commit to design direction:**
| Decision | Derive from | |---|---| | Tone | Professional / editorial / bold / technical — match the data's audience | | Data story | Single insight this chart proves (becomes the title) | | Highlight strategy | Which data point needs visual emphasis and why? | | Background | Light (clean-slate, matt-gray) or dark (midnight-editorial, electric-burst, brutalist) |
**5. Parse data:**
- Simple array `[12, 18, 22]` → series.data, labels provided separately
- Object array `[{x: 'Jan', y: 12}]` → xAxis.data from x keys, series.data from y values
- CSV: parse header row as xAxis.data, value row as series.data
- Multi-series: multiple `series` entries each with `type`, `name`, `data`
- Scatter: `series.data: [[x1,y1], [x2,y2], ...]` format
**6. Parse dimensions:** `"1080x1080"` → W=1080, H=1080. Body = WxH. Output PNG = 2W × 2H.
---
Step 3: HTML Generation
Read ALL before generating:
- `references/chart-library.md` for this chart type's full ECharts config spec
- `references/style-presets.md` for the chosen style's CSS tokens + palette
**Required HTML structure:**
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
[font CDN link from style preset]
<style>
:root {
[all CSS tokens from style preset]
}
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: [W]px; height: [H]px;
overflow: hidden;
background: var(--bg);
font-family: var(--font-body);
}
body {
display: flex;
flex-direction: column;
padding: 40px 48px 32px; /* pie/doughnut: use 64px 80px */
}
/* ECharts container must have explicit size */
.chart-container {
flex: 1;
min-height: 0;
/* pie/doughnut only: max-height: 860px; */
}
.chart-header { margin-bottom: 24px; }
.chart-title {
font-family: var(--font-display);
font-size: cAI Agent Skills built for Founders who hate Marketing
Repo: Varnan-Tech/opendirectory
Other skills on opendirectory-gtm-skills.
- /app-store-review-arbitrage
Fetches low-star App Store and Google Play reviews, clusters them into broken-promise patterns, and generates a ranked copy brief with positioning opportunities.
Open skill - /blog-cover-image-cli
Use when the user asks to generate a blog cover image, thumbnail, or article header. Automatically uses modern typography, brand logos, and Google Search grounding to create beautiful 16:9 images with Gemini 3.1 Flash Image Preview.
Open skill - /brand-alchemy
World-class brand strategist and naming expert. Uses an interrogation-led discovery phase to extract your brand's DNA, then applies scientific naming frameworks (Phonosemantics) and automated multi-TLD domain checking.
Open skill - /claude-md-generator
Use when the user asks to generate or update a project's CLAUDE or AGENTS context file from a codebase scan. Writes a focused file under 100 lines containing only the non-obvious build commands, conventions, and gotchas Claude Code needs.
Open skill - /cold-email-verifier
Use when the user wants to verify cold emails, enrich a lead list, or autonomously guess email addresses from a CSV using ValidEmail.co or the open-source Reacher engine.
Open skill - /company-radar
Competitive intelligence orchestrator tracking companies across 8+ platforms (GitHub, Twitter, Reddit, HN, PH, YC Jobs) with heat scores and AI briefings.
Open skill

