@opendirectory.dev/skills 0.1.58 → 0.1.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/registry.json +18 -0
- package/skills/graphic-chart/README.md +104 -0
- package/skills/graphic-chart/SKILL.md +318 -0
- package/skills/graphic-chart/evals/evals.json +30 -0
- package/skills/graphic-chart/references/chart-library.md +487 -0
- package/skills/graphic-chart/references/style-presets.md +219 -0
- package/skills/graphic-chart/scripts/export-chart.sh +182 -0
- package/skills/graphic-chart/scripts/screenshot-chart.mjs +143 -0
- package/skills/graphic-gif/README.md +99 -0
- package/skills/graphic-gif/SKILL.md +313 -0
- package/skills/graphic-gif/evals/evals.json +30 -0
- package/skills/graphic-gif/references/animation-library.md +446 -0
- package/skills/graphic-gif/references/style-presets.md +194 -0
- package/skills/graphic-gif/scripts/capture-and-encode.mjs +201 -0
- package/skills/graphic-gif/scripts/export-gif.sh +274 -0
package/package.json
CHANGED
package/registry.json
CHANGED
|
@@ -126,6 +126,14 @@
|
|
|
126
126
|
"version": "1.0.0",
|
|
127
127
|
"path": "skills/graphic-case-study"
|
|
128
128
|
},
|
|
129
|
+
{
|
|
130
|
+
"name": "graphic-chart",
|
|
131
|
+
"description": "Generates data visualization charts (bar, line, area, pie, doughnut, scatter, radar, treemap) as PNG using Apache ECharts v6.",
|
|
132
|
+
"tags": [],
|
|
133
|
+
"author": "OpenDirectory",
|
|
134
|
+
"version": "2.0.0",
|
|
135
|
+
"path": "skills/graphic-chart"
|
|
136
|
+
},
|
|
129
137
|
{
|
|
130
138
|
"name": "graphic-ebook",
|
|
131
139
|
"description": "Creates professionally designed B2B SaaS e-books in HTML + CSS, exported as print-ready PDF.",
|
|
@@ -134,6 +142,16 @@
|
|
|
134
142
|
"version": "1.0.0",
|
|
135
143
|
"path": "skills/graphic-ebook"
|
|
136
144
|
},
|
|
145
|
+
{
|
|
146
|
+
"name": "graphic-gif",
|
|
147
|
+
"description": "Creates animated looping GIFs from CSS animations (default) or AI image-to-video.",
|
|
148
|
+
"tags": [
|
|
149
|
+
"AI"
|
|
150
|
+
],
|
|
151
|
+
"author": "OpenDirectory",
|
|
152
|
+
"version": "1.0.0",
|
|
153
|
+
"path": "skills/graphic-gif"
|
|
154
|
+
},
|
|
137
155
|
{
|
|
138
156
|
"name": "graphic-slide-deck",
|
|
139
157
|
"description": "Generates a professionally designed HTML slide deck from a brief or content.",
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# graphic-chart
|
|
2
|
+
|
|
3
|
+
Generate publication-quality data visualization charts as PNG using Chart.js v4. 8 chart types, 5 style presets, annotation highlights.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx "@opendirectory.dev/skills" install graphic-chart --target claude
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Manual Install (2 steps)
|
|
12
|
+
|
|
13
|
+
1. Copy the URL of this skill folder, paste it at [download-directory.github.io](https://download-directory.github.io/), download the zip.
|
|
14
|
+
2. Open Claude desktop app → sidebar → **Customize** → **Skills** → **+** → **Upload a skill** → drop the extracted folder.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
- Takes chart type + data (JSON or CSV) as input
|
|
21
|
+
- Generates a self-contained HTML file with Chart.js v4
|
|
22
|
+
- Screenshots via headless Chromium at 2× deviceScaleFactor (retina quality)
|
|
23
|
+
- Outputs a crisp PNG ready for decks, reports, social, or email
|
|
24
|
+
- Supports annotation highlights on a specific data point
|
|
25
|
+
- No Python, no API key, no external service
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Example
|
|
30
|
+
|
|
31
|
+
> "Create a line chart. Title: 'From $12k to $95k ARR in 12 Months'. Data: [12, 18, 22, 25, 31, 38, 44, 52, 61, 68, 78, 95] (Jan–Dec 2024, in thousands). Highlight December in gold. Source: Internal CRM. Style: electric-burst. Dimensions: 1080x1080."
|
|
32
|
+
|
|
33
|
+
Output: `chart.png` — dark canvas, electric yellow December highlight with callout, growth title.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Supported Chart Types
|
|
38
|
+
|
|
39
|
+
| Type | Best for |
|
|
40
|
+
|---|---|
|
|
41
|
+
| bar | Comparing values across categories |
|
|
42
|
+
| line | Trends over time |
|
|
43
|
+
| area | Cumulative trends, volume over time |
|
|
44
|
+
| pie | Part-to-whole relationships |
|
|
45
|
+
| doughnut | Part-to-whole with center hole |
|
|
46
|
+
| scatter | Correlations between two variables |
|
|
47
|
+
| radar | Multi-dimensional comparisons |
|
|
48
|
+
| treemap | Hierarchical data, proportional sizes |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Supported Styles
|
|
53
|
+
|
|
54
|
+
| Style | Best for |
|
|
55
|
+
|---|---|
|
|
56
|
+
| clean-slate | Enterprise B2B, investor decks, any professional audience |
|
|
57
|
+
| midnight-editorial | Editorial, premium brand, thought leadership |
|
|
58
|
+
| matt-gray | Board materials, consultancy reports, sophisticated neutral |
|
|
59
|
+
| electric-burst | Growth metrics, startup content, bold data stories |
|
|
60
|
+
| brutalist | Design-forward, stark comparisons, confrontational data |
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Parameters
|
|
65
|
+
|
|
66
|
+
| Parameter | Required | Default | Description |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| chart_type | Yes | — | bar / line / area / pie / doughnut / scatter / radar / treemap |
|
|
69
|
+
| data | Yes | — | JSON array or CSV |
|
|
70
|
+
| title | No | — | States the insight (≤10 words) |
|
|
71
|
+
| subtitle | No | — | 1-sentence context line |
|
|
72
|
+
| style | No | clean-slate | Visual style preset |
|
|
73
|
+
| dimensions | No | 1080x1080 | WxH in pixels |
|
|
74
|
+
| x_label | No | — | X-axis label |
|
|
75
|
+
| y_label | No | — | Y-axis label |
|
|
76
|
+
| source | No | — | Data source for footer attribution |
|
|
77
|
+
| highlight | No | — | Data label/value to annotate (e.g. "Q4", "Dec") |
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Output
|
|
82
|
+
|
|
83
|
+
| File | What it is |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `chart/[slug]/chart.html` | Self-contained HTML (open in browser to preview) |
|
|
86
|
+
| `chart/[slug]/chart.png` | PNG at 2× retina quality |
|
|
87
|
+
|
|
88
|
+
Default output: `1080×1080` viewport → `2160×2160` PNG (@2× deviceScaleFactor).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Dependencies
|
|
93
|
+
|
|
94
|
+
**Node.js** — required. Install from [nodejs.org](https://nodejs.org) or `brew install node`.
|
|
95
|
+
|
|
96
|
+
Bundled inside this skill:
|
|
97
|
+
- `scripts/export-chart.sh` — orchestrator script
|
|
98
|
+
- `scripts/screenshot-chart.mjs` — Playwright capture script
|
|
99
|
+
|
|
100
|
+
Auto-installed on first run via npm:
|
|
101
|
+
- `playwright` — headless Chromium for screenshot
|
|
102
|
+
- Chromium browser binary (~200MB, downloaded once and cached)
|
|
103
|
+
|
|
104
|
+
No API keys required.
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: graphic-chart
|
|
3
|
+
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".
|
|
4
|
+
compatibility: [claude-code, gemini-cli, github-copilot]
|
|
5
|
+
author: OpenDirectory
|
|
6
|
+
version: 2.0.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# graphic-chart
|
|
10
|
+
|
|
11
|
+
Generates data visualization charts as PNG. Renders HTML with Apache ECharts v6 in headless Chromium via Playwright → screenshots at 2× retina quality.
|
|
12
|
+
|
|
13
|
+
CDN: `https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.min.js`
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Critical Rules (read before every generation)
|
|
18
|
+
|
|
19
|
+
1. **`area` type → `type: 'line'` + `areaStyle: {}`** — ECharts has no `type: 'area'`.
|
|
20
|
+
2. **`doughnut` → `type: 'pie'` + `radius: ['40%', '70%']`** — ECharts has no `type: 'doughnut'`.
|
|
21
|
+
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.
|
|
22
|
+
4. **`xAxis.type: 'category'` must be explicit** — ECharts does not infer it from the data. Forgetting this produces a blank chart.
|
|
23
|
+
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`.
|
|
24
|
+
6. **Data labels are fully built-in** — use `label: { show: true }` on any series. No plugin needed.
|
|
25
|
+
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.
|
|
26
|
+
8. **ECharts init uses a `<div>` container, not `<canvas>`** — `echarts.init(document.getElementById('chart'))`. The container div needs explicit dimensions.
|
|
27
|
+
9. **`animation: false` in option** — disables animation for instant render. Still register `finished` + `rendered` events before setOption for the readiness signal.
|
|
28
|
+
10. **Never dump HTML in chat.** Save to file, show summary only.
|
|
29
|
+
11. **Title states the insight, not the subject.** "Revenue grew 3× in 12 months" not "Monthly Revenue".
|
|
30
|
+
12. **Pie/doughnut: use body `padding: 64px 80px` and `.chart-container { max-height: 860px }`** — prevents edge-to-edge fill when no title.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Step 1: Intake
|
|
35
|
+
|
|
36
|
+
**Required:** `chart_type`, `data`
|
|
37
|
+
|
|
38
|
+
**Optional parameters and defaults:**
|
|
39
|
+
|
|
40
|
+
| Parameter | Default | Description |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| chart_type | — | bar / line / area / pie / doughnut / scatter / radar / treemap |
|
|
43
|
+
| data | — | JSON array or CSV — required |
|
|
44
|
+
| title | — | States the insight, ≤10 words |
|
|
45
|
+
| subtitle | — | 1-sentence context line |
|
|
46
|
+
| style | clean-slate | clean-slate / midnight-editorial / matt-gray / electric-burst / brutalist |
|
|
47
|
+
| dimensions | 1080x1080 | WxH pixels (output PNG = 2× via deviceScaleFactor) |
|
|
48
|
+
| x_label | — | X-axis label text |
|
|
49
|
+
| y_label | — | Y-axis label text |
|
|
50
|
+
| source | — | Data source shown in footer |
|
|
51
|
+
| highlight | — | Data label to highlight (e.g. "Q4", "Dec", index 3) |
|
|
52
|
+
|
|
53
|
+
**If `chart_type` or `data` is missing, ask exactly:**
|
|
54
|
+
|
|
55
|
+
> "To create the chart, I need:
|
|
56
|
+
> 1. **Chart type** — bar / line / area / pie / doughnut / scatter / radar / treemap
|
|
57
|
+
> 2. **Data** — provide as JSON array or CSV (e.g. `[12, 18, 22, 25, 31]` with labels `['Q1','Q2','Q3','Q4','Q5']`)
|
|
58
|
+
>
|
|
59
|
+
> Optional: title, style (default: clean-slate), dimensions (default: 1080×1080), highlight a specific data point"
|
|
60
|
+
|
|
61
|
+
If both present → skip to Step 2.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Step 2: Internal Architecture (never shown to user)
|
|
66
|
+
|
|
67
|
+
**1. Normalize chart type:**
|
|
68
|
+
- `area` → `line` + `areaStyle: {}` on series
|
|
69
|
+
- `doughnut` → `pie` + `radius: ['40%', '70%']` on series
|
|
70
|
+
- `horizontal bar` → `bar` + swap xAxis/yAxis (category axis on y)
|
|
71
|
+
- All others: use as-is
|
|
72
|
+
|
|
73
|
+
**2. Read `references/chart-library.md`** — load full config spec for this chart type.
|
|
74
|
+
|
|
75
|
+
**3. Read `references/style-presets.md`** — load CSS tokens + data palette for chosen style.
|
|
76
|
+
|
|
77
|
+
**4. Commit to design direction:**
|
|
78
|
+
|
|
79
|
+
| Decision | Derive from |
|
|
80
|
+
|---|---|
|
|
81
|
+
| Tone | Professional / editorial / bold / technical — match the data's audience |
|
|
82
|
+
| Data story | Single insight this chart proves (becomes the title) |
|
|
83
|
+
| Highlight strategy | Which data point needs visual emphasis and why? |
|
|
84
|
+
| Background | Light (clean-slate, matt-gray) or dark (midnight-editorial, electric-burst, brutalist) |
|
|
85
|
+
|
|
86
|
+
**5. Parse data:**
|
|
87
|
+
- Simple array `[12, 18, 22]` → series.data, labels provided separately
|
|
88
|
+
- Object array `[{x: 'Jan', y: 12}]` → xAxis.data from x keys, series.data from y values
|
|
89
|
+
- CSV: parse header row as xAxis.data, value row as series.data
|
|
90
|
+
- Multi-series: multiple `series` entries each with `type`, `name`, `data`
|
|
91
|
+
- Scatter: `series.data: [[x1,y1], [x2,y2], ...]` format
|
|
92
|
+
|
|
93
|
+
**6. Parse dimensions:** `"1080x1080"` → W=1080, H=1080. Body = WxH. Output PNG = 2W × 2H.
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Step 3: HTML Generation
|
|
98
|
+
|
|
99
|
+
Read ALL before generating:
|
|
100
|
+
- `references/chart-library.md` for this chart type's full ECharts config spec
|
|
101
|
+
- `references/style-presets.md` for the chosen style's CSS tokens + palette
|
|
102
|
+
|
|
103
|
+
**Required HTML structure:**
|
|
104
|
+
|
|
105
|
+
```html
|
|
106
|
+
<!DOCTYPE html>
|
|
107
|
+
<html lang="en">
|
|
108
|
+
<head>
|
|
109
|
+
<meta charset="UTF-8">
|
|
110
|
+
[font CDN link from style preset]
|
|
111
|
+
<style>
|
|
112
|
+
:root {
|
|
113
|
+
[all CSS tokens from style preset]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
|
|
117
|
+
html, body {
|
|
118
|
+
width: [W]px; height: [H]px;
|
|
119
|
+
overflow: hidden;
|
|
120
|
+
background: var(--bg);
|
|
121
|
+
font-family: var(--font-body);
|
|
122
|
+
}
|
|
123
|
+
body {
|
|
124
|
+
display: flex;
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
padding: 40px 48px 32px; /* pie/doughnut: use 64px 80px */
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/* ECharts container must have explicit size */
|
|
130
|
+
.chart-container {
|
|
131
|
+
flex: 1;
|
|
132
|
+
min-height: 0;
|
|
133
|
+
/* pie/doughnut only: max-height: 860px; */
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.chart-header { margin-bottom: 24px; }
|
|
137
|
+
.chart-title {
|
|
138
|
+
font-family: var(--font-display);
|
|
139
|
+
font-size: clamp(1.1rem, 2.5vw, 1.6rem);
|
|
140
|
+
font-weight: 700;
|
|
141
|
+
color: var(--text);
|
|
142
|
+
line-height: 1.2;
|
|
143
|
+
}
|
|
144
|
+
.chart-subtitle {
|
|
145
|
+
font-family: var(--font-body);
|
|
146
|
+
font-size: clamp(0.75rem, 1.2vw, 0.9rem);
|
|
147
|
+
color: var(--text-muted);
|
|
148
|
+
margin-top: 6px;
|
|
149
|
+
line-height: 1.5;
|
|
150
|
+
}
|
|
151
|
+
.chart-footer {
|
|
152
|
+
margin-top: 14px;
|
|
153
|
+
font-family: var(--font-body);
|
|
154
|
+
font-size: 10px;
|
|
155
|
+
color: var(--text-muted);
|
|
156
|
+
opacity: 0.65;
|
|
157
|
+
}
|
|
158
|
+
</style>
|
|
159
|
+
</head>
|
|
160
|
+
<body>
|
|
161
|
+
|
|
162
|
+
[if title or subtitle: <div class="chart-header"><div class="chart-title">...</div>...</div>]
|
|
163
|
+
|
|
164
|
+
<div id="chart" class="chart-container"></div>
|
|
165
|
+
|
|
166
|
+
[if source: <div class="chart-footer">Source: [source]</div>]
|
|
167
|
+
|
|
168
|
+
<script src="https://cdn.jsdelivr.net/npm/echarts@6.0.0/dist/echarts.min.js"></script>
|
|
169
|
+
|
|
170
|
+
<script>
|
|
171
|
+
window.__chartReady = false;
|
|
172
|
+
|
|
173
|
+
document.fonts.ready.then(() => {
|
|
174
|
+
const container = document.getElementById('chart');
|
|
175
|
+
const chart = echarts.init(container, null, { renderer: 'canvas' });
|
|
176
|
+
|
|
177
|
+
// CRITICAL: register events BEFORE setOption — ECharts bug #14101/#17500
|
|
178
|
+
// 'finished' may silently not fire if registered after setOption with animation:false
|
|
179
|
+
chart.on('finished', () => {
|
|
180
|
+
window.__chartReady = true;
|
|
181
|
+
});
|
|
182
|
+
// Belt-and-suspenders fallback via 'rendered'
|
|
183
|
+
chart.on('rendered', () => {
|
|
184
|
+
clearTimeout(window.__renderDebounce);
|
|
185
|
+
window.__renderDebounce = setTimeout(() => { window.__chartReady = true; }, 100);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
const palette = [palette from style preset];
|
|
189
|
+
|
|
190
|
+
const option = {
|
|
191
|
+
animation: false, // instant render for screenshot
|
|
192
|
+
|
|
193
|
+
backgroundColor: 'transparent', // body CSS handles bg color
|
|
194
|
+
|
|
195
|
+
textStyle: {
|
|
196
|
+
fontFamily: '[--font-body value]',
|
|
197
|
+
color: '[--text-muted value]',
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
[title config if title param provided],
|
|
201
|
+
[legend config per chart type],
|
|
202
|
+
[grid config per chart type],
|
|
203
|
+
[xAxis config per chart type],
|
|
204
|
+
[yAxis config per chart type],
|
|
205
|
+
|
|
206
|
+
series: [{
|
|
207
|
+
[full series config from chart-library.md for this type]
|
|
208
|
+
[palette colors applied per chart type]
|
|
209
|
+
[if highlight: per-item itemStyle on the highlighted data point]
|
|
210
|
+
}]
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
chart.setOption(option); // setOption ALWAYS comes after event registration
|
|
214
|
+
});
|
|
215
|
+
</script>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Design quality rules:**
|
|
221
|
+
- Title font: `fontWeight: 'bold'`, `fontSize: 20–24` — no thin titles
|
|
222
|
+
- Grid lines: low opacity (0.06–0.10) — subordinate to data
|
|
223
|
+
- Bars: `barMaxWidth: 60`, rounded via `itemStyle.borderRadius: [4,4,0,0]`
|
|
224
|
+
- Lines: `smooth: true` for natural curves, `symbolSize: 8` for points
|
|
225
|
+
- Pie/doughnut: `label.formatter: '{b}\n{d}%'` for built-in on-slice labels
|
|
226
|
+
- Dark presets: grid `rgba(255,255,255,0.07)`, axis line/tick color `rgba(255,255,255,0.15)`
|
|
227
|
+
- Tooltip: `show: false` — static PNG, no hover interaction
|
|
228
|
+
- When no title provided: skip `.chart-header`, omit title from ECharts option
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Step 4: Self-QA (fix every failure before Step 5)
|
|
233
|
+
|
|
234
|
+
**Structure:**
|
|
235
|
+
- [ ] Container is a `<div>`, not `<canvas>`
|
|
236
|
+
- [ ] `window.__chartReady = false` declared before `document.fonts.ready`
|
|
237
|
+
- [ ] `chart.on('finished', ...)` registered BEFORE `chart.setOption()`
|
|
238
|
+
- [ ] `chart.on('rendered', ...)` debounce fallback registered BEFORE `chart.setOption()`
|
|
239
|
+
- [ ] `animation: false` in option object
|
|
240
|
+
- [ ] `chart.setOption(option)` is the LAST call in the init block
|
|
241
|
+
|
|
242
|
+
**Type-specific:**
|
|
243
|
+
- [ ] Area: `type: 'line'` + `areaStyle: {}` — no `type: 'area'`
|
|
244
|
+
- [ ] Doughnut: `type: 'pie'` + `radius: ['40%', '70%']` — no `type: 'doughnut'`
|
|
245
|
+
- [ ] Bar: `xAxis.type: 'category'` explicitly set
|
|
246
|
+
- [ ] Category data in `xAxis.data` (not `data.labels`)
|
|
247
|
+
- [ ] Pie/doughnut: body `padding: 64px 80px` + `.chart-container { max-height: 860px }`
|
|
248
|
+
- [ ] Highlight: per-item `{ value: N, itemStyle: { color } }` in data array
|
|
249
|
+
|
|
250
|
+
**Design:**
|
|
251
|
+
- [ ] All palette colors from `references/style-presets.md`
|
|
252
|
+
- [ ] Title states insight (not just subject)
|
|
253
|
+
- [ ] `tooltip: { show: false }` or omitted (no hover on static PNG)
|
|
254
|
+
- [ ] Dark preset: grid/axis colors use `rgba(255,255,255,...)`
|
|
255
|
+
- [ ] Source in footer if `source` param provided
|
|
256
|
+
- [ ] Data labels visible (built-in `label: { show: true }` on series)
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Step 5: Export
|
|
261
|
+
|
|
262
|
+
Determine slug from title or chart type + data context (kebab-case, ≤30 chars):
|
|
263
|
+
```bash
|
|
264
|
+
mkdir -p chart/[slug]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Save HTML: `chart/[slug]/chart.html`
|
|
268
|
+
|
|
269
|
+
Quick browser check:
|
|
270
|
+
```bash
|
|
271
|
+
open chart/[slug]/chart.html
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Run export (replace `[skill-root]` with actual path to this skill's directory):
|
|
275
|
+
```bash
|
|
276
|
+
bash [skill-root]/scripts/export-chart.sh \
|
|
277
|
+
chart/[slug]/chart.html \
|
|
278
|
+
chart/[slug]/chart.png \
|
|
279
|
+
--width [W] \
|
|
280
|
+
--height [H]
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
The script installs Playwright on first run (~200MB Chromium download), then captures the chart at `deviceScaleFactor: 2`.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Step 6: Output Summary
|
|
288
|
+
|
|
289
|
+
```
|
|
290
|
+
## Chart: [title]
|
|
291
|
+
Date: [YYYY-MM-DD] | Type: [chart_type] | Style: [style]
|
|
292
|
+
Dimensions: [W×H]px → PNG: [2W×2H]px @2× retina
|
|
293
|
+
|
|
294
|
+
Files
|
|
295
|
+
Source: chart/[slug]/chart.html
|
|
296
|
+
Output: chart/[slug]/chart.png
|
|
297
|
+
Size: [X] KB
|
|
298
|
+
|
|
299
|
+
Checklist
|
|
300
|
+
- [ ] Title states the insight clearly
|
|
301
|
+
- [ ] Data labels legible at display size
|
|
302
|
+
- [ ] Highlight visible on correct data point
|
|
303
|
+
- [ ] Source attribution present in footer
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Prompt Tips (show when user asks for guidance)
|
|
309
|
+
|
|
310
|
+
> "Provide structured data — JSON or CSV, not prose descriptions."
|
|
311
|
+
>
|
|
312
|
+
> "Name the chart type explicitly. 'bar chart comparing Q1–Q4' not 'a chart showing quarters'."
|
|
313
|
+
>
|
|
314
|
+
> "Specify the data story. 'highlight Q4 which outperformed all others' gives the annotation context."
|
|
315
|
+
>
|
|
316
|
+
> ✅ Good: "Create a line chart. Title: 'From $12k to $95k ARR in 12 Months'. Data: [12, 18, 22, 25, 31, 38, 44, 52, 61, 68, 78, 95] (Jan–Dec 2024). Highlight December. Source: Internal CRM. Style: electric-burst."
|
|
317
|
+
>
|
|
318
|
+
> ❌ Bad: "make a chart about our company growth"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "graphic-chart",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Create a line chart. Title: 'From $12k to $95k ARR in 12 Months'. Data: [12, 18, 22, 25, 31, 38, 44, 52, 61, 68, 78, 95] (Jan–Dec 2024, in thousands). Highlight December in gold. Source: Internal CRM. Style: terminal. Dimensions: 1080x1080.",
|
|
7
|
+
"expected_output": "type: 'line', animation: {duration: 0, onComplete: () => window.__chartReady = true}, chartjs-plugin-annotation CDN loaded after Chart.js (UMD auto-registers — no Chart.register call), annotation box on 'Dec' label with callout showing '95', electric-burst-style dark tokens applied (terminal mapped to electric-burst or midnight-editorial), title states growth story not just description, source shown in footer, no CSS on canvas element, deviceScaleFactor: 2 in export script → 2160×2160 output PNG."
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": 2,
|
|
11
|
+
"prompt": "Create a bar chart. Title: 'Q4 Outperformed Every Quarter'. Data: Q1=420, Q2=510, Q3=480, Q4=780. Highlight Q4. Style: electric-burst.",
|
|
12
|
+
"expected_output": "type: 'bar', borderRadius: 4 on dataset (non-negotiable), borderSkipped: false, annotation box xMin:'Q4' xMax:'Q4' with label callout, annotation CDN script loaded after Chart.js (UMD auto-registers — no Chart.register call), electric-burst tokens (Space Grotesk display, DM Sans body, #09090B bg, #FACC15 accent), window.__chartReady set in animation.onComplete, no animation: false, no CSS on canvas."
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": 3,
|
|
16
|
+
"prompt": "Create an area chart. Revenue by month: 5, 8, 12, 10, 15, 22, 28, 25, 32, 38, 45, 52. Style: clean-slate.",
|
|
17
|
+
"expected_output": "type: 'line' (NOT 'area'), fill: 'origin' on dataset, backgroundColor rgba at 0.15 opacity, NO annotation plugin loaded (no highlight param), clean-slate tokens (Plus Jakarta Sans, white bg, #3B82F6 accent), animation: {duration: 0, onComplete: ...} present, maintainAspectRatio: false, position: relative on container."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 4,
|
|
21
|
+
"prompt": "Create a pie chart. Market share: Product A 45%, Product B 28%, Product C 17%, Other 10%. Style: midnight-editorial.",
|
|
22
|
+
"expected_output": "type: 'pie', backgroundColor is palette array (not single color), legend position: 'right', NO chartjs-plugin-annotation script loaded (pie not supported), midnight-editorial tokens (Instrument Serif display, Inter body, #111111 bg, #D8F90A accent), 4 segments (under 7 max), hoverOffset: 6, no CSS on canvas."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": 5,
|
|
26
|
+
"prompt": "make a chart",
|
|
27
|
+
"expected_output": "chart_type AND data both missing. Does NOT read any reference files. Does NOT generate HTML. Asks exactly for both: chart type (bar/line/area/pie/doughnut/scatter/radar/treemap) and data (JSON or CSV). Waits for user response."
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|