# Chart Image API - Data to PNG/SVG Chart for Agents & Reports (`that_red_bird/chart-image-generator`) Actor

Need a chart image, not a library? Send JSON rows, a Chart.js or Vega-Lite spec, or any dataset ID and get a PNG and SVG with a public link in the key-value store. Pay per chart, no browser, no monthly plan. Good for Slack, email and PDF reports.

- **URL**: https://apify.com/that_red_bird/chart-image-generator.md
- **Developed by:** [mohamed alaya](https://apify.com/that_red_bird) (community)
- **Categories:** Developer tools, Automation, AI
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.00 / 1,000 chart rendereds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Chart Image API - Data to PNG/SVG Chart for Agents & Reports

Turns JSON data, a Chart.js config, a Vega-Lite spec or any Apify dataset into a chart image (PNG, and SVG for Vega-Lite and simple charts) stored in the key-value store with a link you can drop into Slack, email, a PDF or an AI agent reply.

For developers, report builders and AI agents that need a picture of a chart without running a browser or paying a monthly plan. Pay per chart.

### Input examples

Simple mode, rows in, grouped bar chart out:

```json
{
  "chartType": "bar",
  "title": "Sales by month",
  "stacked": false,
  "data": [
    { "month": "Jan", "online": 120, "store": 80 },
    { "month": "Feb", "online": 150, "store": 95 }
  ]
}
```

A Chart.js config (PNG only):

```json
{ "spec": { "type": "line", "data": { "labels": ["Mon", "Tue", "Wed"], "datasets": [{ "label": "Visitors", "data": [320, 410, 380] }] } }, "width": 800, "height": 400 }
```

Chart any dataset, for example another Actor's output, mapping its columns:

```json
{ "datasetId": "YOUR_DATASET_ID", "chartType": "horizontalBar", "xField": "name", "yFields": ["reviewsCount"], "title": "Top places by reviews", "theme": "dark" }
```

Leave the input empty to render three demo charts.

### Input guide

| Field | What it does |
|---|---|
| `data`, `chartType`, `xField`, `yFields`, `seriesField`, `stacked`, `title` | Simple mode: bar, horizontalBar, line, area, pie, doughnut, scatter from JSON rows. Several value fields draw several series. |
| `spec` | Advanced: a Chart.js config (PNG) or a Vega-Lite spec (PNG and SVG). Plain JSON, no functions. A Vega-Lite `data.url` is fetched for you (public http/https only). |
| `datasetId`, `maxRows` | Chart the rows of any dataset (first `maxRows`). |
| `charts` | Render many charts in one run: a list of jobs with the fields above. Up to 200 per run. |
| `width`, `height`, `scale`, `theme`, `formats` | Size, PNG pixel density (1-4), light or dark, png and/or svg. |

### Output

One dataset row per chart. The images are in the run's key-value store; the row holds links.

| Field | Meaning |
|---|---|
| `name`, `engine`, `chartType` | What was rendered (`vega-lite` or `chartjs`) |
| `imagePixels`, `width`, `height`, `theme` | Image size and theme |
| `rows` | Number of data rows used |
| `pngUrl`, `svgUrl` | Links to the image files (`svgUrl` is empty for Chart.js specs) |
| `pngBytes`, `svgBytes` | File sizes |

Sample row:

```json
{ "type": "chart", "name": "sales", "engine": "vega-lite", "chartType": "bar", "imagePixels": "1800x1040",
  "rows": 2, "pngUrl": "https://api.apify.com/v2/key-value-stores/.../records/chart-1-sales.png?signature=...",
  "svgUrl": "https://api.apify.com/v2/key-value-stores/.../records/chart-1-sales.svg?signature=..." }
```

The links are signed, so they open without an API token. They live as long as the run's storage (your Apify data retention).

### Use it with

- Google Maps Scraper -> this Actor with `datasetId`: chart ratings or review counts of the places you scraped.
- Any scraper's dataset -> a weekly Slack report: schedule this Actor, post `pngUrl`.
- An AI agent (MCP or API): the agent sends rows or a spec and gets back an image link to put in its answer.

### FAQ

**Does it use a browser?** No. Charts are drawn with Vega and Chart.js on a native canvas, and converted with resvg.

**Why is there no SVG for my Chart.js config?** Chart.js only draws to a canvas. Use simple mode or a Vega-Lite spec when you need SVG.

**Can I use custom fonts or callbacks in Chart.js options?** No. Only JSON options work. Fonts are DejaVu Sans.

### Honest limits

- Chart.js specs cannot contain functions (tooltips and scriptable options are ignored); plugins are not loadable.
- Simple mode has no log scales, dual axes or annotations; use a Vega-Lite spec for those.
- Text widths in Vega charts are estimated, so very long labels may overlap. Set `width` larger or shorten labels.
- Only Latin-script text is guaranteed to render (DejaVu Sans).

### Price

Pay per event: **$0.001 per chart rendered** (`chart-rendered`). PNG and SVG of the same chart are one chart. 1,000 charts cost $1.00. Charts that fail are not charged.

# Actor input Schema

## `data` (type: `array`):

Simple mode: a list of JSON objects, one per category or point, for example \[{"month":"Jan","sales":10},{"month":"Feb","sales":14}]. The first column is the x axis and numeric columns become the values. Leave empty (with no spec and no dataset) to render three demo charts.

## `chartType` (type: `string`):

Chart type for simple mode and dataset mode. Ignored when you pass a spec.

## `title` (type: `string`):

Title drawn above the chart. Leave empty for no title.

## `xField` (type: `string`):

Name of the column for the x axis or the pie slices. Leave empty to use the first column of the data.

## `yFields` (type: `array`):

Names of the numeric columns to plot. Several columns draw several series. Leave empty to use every numeric column except the x field.

## `seriesField` (type: `string`):

Name of a column that splits one value column into coloured series, for example region or product. Use it when your rows are in long format.

## `stacked` (type: `boolean`):

Stack bars or areas of several series on top of each other. When off, bars of several series are drawn side by side.

## `spec` (type: `object`):

Advanced: a full Chart.js config ({type, data:{labels, datasets}, options}) rendered to PNG, or a Vega-Lite spec rendered to PNG and SVG. Plain JSON only, no functions. Leave empty for simple mode.

## `datasetId` (type: `string`):

Pick any dataset, for example the output of another Actor, to chart its rows. Use X field and Value fields to map columns. The first rows (see Max rows) are used.

## `charts` (type: `array`):

Advanced: a list of chart jobs, each with the same fields as above (name, chartType, data, spec, title, xField, yFields, seriesField, stacked, width, height, theme, formats). One image set is rendered and charged per job.

## `width` (type: `integer`):

Chart width in pixels, 200 to 2400. Vega-Lite and simple charts are also multiplied by Scale.

## `height` (type: `integer`):

Chart height in pixels, 150 to 1800.

## `scale` (type: `integer`):

Pixel density multiplier for the PNG of simple and Vega-Lite charts (2 gives sharp images for retina and PDF). Not used for Chart.js specs.

## `theme` (type: `string`):

Light or dark colours for background, text and grid.

## `formats` (type: `array`):

Which images to store. SVG is available for simple and Vega-Lite charts only. Both formats count as one chart.

## `maxRows` (type: `integer`):

Rows beyond this number are ignored, to keep charts readable and runs fast.

## Actor input object example

```json
{
  "data": [],
  "chartType": "bar",
  "title": "",
  "xField": "",
  "yFields": [],
  "seriesField": "",
  "stacked": true,
  "spec": {},
  "charts": [],
  "width": 900,
  "height": 520,
  "scale": 2,
  "theme": "light",
  "formats": [
    "png",
    "svg"
  ],
  "maxRows": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `downloadCsv` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `count` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "data": [],
    "chartType": "bar",
    "title": "",
    "xField": "",
    "yFields": [],
    "seriesField": "",
    "stacked": true,
    "spec": {},
    "charts": [],
    "width": 900,
    "height": 520,
    "scale": 2,
    "theme": "light",
    "formats": [
        "png",
        "svg"
    ],
    "maxRows": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("that_red_bird/chart-image-generator").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "data": [],
    "chartType": "bar",
    "title": "",
    "xField": "",
    "yFields": [],
    "seriesField": "",
    "stacked": True,
    "spec": {},
    "charts": [],
    "width": 900,
    "height": 520,
    "scale": 2,
    "theme": "light",
    "formats": [
        "png",
        "svg",
    ],
    "maxRows": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("that_red_bird/chart-image-generator").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "data": [],
  "chartType": "bar",
  "title": "",
  "xField": "",
  "yFields": [],
  "seriesField": "",
  "stacked": true,
  "spec": {},
  "charts": [],
  "width": 900,
  "height": 520,
  "scale": 2,
  "theme": "light",
  "formats": [
    "png",
    "svg"
  ],
  "maxRows": 1000
}' |
apify call that_red_bird/chart-image-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,that_red_bird/chart-image-generator"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Dv1ZIvhvqxaUDoljc/builds/dYZJgP5pBg2mXWzAK/openapi.json
