aden-hive/hive.chart-creation-foundations
Required reading whenever any chart_* tool is available. Teaches the one-tool embedding contract (call chart_render → live chart appears in chat AND a downloadable PNG lands in the queen session dir), the ECharts (data viz) vs Mermaid (structural diagrams) decision, the BI/financial-grade aesthetic baseline (no chartjunk, restrained palette, proper typography, single message per chart), and the canonical spec patterns for the 12 most-common chart types. Skipping this leads to 1990s-Excel charts, missing downloads, and the agent writing markdown image links by hand instead of letting chart_render drive the UI.
npx skills add https://github.com/aden-hive/hive --skill hive.chart-creation-foundations
These tools render BI/financial-analyst-grade charts and diagrams that show up live in the chat AND save as high-DPI PNGs in the user's queen session dir.
> To put a chart in chat, call chart_render. The chat reads result.spec and renders the chart live in the message bubble. The download link is result.file_url. Do not write !chart image markdown by hand — the tool's result drives the UI.
That's it. One tool call, one chart in chat, one file on disk. No two-step "remember to also save it" pattern. The chat's chart-rendering UI is fed by the tool result envelope automatically.
Chart when the data is visual at heart: trends over time, distributions, comparisons across categories, hierarchies, flows, geo. Skip the chart when:
A chart costs the user attention. It must repay that cost with a takeaway they couldn't get from prose.
| Use ECharts (kind: "echarts") when... | Use Mermaid (kind: "mermaid") when... |
|---|---|
| You're plotting numbers over categories or time | You're showing structure, not data |
| Bar / line / area / scatter / candlestick / heatmap / treemap / sankey / parallel coordinates / calendar / gauge / pie / sunburst / geo map | Flowchart / sequence / gantt / ERD / state diagram / mindmap / class diagram / C4 architecture |
| The viewer's question is "how much / how many / what's the trend" | The viewer's question is "what calls what / what depends on what / what happens after what" |
If both fit (rare), prefer ECharts — its rasterized output is a proper data chart for slides; Mermaid's diagrams are for technical docs.
These are the rules that turn an Excel-default chart into a Tableau-grade one. Every chart you produce must follow them.
chart_render has no theme parameter. The renderer reads the user's UI theme from the desktop env (HIVE_DESKTOP_THEME) so the saved PNG matches what the user is actually looking at. You don't pick; the system does.option.title.text, NOT in the message body. The chart is self-contained.color on seriesThe OpenHive ECharts theme is auto-applied to every chart_render call. It defines:
grid.top: 90, grid.bottom: 56, etc.)Do not set option.color, option.title.textStyle, option.grid, or option.itemStyle.color on series. The theme covers it. If you do override, you'll fight the brand palette and the chart will look generic.
When you need data-encoded color (NOT category color):
visualMap with inRange.color: ['#fff7e0', '#db6f02'] (light-to-honey)visualMap with inRange.color: ['#a8453d', '#f5f5f5', '#3d7a4a'] (terracotta/neutral/sage)#3d7a4a (gain) and #a8453d (loss), NOT #27ae60 / #e74c3c.The default font (-apple-system, "Inter Tight", system-ui) is already wired in the renderer — don't override unless the user asked. Set option.textStyle.fontSize: 13 for body labels, 16 for axis names, 18 bold for the title.
option.yAxis.axisLabel.formatter: '{value} M' to add units, NOT a separate "USD millions" subtitle."2024-01-15") and ECharts handles the layout. Use xAxis.type: "time".Every chart goes in its own assistant message (or its own chart_render call). Do not pile 4 charts into one wall of tool calls — the user can't focus and the chat gets noisy.
chart_render — the canonical patternchart_render(
kind="echarts",
spec={
"title": {"text": "Q4 revenue by region", "left": "center"},
"tooltip": {"trigger": "axis"},
"xAxis": {"type": "category", "data": ["NA", "EU", "APAC", "LATAM"]},
"yAxis": {"type": "value", "axisLabel": {"formatter": "${value}M"}},
"series": [{"type": "bar", "data": [12.4, 8.7, 5.3, 2.1], "itemStyle": {"color": "#db6f02"}}]
},
title="q4-revenue-by-region",
width=1600, height=900, dpi=300
)
Returns:
{
"kind": "echarts",
"spec": {...echoed...},
"file_path": "/.../charts/2026-04-30T...q4-revenue-by-region.png",
"file_url": "file:///.../q4-revenue-by-region.png",
"width": 1600, "height": 900, "dpi": 300, "bytes": 142318,
"title": "q4-revenue-by-region", "runtime_ms": 287
}
The chat panel reads result.spec and mounts ECharts in the message bubble. The user sees the chart immediately. The PNG is on disk and the chat shows a download link from result.file_url. You don't write that link — it appears automatically.
| When | ECharts type | Notes |
|---|---|---|
| Trend over time | series.type: "line" | Smooth = smooth: true only when data is noisy |
| Multi-metric trend | Two line series with yAxis: [{}, {}] | Separate scales when units differ |
| Category comparison | series.type: "bar" | Sort by value descending, not alphabetically |
| Stacked composition | bar with stack: "total" | Cap at 5 categories |
| Distribution | series.type: "boxplot" or bar of bins | Boxplot for ≥3 groups; histogram for one |
| Two-variable correlation | series.type: "scatter" | Add regression markline if relevant |
| Candlestick / OHLC | series.type: "candlestick" | Date axis + dataZoom range slider |
| Geo distribution | series.type: "map" | Bundled world and country GeoJSONs |
| Hierarchy / share | series.type: "treemap" or sunburst | Use treemap for >12 leaves; pie only for 2-5 |
| Flow | series.type: "sankey" | Names matter — keep them short |
| Calendar density | series.type: "heatmap" + calendar | Daily metrics over a year |
| KPI scorecard | series.type: "gauge" | Set min, max, threshold band |
Worked specs for each are in references/ — paste, modify, render.
chart_render(
kind="mermaid",
spec="""
flowchart LR
A[Customer signs up] --> B{Onboarded?}
B -- yes --> C[Activate trial]
B -- no --> D[Email reminder]
""",
title="signup-flow"
)
flowchart LR for left-to-right; TD for top-down. LR reads better in a chat bubble.->> (open arrow) and sync return with -->> (dashed).!chart markdown by hand. Don't. The chat renders from the tool result automatically. Manual image markdown will display nothing (file:// is blocked from arbitrary chat content).axisLabel.formatter for currency / percentage. A y-axis showing "12000000" is unreadable; "12M" is correct.option.title.text instead so the title is part of the saved PNG.Take aden-hive/hive.chart-creation-foundations from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.