Skip to content
Back to skills

Metrics Chart

BSecurity

Render Axiom metrics query results (application/vnd.metrics.v3+json) as line charts. Zero-dependency Unicode/ASCII by default; upgrades to inline PNG/SVG/sixel via gnuplot when present. Use when you have a metrics v3 query response and want to see the series as a chart in the terminal or transcript.

  • 3 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 2, 2026
ai-agentspythongobashnodeawsapibackend

Works with

  • terminal
  • api

Security analysis

B80/100
  • criticalDownloads and executes remote scripts — classic supply chain attack
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 8 files and shows the line behind each finding

Scanned September 2, 2026

npx -y skills add nuroctane/nur-cli --skill metrics-chart --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Metrics Chart?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Metrics Chart
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/nuroctane-metrics-chart/badge)](https://www.skillsdirectory.com/skills/nuroctane-metrics-chart)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: metrics-chart
description: Render Axiom metrics query results (application/vnd.metrics.v3+json) as line charts. Zero-dependency Unicode/ASCII by default; upgrades to inline PNG/SVG/sixel via gnuplot when present. Use when you have a metrics v3 query response and want to see the series as a chart in the terminal or transcript.
---

# metrics-chart

Turns a metrics query response into a **multi-series line chart**.

Input is exactly the body the Axiom metrics query service returns for
`application/vnd.metrics.v3+json` — defined in the metrics query service
(`service/query`, `JsonV3QueryResponse` in `src/server.rs`). It is a
regularly-sampled, multi-series time series; this skill draws it.

## TL;DR

```bash
# From a file, stdout picks the best renderer for your terminal:
python3 scripts/metrics_chart.py response.json

# From a pipe (e.g. straight off the query API):
curl ... -H 'Accept: application/vnd.metrics.v3+json' | python3 scripts/metrics_chart.py

# Force a zero-dependency ASCII chart (always works, anywhere):
python3 scripts/metrics_chart.py --format ascii response.json
```

> **Aggregate first.** Charts are only readable with a *handful* of series.
> The cleanest result comes from a query that already groups/aggregates to a few
> lines (e.g. `group by status` rather than per-`pod`). This skill's series
> reduction (below) is a safety net for high-cardinality results, **not** a
> substitute for aggregating in the query.

## Input format (vnd.metrics.v3+json)

```json
{
  "metadata": {
    "group_keys": ["code", "method"],
    "warnings": [],
    "unit": "ms",
    "custom_unit": "millisec"
  },
  "series": [
    {
      "metric": "http_requests",
      "tags": { "code": 200, "method": "GET", "path": "/" },
      "start": 1750753164,
      "resolution": 60,
      "data": [420.0, 42.0, 30.0, 9.0, 15.0, 18.0]
    }
  ]
}
```

| Field                 | Meaning                                                                 |
| --------------------- | ----------------------------------------------------------------------- |
| `metadata.group_keys` | Tags the query grouped on → used to build legend labels.                |
| `metadata.warnings`   | Shown as `⚠` captions under the chart.                                  |
| `metadata.unit`       | Canonical y-axis unit (`ms`, `bytes`, …).                               |
| `metadata.custom_unit`| Human y-axis label; preferred over `unit` when present.                 |
| `series[].start`      | Unix **seconds** (UTC) of `data[0]`.                                    |
| `series[].resolution` | **Seconds** per point; `x[i] = start + resolution*i` (uniform spacing). |
| `series[].data`       | Y values; **`null` = gap** (the line breaks, it is not drawn as 0).     |

The parser also accepts v2/v2a (same shape with an extra per-series `summary`,
ignored) and the v0/v1 bare-array form, so you can feed older responses too.

## Behaviour

- **Labels** come from `group_keys` values joined with ` | ` → `200 | GET`
  (not `code=200,method=GET`). Without `group_keys`, falls back to `k=v` tags.
- **Local time** axis by default; `--tz UTC` or `--tz Europe/Berlin` to override.
- **Gaps**: `null` points break the line.
- **Series reduction** (unless `--all`), in order:
  1. **Collapse overlapping** series whose lines essentially coincide (within
     `--eps`, default 2% of the y-range); the most prominent is kept.
  2. **Top-N** by peak value (`--top`, default 8).
  3. The legend prints **how many were dropped**, e.g.
     `showing 8 of 30 series (5 overlapping, 17 low/hidden)`, plus the
     aggregate-your-query tip.

## Output formats

`--format auto` (default) picks the best renderer for the context:

- an **inline image** when `gnuplot` is installed and the terminal supports
  images (Kitty/Ghostty, iTerm2);
- a **PNG file plus a "display this file" instruction** when output is
  piped/captured (e.g. an AI agent harness) and `gnuplot` is installed — the
  agent then displays the file;
- **ASCII** in a plain terminal, or whenever `gnuplot` is unavailable.

Force a specific backend with `--format`:

| `--format` | Needs     | Output                                                        |
| ---------- | --------- | ------------------------------------------------------------- |
| `auto`     | —         | inline image, else a PNG file + display instruction when piped, else ASCII |
| `ascii`    | nothing   | Unicode braille line chart; renders in any terminal/transcript/CI log. |
| `png`      | gnuplot   | PNG; displayed inline (Kitty/iTerm2) or written to `--output`/temp. |
| `svg`      | gnuplot   | SVG written to `--output` or a temp file (path printed).      |
| `sixel`    | gnuplot   | sixel stream to stdout (terminals with sixel support).        |

If an image format is requested but `gnuplot` is missing, it prints a note and
falls back to ASCII — it never hard-fails.

## Using from an AI agent / harness

Terminal harnesses (e.g. pi) collapse tool output and don't repaint inline
ANSI, so ASCII charts come out monochrome and folded. **Prefer images:** render
a file and let the agent display it. With `--format auto` (the default) this is
automatic whenever output is piped and `gnuplot` is installed — the skill
writes a PNG and prints:

```
metrics-chart: wrote image to /tmp/metrics-chart-XXXX.png
→ Display this file to the user with your image tool (e.g. read it); do not paste its contents.
```

The agent should then **display that file** (its image/`read` tool renders it
inline, in colour, un-folded). To control the path, pass `--output chart.png`.
Do not paste the PNG bytes or the ASCII into chat.

## Options

| Flag                | Default | Meaning                                            |
| ------------------- | ------- | -------------------------------------------------- |
| `--format`          | `auto`  | `auto`/`ascii`/`png`/`svg`/`sixel`.                |
| `--tz NAME`         | local   | IANA tz for the x-axis; `UTC` for UTC.             |
| `--top N`           | `8`     | Max series after collapse; must be >= 1.           |
| `--eps F`           | `0.02`  | Overlap threshold as a fraction of the y-range.    |
| `--all`             | off     | Draw every series (disable collapse + top-N).      |
| `--width` / `--height` | auto | Chart size (cells for ASCII, pixels for images).   |
| `--title TEXT`      | —       | Chart title.                                       |
| `--output PATH`     | —       | Write png/svg to PATH instead of a temp file.      |
| `--color` / `--no-color` | auto | Force ANSI colour on/off (default: on when a TTY). |

## Dependencies

- **Default path: none.** Pure Python 3.9+ standard library. The ASCII renderer
  always works.
- **Optional: `gnuplot`** (one system binary) for PNG/SVG/sixel. Install only if
  you want high-fidelity images.

## Why not graphviz?

`graphviz` (`dot`/`neato`) lays out node-edge graphs; it has no numeric/time
axis and cannot plot `data[i]` over time. This payload is a numeric time series
with no graph structure, so graphviz does not apply. `gnuplot` is the correct
image backend. (matplotlib is avoided on purpose: it is a heavy multi-package
pip install.)

## Tests

```bash
cd scripts && python3 -m unittest test_metrics_chart -v
```

The parser tests are pinned to the golden bytes from the metrics query
service's `service/query/src/server/tests.rs`.

Files in this skill

  • .gitignore19 B
  • README.md3.3 KB
  • SKILL.md7.3 KB
  • examples/v3_gaps.json166 B
  • examples/v3_golden.json427 B
  • examples/v3_many.json9.5 KB
  • scripts/metrics_chart.py26.1 KB
  • scripts/test_metrics_chart.py18.8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.