agentleFS
ethosagentethosagent/ethos/skills/document/charts/SKILL.md

charts

Skill22 starsChanged 9 days agoMITView on GitHub

Show data as an interactive chart inline in chat by emitting a fenced ```echarts block containing a single pure-JSON ECharts option object. No tools, no files, no install — the chart is the message. Supports bar, line, pie, scatter, and heatmap series against the echarts@1 spec. Surfaces that cannot render it show the JSON as a code block.

8 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use aminer-data-search, auto-target-tracker and 10 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • dav-niu474Skill

    aminer-data-search

    使用 AMiner 开放平台 API 进行学术数据查询与分析。当用户需要查询学者信息、论文详情、机构数据、期刊内容或专利信息时使用此 skill。 触发场景:提到 AMiner、学术数据查询、查论文/学者/机构/期刊/专利、学术问答搜索、引用分析、科研机构分析、学者画像、论文引用链、期刊投稿分析等。 支持 6 大组合工作流(学者全景分析、论文深度挖掘、机构研究力分析、期刊论文监控、学术智能问答、专利链分析)以及 28 个独立 API 的直接调用。 即使用户只说"帮我查一下 XXX 学者"或"找找关于 XXX 的论文",也应主动使用此 skill。

    Also in 3 projects that use this

  • dav-niu474Skill

    auto-target-tracker

    自动目标进度追踪器。在对话中检测到目标相关图片(笔记、进度、截图、记录)时,自动调用 VLM 识别关键信息并记录到目标日记。适用于学习管理、健身追踪、工作进度、习惯养成、创作记录等所有目标管理场景。

    Also in 3 projects that use this

  • Liang-MHSkill

    stock_analysis

    获取 A 股、基金和港股的实时行情和技术分析数据

    Also in 3 projects that use this

  • +9 more from dav-niu474

The file

We split this skill into the rules it gives an agent

7 rules. 0 are common, 4 are distinctive, and 3 are very specific to this project.

  • 0

    Common

    Most of the 8 edited versions we read keep these.

  • 4

    Distinctive

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    The recipient needs a file or an image: Use make-chart (Vega-Lite → PNG) — see the comparison below.

    line 42
  2. Distinctive:

    The data has no clear chart type: Ask the user which view they want before emitting anything.

    line 44
  3. Very specific:

    No JavaScript anywhere: No functions, no expressions, no data.url or any other remote fetch.

    line 71
  4. Distinctive:

    If the user might want both, say so and ask — do not emit a fence and a PNG for the same data by default.

    line 177
  5. Distinctive:

    Do not put a function in the JSON: Not as a value, not as a string that looks like one.

    line 181
  6. Distinctive:

    Only the spec-1 keys and series types above.

    line 192
  7. Very specific:

    Every spec sets title.text.

    line 193

“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Charts

Show data as an interactive chart inline in the conversation. Emit one fenced ```echarts block containing a single pure-JSON ECharts option object. No tools, no files, no install — the fence is the deliverable.

When to use this skill

  • A comparison across categories (revenue by region, errors by service).
  • A trend over time (weekly signups, latency across releases).
  • A distribution or relationship (score histogram, price vs. rating).
  • The user says "chart this", "plot this", "show me a graph", "visualise this".

Chart when the shape is the point — when seeing it answers a question that reading the numbers does not.

When NOT to use this skill

  • Two or three numbers. State them in a sentence. A chart of three bars is a table with extra steps.
  • The recipient needs a file or an image. Use make-chart (Vega-Lite → PNG) — see the comparison below.
  • The data is a lookup, not a shape. Exact values people will read one at a time belong in a markdown table.
  • The data has no clear chart type. Ask the user which view they want before emitting anything.

The fence

One fenced block, language tag echarts, body is a single JSON object — the ECharts option. Nothing else inside the fence: no comments, no trailing text, no second object.

```echarts
{ "title": { "text": "Errors by service" }, "xAxis": { "type": "category", "data": ["auth", "api"] }, "yAxis": { "type": "value" }, "series": [{ "type": "bar", "data": [12, 31] }] }
```

Introduce it in one line of prose before the fence ("Revenue by region:") so the message reads correctly on surfaces that show the JSON instead of the chart.

Spec 1 — the contract

echarts@1 is the subset below. It is a contract, not a suggestion: a surface renders only what the spec allows, and strips or falls back on the rest.

AllowedValues
Series typesbar, line, pie, scatter, heatmap
Datadataset (preferred — dataset.source as an array of rows or objects) or inline series[].data
Top-level keysdataset, series, xAxis, yAxis, tooltip, legend, title, grid, color, visualMap
StylingPlain JSON values only — strings, numbers, booleans, arrays, objects

heatmap requires visualMap. It is the only series type that does: the colour scale is the value axis, so a heatmap without one draws a monochrome grid. Set visualMap.min / visualMap.max to the data's range. Every other series type ignores visualMap — omit it.

No JavaScript anywhere. No functions, no expressions, no data.url or any other remote fetch. Formatter callbacks are not spec 1. If you need label formatting, use ECharts' plain-string template form ("{b}: {c}") — that is a JSON string, not code.

Pure JSON is exactly what makes the block safely renderable: the surface runs JSON.parse on the fence body and hands the result to its own charting library. It never evaluates it. A spec containing anything that is not data is not rendered — it degrades to a code block.

Spec versions are ours, not npm's. echarts@1 names the Ethos spec version — this documented subset — not the ECharts package version. The surface pins its own library version and may upgrade it without any skill changing. Spec versions are small integers: there is no echarts@1.1. A new subset is echarts@2.

Sizing

Omit fixed pixel sizes. No width, no height, no hard-coded px in grid. The surface owns layout and resizes the chart to its container; a fixed size fights it. Percentages and "containLabel": true in grid are fine.

Examples

Bar — complete. Two series, dataset rows, legend, tooltip:

```echarts
{
  "title": { "text": "Revenue by region — Q1 vs Q2 2026" },
  "dataset": {
    "source": [
      ["region", "Q1", "Q2"],
      ["North", 128000, 141000],
      ["South", 94000, 102500],
      ["East", 156000, 149000],
      ["West", 88000, 117000]
    ]
  },
  "xAxis": { "type": "category" },
  "yAxis": { "type": "value", "name": "USD" },
  "tooltip": { "trigger": "axis" },
  "legend": {},
  "grid": { "containLabel": true },
  "series": [
    { "type": "bar", "name": "Q1" },
    { "type": "bar", "name": "Q2" }
  ]
}
```

Line — minimal. Inline data, one series:

```echarts
{
  "title": { "text": "Weekly active users" },
  "xAxis": { "type": "category", "data": ["W1", "W2", "W3", "W4", "W5"] },
  "yAxis": { "type": "value" },
  "series": [{ "type": "line", "name": "Active users", "data": [820, 932, 901, 1290, 1330] }]
}
```

Heatmap — with its required visualMap. Both axes are categories; each data point is [xIndex, yIndex, value]:

```echarts
{
  "title": { "text": "Deploys by weekday and hour — last 30 days" },
  "xAxis": { "type": "category", "data": ["Mon", "Tue", "Wed", "Thu", "Fri"] },
  "yAxis": { "type": "category", "data": ["09:00", "13:00", "17:00"] },
  "tooltip": {},
  "grid": { "containLabel": true },
  "visualMap": {
    "min": 0,
    "max": 12,
    "calculable": true,
    "orient": "horizontal",
    "left": "center",
    "bottom": 0
  },
  "series": [
    {
      "type": "heatmap",
      "name": "Deploys",
      "data": [
        [0, 0, 2], [0, 1, 5], [0, 2, 1],
        [1, 0, 3], [1, 1, 8], [1, 2, 4],
        [2, 0, 1], [2, 1, 12], [2, 2, 6],
        [3, 0, 4], [3, 1, 9], [3, 2, 3],
        [4, 0, 2], [4, 1, 4], [4, 2, 0]
      ]
    }
  ]
}
```

Graceful degradation

A surface that cannot render the fence — CLI, Telegram, email, an older client — shows the JSON as a code block. That is the designed fallback, not a failure. Write every spec so it survives it:

  • Always set title.text. It is the one line that tells a reader what they are looking at.
  • Keep specs small. A screenful of data points, not a thousand. Large inline arrays are unreadable as text and slow to render.
  • Name things. series[].name, yAxis.name, and dataset header rows make the raw JSON self-describing.

charts vs make-chart

Complementary, not competing. Both are current.

Use chartsUse make-chart
Interactive chat surfaces (web, desktop)The recipient needs a PNG or a file on disk
The chart is the message — inline, no artifactsEmail, or any non-interactive surface
Zero tools, one turnThe image goes into a document, report, or attachment

If the user might want both, say so and ask — do not emit a fence and a PNG for the same data by default.

Anti-patterns

  • Do not put a function in the JSON. Not as a value, not as a string that looks like one. It will be stripped or the whole block will fall back.
  • Do not set width or height. The surface sizes the chart.
  • Do not use data.url, an image://… icon, or any other remote reference. All data is inline; remote-fetching strings are stripped.
  • Do not emit more than one JSON object per fence, and do not wrap the option in an extra key.
  • Do not use a series type outside spec 1. Unknown types do not render.
  • Do not chart three numbers. Say them.

Hard rules

  • The fence language tag is exactly echarts.
  • The fence body is one JSON object and nothing else — it must satisfy JSON.parse.
  • Only the spec-1 keys and series types above.
  • Every spec sets title.text.
  • Data is always inline. Never a URL, never a file path.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.