Back to skills
SkillHub ClubAnalyze Data & AIFull StackBackendData / AI

chart-splat

Generate beautiful charts via the Chart Splat API. Use when the user asks to create, generate, or visualize data as charts, graphs, or plots. Supports line, bar, pie, doughnut, radar, polar area, and candlestick/OHLC charts. Returns PNG images.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,127
Hot score
99
Updated
March 19, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
B71.9

Install command

npx @skill-hub/cli install openclaw-skills-chart-splat

Repository

openclaw/skills

Skill path: skills/bobbyg603/chart-splat

Generate beautiful charts via the Chart Splat API. Use when the user asks to create, generate, or visualize data as charts, graphs, or plots. Supports line, bar, pie, doughnut, radar, polar area, and candlestick/OHLC charts. Returns PNG images.

Open repository

Best for

Primary workflow: Analyze Data & AI.

Technical facets: Full Stack, Backend, Data / AI.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install chart-splat into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding chart-splat to shared team environments
  • Use chart-splat for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: chart-splat
description: Generate beautiful charts via the Chart Splat API. Use when the user asks to create, generate, or visualize data as charts, graphs, or plots. Supports line, bar, pie, doughnut, radar, polar area, and candlestick/OHLC charts. Returns PNG images.
version: 1.1.0
license: MIT
compatibility: Requires Node.js and npx with network access to api.chartsplat.com
metadata:
  author: workingdevshero
  version: "1.1.0"
  homepage: https://chartsplat.com
  openclaw:
    requires:
      env:
        - CHARTSPLAT_API_KEY
      bins:
        - node
        - npx
    primaryEnv: CHARTSPLAT_API_KEY
    emoji: "bar-chart"
    homepage: https://chartsplat.com
    os:
      - darwin
      - linux
      - win32
    install:
      - kind: node
        package: chartsplat-cli
        bins: [chartsplat]
        label: "Install Chart Splat CLI via npm"
---

# Chart Splat

Generate beautiful charts from data using the Chart Splat API. Charts are rendered server-side with Chart.js and returned as PNG images.

## Supported Chart Types

| Type | Best For |
|------|----------|
| `line` | Trends over time |
| `bar` | Comparing categories |
| `pie` | Parts of a whole |
| `doughnut` | Parts of a whole (with center space) |
| `radar` | Multivariate comparison |
| `polarArea` | Comparing categories with radial layout |
| `candlestick` | Financial/crypto OHLC price data |
| `ohlc` | Financial/crypto OHLC price data (bar variant) |

## Method 1: CLI (Preferred)

Use the `chartsplat` CLI via npx. No install required.

```bash
npx -y chartsplat-cli bar \
  --labels "Q1,Q2,Q3,Q4" \
  --data "50,75,60,90" \
  --title "Quarterly Revenue" \
  --color "#8b5cf6" \
  -o chart.png
```

### CLI Options

| Flag | Description |
|------|-------------|
| `-l, --labels <csv>` | Comma-separated labels |
| `-d, --data <csv>` | Comma-separated numeric values |
| `-t, --title <text>` | Chart title |
| `--label <text>` | Dataset label for legend |
| `-c, --color <hex>` | Background color |
| `-w, --width <px>` | Image width (default: 800) |
| `--height <px>` | Image height (default: 600) |
| `-o, --output <file>` | Output file path (default: chart.png) |
| `--config <file>` | JSON config file for complex charts |

### CLI Chart Commands

```bash
npx -y chartsplat-cli line -l "Mon,Tue,Wed,Thu,Fri" -d "100,200,150,300,250" -o line.png
npx -y chartsplat-cli bar -l "A,B,C" -d "10,20,30" -o bar.png
npx -y chartsplat-cli pie -l "Red,Blue,Green" -d "30,50,20" -o pie.png
npx -y chartsplat-cli doughnut -l "Yes,No,Maybe" -d "60,25,15" -o doughnut.png
npx -y chartsplat-cli radar -l "Speed,Power,Range,Durability,Precision" -d "80,90,70,85,95" -o radar.png
npx -y chartsplat-cli polararea -l "N,E,S,W" -d "40,30,50,20" -o polar.png
npx -y chartsplat-cli candlestick --config ohlc.json -o chart.png
```

### Candlestick Charts

Candlestick and OHLC charts require a JSON config file since the data format is more complex than a simple CSV list. Use `--config` to provide a file with OHLC data points.

```bash
npx -y chartsplat-cli candlestick --config ohlc.json -o candlestick.png
```

Config format (`ohlc.json`):

```json
{
  "type": "candlestick",
  "data": {
    "datasets": [{
      "label": "VVV Price",
      "data": [
        { "x": 1740441600000, "o": 4.23, "h": 4.80, "l": 4.10, "c": 4.45 },
        { "x": 1740528000000, "o": 4.45, "h": 5.50, "l": 4.30, "c": 5.34 },
        { "x": 1740614400000, "o": 5.34, "h": 6.20, "l": 5.10, "c": 5.97 }
      ]
    }]
  }
}
```

Each OHLC data point requires: `x` (numeric timestamp in ms, or a date string like `"2025-02-25"`), `o` (open), `h` (high), `l` (low), `c` (close).

### Complex Charts via Config File

For multi-dataset or customized charts, write a JSON config file then pass it to the CLI:

```bash
npx -y chartsplat-cli bar --config chart-config.json -o chart.png
```

See [examples/sample-charts.json](examples/sample-charts.json) for config file examples and [references/api-reference.md](references/api-reference.md) for the full config schema.

## Method 2: Helper Script

Use the bundled script for quick generation without installing the CLI:

```bash
node scripts/generate-chart.js bar "Q1,Q2,Q3,Q4" "50,75,60,90" "Revenue" chart.png
```

Or with a config file:

```bash
node scripts/generate-chart.js --config chart-config.json -o chart.png
```

## Output Handling

- Charts are saved as PNG files to the specified output path
- Default output is `chart.png` in the current directory
- For messaging platforms (Discord, Slack), return the file path: `MEDIA: /path/to/chart.png`
- The CLI and helper script handle base64 decoding automatically

## Error Handling

| Error | Cause | Fix |
|-------|-------|-----|
| `API key required` | Missing `CHARTSPLAT_API_KEY` | Set the env var in agent config |
| `Invalid API key` | Wrong or revoked key | Generate a new key at chartsplat.com/dashboard |
| `Rate limit exceeded` | Monthly quota reached | Upgrade plan or wait for reset |
| `Invalid chart configuration` | Bad request payload | Check that `data.labels` and `data.datasets` are present (candlestick/ohlc only require `data.datasets`) |

## Tips

- Always provide both `labels` and `data` arrays of the same length
- Use hex colors (e.g., `#8b5cf6`) for consistent styling
- For pie/doughnut charts, use an array of colors for `backgroundColor` to color each segment
- Default dimensions (800x600) work well for most uses; increase for presentations
- The `--config` flag accepts any valid Chart.js configuration for full customization


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### examples/sample-charts.json

```json
{
  "examples": [
    {
      "name": "Simple Bar Chart",
      "description": "Basic bar chart with single dataset",
      "config": {
        "type": "bar",
        "data": {
          "labels": ["Q1", "Q2", "Q3", "Q4"],
          "datasets": [
            {
              "label": "Revenue ($K)",
              "data": [50, 75, 60, 90],
              "backgroundColor": "#8b5cf6"
            }
          ]
        },
        "options": {
          "width": 800,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Quarterly Revenue" }
          }
        }
      }
    },
    {
      "name": "Line Chart with Trend",
      "description": "Line chart showing a time series",
      "config": {
        "type": "line",
        "data": {
          "labels": ["Jan", "Feb", "Mar", "Apr", "May", "Jun"],
          "datasets": [
            {
              "label": "Users",
              "data": [120, 190, 300, 500, 780, 1200],
              "borderColor": "#3b82f6",
              "fill": false
            }
          ]
        },
        "options": {
          "width": 800,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "User Growth" }
          }
        }
      }
    },
    {
      "name": "Multi-Dataset Bar Chart",
      "description": "Grouped bar chart comparing two years",
      "config": {
        "type": "bar",
        "data": {
          "labels": ["Q1", "Q2", "Q3", "Q4"],
          "datasets": [
            {
              "label": "2024",
              "data": [50, 75, 60, 90],
              "backgroundColor": "#8b5cf6"
            },
            {
              "label": "2025",
              "data": [65, 80, 70, 95],
              "backgroundColor": "#3b82f6"
            }
          ]
        },
        "options": {
          "width": 800,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Year-over-Year Revenue" }
          }
        }
      }
    },
    {
      "name": "Pie Chart",
      "description": "Pie chart showing market share",
      "config": {
        "type": "pie",
        "data": {
          "labels": ["Chrome", "Safari", "Firefox", "Edge", "Other"],
          "datasets": [
            {
              "data": [65, 18, 7, 5, 5],
              "backgroundColor": ["#8b5cf6", "#3b82f6", "#ef4444", "#10b981", "#f59e0b"]
            }
          ]
        },
        "options": {
          "width": 600,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Browser Market Share" }
          }
        }
      }
    },
    {
      "name": "Doughnut Chart",
      "description": "Doughnut chart showing budget allocation",
      "config": {
        "type": "doughnut",
        "data": {
          "labels": ["Engineering", "Marketing", "Sales", "Operations"],
          "datasets": [
            {
              "data": [40, 25, 20, 15],
              "backgroundColor": ["#6366f1", "#ec4899", "#f59e0b", "#10b981"]
            }
          ]
        },
        "options": {
          "width": 600,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Budget Allocation" }
          }
        }
      }
    },
    {
      "name": "Radar Chart",
      "description": "Radar chart comparing skill profiles",
      "config": {
        "type": "radar",
        "data": {
          "labels": ["Frontend", "Backend", "DevOps", "Design", "Testing"],
          "datasets": [
            {
              "label": "Alice",
              "data": [90, 70, 60, 80, 75],
              "borderColor": "#8b5cf6",
              "backgroundColor": "rgba(139, 92, 246, 0.2)"
            },
            {
              "label": "Bob",
              "data": [60, 95, 80, 40, 85],
              "borderColor": "#3b82f6",
              "backgroundColor": "rgba(59, 130, 246, 0.2)"
            }
          ]
        },
        "options": {
          "width": 600,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Developer Skill Comparison" }
          }
        }
      }
    },
    {
      "name": "Polar Area Chart",
      "description": "Polar area chart showing category scores",
      "config": {
        "type": "polarArea",
        "data": {
          "labels": ["Speed", "Reliability", "Comfort", "Safety", "Efficiency"],
          "datasets": [
            {
              "data": [85, 90, 70, 95, 80],
              "backgroundColor": [
                "rgba(139, 92, 246, 0.7)",
                "rgba(59, 130, 246, 0.7)",
                "rgba(16, 185, 129, 0.7)",
                "rgba(239, 68, 68, 0.7)",
                "rgba(245, 158, 11, 0.7)"
              ]
            }
          ]
        },
        "options": {
          "width": 600,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "Vehicle Ratings" }
          }
        }
      }
    },
    {
      "name": "Candlestick Chart",
      "description": "OHLC candlestick chart for financial/crypto data",
      "config": {
        "type": "candlestick",
        "data": {
          "datasets": [{
            "label": "VVV Price",
            "data": [
              { "x": 1740441600000, "o": 4.23, "h": 4.80, "l": 4.10, "c": 4.45 },
              { "x": 1740528000000, "o": 4.45, "h": 5.50, "l": 4.30, "c": 5.34 },
              { "x": 1740614400000, "o": 5.34, "h": 6.20, "l": 5.10, "c": 5.97 }
            ]
          }]
        },
        "options": {
          "width": 800,
          "height": 600,
          "plugins": {
            "title": { "display": true, "text": "VVV Price History" }
          }
        }
      }
    }
  ]
}

```

### references/api-reference.md

```markdown
# Chart Splat API Reference

## Endpoint

```
POST https://api.chartsplat.com/chart
```

## Authentication

Include your API key using one of these headers:

```
X-Api-Key: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEY
```

API keys start with `cs_` and are managed at [chartsplat.com/dashboard/api-keys](https://chartsplat.com/dashboard/api-keys).

## Request Body

```json
{
  "type": "bar",
  "data": {
    "labels": ["Jan", "Feb", "Mar"],
    "datasets": [
      {
        "label": "Revenue",
        "data": [12, 19, 3],
        "backgroundColor": "#8b5cf6",
        "borderColor": "#6366f1",
        "borderWidth": 1,
        "fill": false
      }
    ]
  },
  "options": {
    "width": 800,
    "height": 600,
    "plugins": {
      "title": { "display": true, "text": "Monthly Revenue" }
    },
    "scales": {
      "y": { "beginAtZero": true }
    }
  }
}
```

### Fields

| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `type` | string | No | `line` | Chart type: `line`, `bar`, `pie`, `doughnut`, `radar`, `polarArea`, `candlestick`, `ohlc` |
| `data.labels` | string[] | Yes* | - | Labels for X-axis or chart segments (*optional for candlestick/ohlc) |
| `data.datasets` | object[] | Yes | - | Array of datasets (see below) |
| `options.width` | integer | No | 800 | Image width in pixels (100-4000) |
| `options.height` | integer | No | 600 | Image height in pixels (100-4000) |
| `options.plugins` | object | No | - | Chart.js plugin configuration |
| `options.scales` | object | No | - | Chart.js scale configuration |

### Dataset Fields

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `data` | number[] or OhlcDataPoint[] | Yes | Numeric data points, or OHLC objects for candlestick/ohlc charts |
| `label` | string | No | Dataset label shown in legend |
| `backgroundColor` | string or string[] | No | Fill color(s) in hex or rgba |
| `borderColor` | string or string[] | No | Border/line color(s) |
| `borderWidth` | number | No | Border width in pixels |
| `fill` | boolean | No | Fill area under line charts |

### OHLC Data Point (for candlestick/ohlc charts)

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `x` | number or string | Yes | Timestamp (ms) or date string (e.g., `"2025-02-25"`) |
| `o` | number | Yes | Open price |
| `h` | number | Yes | High price |
| `l` | number | Yes | Low price |
| `c` | number | Yes | Close price |

## Response

### Success (200)

```json
{
  "image": "data:image/png;base64,iVBORw0KGgo...",
  "format": "png",
  "width": 800,
  "height": 600
}
```

### Rate Limit Headers

All responses include:

| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Monthly request limit |
| `X-RateLimit-Remaining` | Requests remaining this month |
| `X-RateLimit-Reset` | When the limit resets (ISO 8601) |

### Errors

| Status | Error | Description |
|--------|-------|-------------|
| 400 | `Request body is required` | Empty request |
| 400 | `Invalid JSON in request body` | Malformed JSON |
| 400 | `Invalid chart configuration` | Missing `data.labels` or `data.datasets` (candlestick/ohlc only require `data.datasets`) |
| 401 | `API key required` | No API key provided |
| 401 | `Invalid API key` | Key not found or revoked |
| 429 | `Rate limit exceeded` | Monthly quota reached |
| 500 | `Chart generation failed` | Server-side rendering error |

### Rate Limit Error Response

```json
{
  "error": "Rate limit exceeded",
  "message": "You have used 100 of 100 requests this month.",
  "limit": 100,
  "used": 100,
  "plan": "free"
}
```

## Rate Limits by Plan

| Plan | Requests/Month | API Keys |
|------|----------------|----------|
| Free | 100 | 1 |
| Pro | 10,000 | 5 |
| Enterprise | Unlimited | Unlimited |

## Multi-Dataset Example

```json
{
  "type": "bar",
  "data": {
    "labels": ["Q1", "Q2", "Q3", "Q4"],
    "datasets": [
      {
        "label": "2024",
        "data": [50, 75, 60, 90],
        "backgroundColor": "#8b5cf6"
      },
      {
        "label": "2025",
        "data": [65, 80, 70, 95],
        "backgroundColor": "#3b82f6"
      }
    ]
  },
  "options": {
    "plugins": {
      "title": { "display": true, "text": "Year-over-Year Revenue" }
    }
  }
}
```

## Candlestick Chart Example

```json
{
  "type": "candlestick",
  "data": {
    "datasets": [
      {
        "label": "Price",
        "data": [
          { "x": 1740441600000, "o": 4.23, "h": 4.80, "l": 4.10, "c": 4.45 },
          { "x": 1740528000000, "o": 4.45, "h": 5.50, "l": 4.30, "c": 5.34 },
          { "x": 1740614400000, "o": 5.34, "h": 6.20, "l": 5.10, "c": 5.97 }
        ]
      }
    ]
  },
  "options": {
    "plugins": {
      "title": { "display": true, "text": "Price History" }
    }
  }
}
```

Use `"type": "ohlc"` for bar-style OHLC rendering. The `x` field accepts numeric timestamps (recommended) or date strings like `"2025-02-25"`.

## Color Suggestions

| Color | Hex | Good For |
|-------|-----|----------|
| Purple | `#8b5cf6` | Primary data |
| Blue | `#3b82f6` | Secondary data |
| Green | `#10b981` | Positive/growth |
| Red | `#ef4444` | Negative/decline |
| Amber | `#f59e0b` | Warning/neutral |
| Indigo | `#6366f1` | Accent |

For pie/doughnut charts, pass an array of colors:

```json
"backgroundColor": ["#8b5cf6", "#3b82f6", "#10b981", "#ef4444", "#f59e0b"]
```

```

### scripts/generate-chart.js

```javascript
#!/usr/bin/env node

/**
 * Chart Splat - Chart Generation Script
 *
 * Usage:
 *   node generate-chart.js <type> <labels> <data> [title] [output]
 *
 * Examples:
 *   node generate-chart.js bar "Q1,Q2,Q3,Q4" "50,75,60,90" "Revenue" chart.png
 *   node generate-chart.js line "Mon,Tue,Wed" "10,20,15"
 *   node generate-chart.js pie "A,B,C" "30,50,20" "" pie.png
 *   node generate-chart.js --config chart-config.json -o chart.png
 */

const fs = require('fs');

const API_URL = process.env.CHARTSPLAT_API_URL || 'https://api.chartsplat.com';
const API_KEY = process.env.CHARTSPLAT_API_KEY;

if (!API_KEY) {
  console.error('Error: CHARTSPLAT_API_KEY environment variable is required');
  console.error('Get your API key at https://chartsplat.com/dashboard/api-keys');
  process.exit(1);
}

const VALID_TYPES = ['line', 'bar', 'pie', 'doughnut', 'radar', 'polarArea'];

async function generateChart(config) {
  const response = await fetch(`${API_URL}/chart`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Api-Key': API_KEY,
    },
    body: JSON.stringify(config),
  });

  if (!response.ok) {
    const error = await response.text();
    throw new Error(`API error (${response.status}): ${error}`);
  }

  const result = await response.json();
  return result.image;
}

async function main() {
  const args = process.argv.slice(2);

  // Handle --config mode
  const configIdx = args.indexOf('--config');
  if (configIdx !== -1) {
    const configFile = args[configIdx + 1];
    if (!configFile) {
      console.error('Error: --config requires a file path');
      process.exit(1);
    }
    const outputIdx = args.indexOf('-o');
    const output = outputIdx !== -1 ? args[outputIdx + 1] : 'chart.png';
    const config = JSON.parse(fs.readFileSync(configFile, 'utf-8'));
    const image = await generateChart(config);
    const base64 = image.replace(/^data:image\/png;base64,/, '');
    fs.writeFileSync(output, Buffer.from(base64, 'base64'));
    console.log(`Chart saved to ${output}`);
    return;
  }

  // Positional args mode
  if (args.length < 3) {
    console.error('Usage: generate-chart.js <type> <labels> <data> [title] [output]');
    console.error('       generate-chart.js --config <file> [-o output.png]');
    console.error('');
    console.error(`Chart types: ${VALID_TYPES.join(', ')}`);
    process.exit(1);
  }

  const [type, labelsStr, dataStr, title, output = 'chart.png'] = args;

  if (!VALID_TYPES.includes(type)) {
    console.error(`Error: Invalid chart type '${type}'`);
    console.error(`Valid types: ${VALID_TYPES.join(', ')}`);
    process.exit(1);
  }

  const labels = labelsStr.split(',').map((s) => s.trim());
  const data = dataStr.split(',').map((s) => parseFloat(s.trim()));

  const config = {
    type,
    data: {
      labels,
      datasets: [{ data }],
    },
    options: {
      width: 800,
      height: 600,
      ...(title && {
        plugins: { title: { display: true, text: title } },
      }),
    },
  };

  const image = await generateChart(config);
  const base64 = image.replace(/^data:image\/png;base64,/, '');
  fs.writeFileSync(output, Buffer.from(base64, 'base64'));
  console.log(`Chart saved to ${output}`);
}

main().catch((err) => {
  console.error(`Error: ${err.message}`);
  process.exit(1);
});

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "bobbyg603",
  "slug": "chart-splat",
  "displayName": "Chart Splat",
  "latest": {
    "version": "1.1.0",
    "publishedAt": 1772676735440,
    "commit": "https://github.com/openclaw/skills/commit/46349efd68d2bbbde3b503300dbe0d98275db136"
  },
  "history": []
}

```

chart-splat | SkillHub