# Chart Image Generator: Chart.js & ECharts to PNG, SVG, PDF (`jumblemog/chart-image-generator`) Actor

Turn data or a Chart.js or ECharts config into chart images: PNG, SVG, PDF, WebP or JPEG. Bar, line, pie, scatter, candlestick, sankey and more, from labels and values, CSV, JSON or an Apify dataset. A QuickChart alternative for AI agents.

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

## Pricing

Pay per event

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 Generator: Chart.js & ECharts to PNG, SVG, PDF

**Turn data into chart images.** Send a [Chart.js](https://www.chartjs.org) config, an [Apache ECharts](https://echarts.apache.org) option, or just your data (labels and values, CSV, JSON rows, a link to a data file, or the dataset of another Actor run), and get back a clean chart as **PNG, SVG, PDF, WebP or JPEG** with a download link. Bar, line, area, pie, doughnut, scatter, radar, mixed bar and line, candlestick, sankey, treemap, heatmap, box plot, word cloud, gauge and more. It reads the same Chart.js configs as [QuickChart](https://quickchart.io), including old Chart.js 2 configs, so it works as a pay-per-chart QuickChart alternative that people, automations and AI agents can call.

![Six charts made by this Actor: grouped bars with dollar labels, a dark area chart of weekly visits, a doughnut of traffic sources, a candlestick chart of a share price, a sankey diagram of where visits go, and an ECharts radar chart comparing two laptops](https://api.apify.com/v2/key-value-stores/Km5b4PG3kYHdZSb1E/records/chart-image-generator-examples.png?signature=YflG8OvklYYMCzgV6JJI)

### What it does

- **Chart.js configs**: `{"type": "bar", "data": {...}, "options": {...}}`, drawn with Chart.js 4. Chart.js 2 configs (the version QuickChart uses by default, and what many AI models write) are converted automatically: `xAxes` and `yAxes`, `horizontalBar`, top-level `title` and `legend`, `scaleLabel`, `gridLines`, `ticks.beginAtZero`, `cutoutPercentage`, `lineTension` and v2 annotations. Configs written as JavaScript can contain functions, such as tick and label formatters.
- **Plugins included**: data labels, annotations (lines, boxes, labels), time axes, candlestick and OHLC (financial), matrix (heatmaps), sankey, treemap, box plot and violin, and word cloud charts.
- **Apache ECharts options**: line, bar, pie, scatter, radar, gauge, funnel, heatmap, treemap, sunburst, sankey, candlestick, box plot, graph, parallel, theme river and calendar charts, with ECharts' own light and dark themes.
- **Charts from plain data**, no config needed: labels with one or more series, CSV or TSV text, JSON rows, an Apify dataset ID, or a link to a CSV or JSON file or a public Google Sheet. Pick the label and value fields (nested fields like `stats.views` work), add up, count, average or take the min or max of rows that share a label, sort, and keep the top N. Dates become a time axis, and a series can be a line over bars or use a second axis.
- **Styled by default**: a left-aligned title and subtitle, round legend markers, soft grid lines, rounded bars, and value labels with your prefix, suffix and decimals (`$1,200`, `45%`, `3.5 kg`).
- **Five formats**: PNG at 1x to 4x pixel density, SVG and PDF as vector files that stay sharp at any size, lossless WebP, and JPEG. One charge per chart, whatever the number of formats.
- **Look**: light or dark theme, any background color or transparent, six palettes (including a colorblind-safe one) or your own colors, 13 fonts, and number and date formats for any locale (`de-DE` writes 1.234,5).
- **Emoji and every script**: color emoji, Chinese, Japanese and Korean, Greek and Cyrillic in titles, labels and legends.
- **Errors that say what to fix**: an unknown chart type lists the ones that exist, a broken config gives the JavaScript error and line, a missing field lists the fields in your data. Failed charts are free.
- **Image straight from the API**: the first chart is also the run's `OUTPUT`, so the run-sync endpoint answers with the image itself.

### Who it's for

- **AI agents and LLM apps** that answer with a chart: write a Chart.js config (most models know the format) or pass the numbers, and show the image in a chat, report, email or slide.
- **Automation builders** in n8n, Make or Zapier who send weekly KPI charts to Slack, email or Notion.
- **Apify users** who want to see their scraped data: chart prices, ratings, review counts or items per category straight from a scraper's dataset.
- **Developers** who need server-side chart images without running a browser, or a QuickChart replacement priced per chart.

### How to use it

1. Paste a Chart.js config or an ECharts option into **Chart config**, or fill in **Labels** and **Series**, or paste a CSV into **CSV data**.
2. Choose a chart type, title, theme and colors, or keep the defaults.
3. Click **Start**. The chart appears in the **Output** tab with its download link.

For many charts in one run, put them in **More charts**. You can also run it through the [Apify API](https://docs.apify.com/api/v2), on a schedule, or from Make, n8n, Zapier and other integrations.

### Input

| Field | What it does |
| --- | --- |
| `chart` | A Chart.js config (`type`, `data`, `options`) or an ECharts option (`series`, `xAxis`, ...). |
| `chartCode` | The same kind of config as JavaScript text, which may contain functions. Markdown code fences are removed. |
| `engine` | `auto` (default), `chartjs` or `echarts`. |
| `charts` | More charts: configs, configs as text, or objects with `chart` (or data fields) and their own settings, such as `{"chart": {...}, "name": "sales", "width": 1200}`. |
| `chartType` | For charts from data: `bar` (default), `horizontalBar`, `stackedBar`, `horizontalStackedBar`, `line`, `area`, `stackedArea`, `pie`, `doughnut`, `polarArea`, `radar` or `scatter`. |
| `labels`, `series`, `values` | Labels with named series (`[{"name": "Sales", "values": [3, 5]}]`, optionally with `"type": "line"`, `"axis": "right"` and `"color"`), or one list of values. |
| `csv`, `data`, `datasetId`, `dataUrl` | Data as CSV or TSV text, JSON rows, the ID of an Apify dataset (up to 100,000 items), or a link to a public CSV or JSON file or Google Sheet (up to 10 MB). |
| `xField`, `yFields` | The field with the labels and the fields with the values. Default: the first text column and every number column. |
| `aggregate`, `sortBy`, `limit` | Combine rows with the same label (`auto`, `none`, `sum`, `count`, `average`, `min`, `max`), sort (`valueDesc`, `valueAsc`, `label`) and keep the top N. |
| `title`, `subtitle`, `xAxisTitle`, `yAxisTitle` | Text for charts made from data. |
| `showValues`, `valuePrefix`, `valueSuffix`, `decimals` | Write the values on the chart, and how numbers look. |
| `legend`, `beginAtZero`, `smooth` | Legend position or `none`, the value axis starting at zero (default on), and curved lines. |
| `width`, `height` | Chart size in CSS pixels (800 x 450 by default, up to 4,000 each). |
| `theme`, `background` | `light` (default) or `dark`, and any CSS color or `transparent`. |
| `palette`, `colors` | `tableau10` (default), `colorblind`, `vivid`, `pastel`, `chartjs` or `echarts`, or your own list of colors. |
| `fontFamily`, `fontSize`, `locale` | Inter (default), Roboto, Open Sans, Lato, Montserrat, Poppins, Source Sans 3, Noto Sans, IBM Plex Sans, Nunito, Arial, Noto Serif or JetBrains Mono; the base size (12 px); and the number and date locale (`en-US`). |
| `formats`, `scale` | Any of `png` (default), `svg`, `pdf`, `webp` and `jpg`, and the pixel density of PNG, WebP and JPEG (2 by default). |
| `name`, `inlineImage`, `maxCharts` | The files' name, the image as a base64 data URI in the results, and the most charts per run (100). |

The data, title and value settings in the form belong to the chart in the form; every chart in **More charts** has its own. The look and output settings apply to every chart unless a chart sets its own. A chart in **More charts** that sets only `chartType`, `xField`, `yFields`, `aggregate` or `sortBy` uses the form's data, so one dataset or CSV can be drawn several ways in one run.

A Chart.js config, the way QuickChart takes it:

```json
{
  "chart": {
    "type": "bar",
    "data": {
      "labels": ["Jan", "Feb", "Mar", "Apr"],
      "datasets": [{"label": "Revenue", "data": [120, 190, 170, 240]}, {"label": "Costs", "data": [80, 110, 95, 130]}]
    },
    "options": {"plugins": {"title": {"display": true, "text": "Revenue and costs"}}}
  }
}
```

A chart from a scraper's dataset: the ten brands with the most products, largest first:

```json
{
  "datasetId": "YOUR_DATASET_ID",
  "xField": "brand",
  "aggregate": "count",
  "sortBy": "valueDesc",
  "limit": 10,
  "chartType": "horizontalBar",
  "title": "Products per brand",
  "showValues": true
}
```

A CSV, with the rows of each region added up:

```json
{
  "csv": "region,product,revenue\nNorth,Widget,1200\nSouth,Widget,950\nNorth,Gadget,800\nEast,Widget,640",
  "xField": "region",
  "chartType": "doughnut",
  "title": "Revenue by region",
  "showValues": true,
  "valuePrefix": "$"
}
```

Orders as bars with the conversion rate as a line on a second axis:

```json
{
  "labels": ["Jan", "Feb", "Mar", "Apr"],
  "series": [
    {"name": "Orders", "values": [320, 410, 380, 520]},
    {"name": "Conversion (%)", "values": [2.1, 2.4, 2.2, 2.9], "type": "line", "axis": "right"}
  ],
  "title": "Orders and conversion rate"
}
```

An ECharts gauge on the dark theme:

```json
{"chart": {"series": [{"type": "gauge", "data": [{"value": 72, "name": "Score"}]}]}, "theme": "dark"}
```

### How-to examples

Each example below is a complete input, checked with a run of the Actor.

#### How to turn a Chart.js config into a PNG image (a QuickChart alternative)

```json
{
  "chart": {"type": "bar",
            "data": {"labels": ["Jan", "Feb", "Mar", "Apr"],
                     "datasets": [{"label": "Revenue", "data": [120, 190, 170, 240]},
                                  {"label": "Costs", "data": [80, 110, 95, 130]}]},
            "options": {"plugins": {"title": {"display": true, "text": "Revenue and costs"}}}},
  "formats": ["png", "svg"]
}
```

Result: a grouped bar chart as a 1600 x 900 PNG (800 x 450 at 2x) in `pngUrl` and a vector SVG in `svgUrl`, made in about 1.4 seconds.

#### How to make a line chart from CSV data

```json
{"csv": "Week,Visits\n2026-09-07,1200\n2026-09-14,1350\n2026-09-21,1610\n2026-09-28,1580\n2026-10-05,1900",
 "chartType": "line", "title": "Weekly visits", "theme": "dark"}
```

Result: a dark line chart. The dates become a time axis (Sep 7 to Oct 5), so gaps between weeks are drawn to scale. A link to a CSV file or a public Google Sheet works the same way in `dataUrl`.

#### How to chart scraped data: count items per category

Give JSON rows here, or the `datasetId` of a scraper run:

```json
{"data": [{"brand": "Acme", "price": 19.99}, {"brand": "Bolt", "price": 24.5}, {"brand": "Acme", "price": 22.0},
          {"brand": "Cora", "price": 9.99}, {"brand": "Acme", "price": 15.0}, {"brand": "Bolt", "price": 31.0}],
 "xField": "brand", "aggregate": "count", "sortBy": "valueDesc", "limit": 10,
 "chartType": "horizontalBar", "title": "Products per brand", "showValues": true}
```

Result: horizontal bars Acme 3, Bolt 2, Cora 1, largest first, with the counts written on the bars. Use `"aggregate": "average"` and `"yFields": ["price"]` for the average price per brand instead.

#### How to let an AI agent answer with a chart

Add this Actor to the [Apify MCP server](https://mcp.apify.com) with `https://mcp.apify.com/?tools=jumblemog/chart-image-generator`. Most models already write Chart.js configs, including old Chart.js 2 ones, which are converted. The agent sends the config in `chart` and shows the user `imageUrl`. A broken config comes back with the JavaScript error and line, so the agent can fix it and try again.

### FAQ

**Can it replace QuickChart?** Yes, for drawing images. It reads the same Chart.js configs, including Chart.js 2 ones, and you pay per chart instead of a monthly plan.

**Which chart types are there?** Bar, line, area, pie, doughnut, scatter, radar, mixed bar and line, candlestick, sankey, treemap, heatmap, box plot, word cloud and gauge, plus every Apache ECharts chart.

**Can I get SVG or PDF?** Yes. `formats` takes any of `png`, `svg`, `pdf`, `webp` and `jpg`, and one chart costs the same whatever the number of formats.

**Can I get the image itself from the API?** Yes. The first chart is also the run's `OUTPUT`, so the run-sync endpoint answers with the image.

**Does it work with Zapier, Make or n8n?** Yes. Call the Actor with its Apify app or an HTTP request, then send `imageUrl` to Slack, email or Notion.

### Output

Each chart becomes one dataset item, and the files are saved in the run's key-value store:

```json
{
  "index": 1,
  "name": "revenue",
  "status": "ok",
  "error": null,
  "engine": "chartjs",
  "chartType": "bar",
  "imageUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/001-revenue.png",
  "pngUrl": "https://api.apify.com/v2/key-value-stores/<store>/records/001-revenue.png",
  "svgUrl": null,
  "pdfUrl": null,
  "webpUrl": null,
  "jpgUrl": null,
  "width": 1600,
  "height": 900,
  "dataPoints": 8,
  "sourceUrl": null,
  "notes": [],
  "processingSeconds": 0.21
}
```

When a chart can't be drawn, the item says why and isn't billed:

```json
{
  "index": 2,
  "status": "failed",
  "error": "\"bars\" isn't a Chart.js chart type this tool knows. Use one of: bar, line, pie, doughnut, radar, polarArea, scatter, bubble, candlestick, ohlc, matrix, sankey, treemap, boxplot, violin, wordCloud.",
  "imageUrl": null
}
```

Download your files within your plan's data retention period, or copy them to your own storage, because run storage expires.

### Pricing

You pay per **chart created**, at the price shown on this page, whatever the number of formats (PNG, SVG, PDF, WebP and JPEG of the same chart count once). Charts that can't be drawn are never charged. If you set a maximum cost per run, the Actor stops when the next chart wouldn't fit.

### Speed

One chart usually takes 3 to 4 seconds through the API, from request to image, most of it the run starting up. Each further chart in the same run adds about 0.2 to 0.7 seconds as PNG, or 1 to 2 seconds with all five formats (sankey and word cloud charts take longer). On Apify more memory also means more CPU, so give big batches 2 GB or more to draw them faster.

### Tips and limits

- Chart.js configs given as JSON can't contain functions; send the config as JavaScript text in `chartCode` (or as a string in `charts`) when it has formatters or callbacks. Text that isn't valid JSON is read as JavaScript.
- Images inside configs (point styles, ECharts image symbols and graphics) and data URLs inside configs aren't loaded: the renderer has no network access. Give the data in the config, or use the data fields.
- ECharts maps (which need GeoJSON registered first) and 3D charts (ECharts GL) aren't available. For Vega-Lite specs, Mermaid diagrams and Graphviz graphs, use the Diagram Renderer Actor.
- Chart.js SVG files have their text turned into outlines, so they look the same everywhere; color emoji show in PNG, WebP, JPEG and PDF files but not in Chart.js SVGs. ECharts SVG files keep text as text in the chosen font.
- Data: up to 100,000 dataset items, files up to 10 MB, 10,000 labels and 20 series per chart. Each chart has a 60-second limit.
- Datasets: Apify lets this Actor read only the dataset picked in its **Apify dataset** field (`datasetId` at the top of the input), so charts in **More charts** can use that dataset but no other. To chart several datasets, run once per dataset.
- Candlestick and OHLC points take `x` as a date (text such as `2026-09-01`, or a timestamp in milliseconds or seconds) with `o`, `h`, `l` and `c` prices, and are put in time order. `[time, open, high, low, close]` lists work too.
- Data file links: CSV, TSV and JSON files, GitHub file links, and Google Sheets links (the sheet must be shared as "Anyone with the link" or published to the web; a `gid` in the link picks the tab). Every site's robots.txt is checked first, and its crawl delay kept.

### For AI agents and developers

This Actor works with the [Apify MCP server](https://mcp.apify.com), so AI agents can call it as a tool: pass a Chart.js config in `chart` (or labels and series) and read `imageUrl` from the dataset item. For a direct API call that waits for the result:

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~chart-image-generator/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"chart": {"type": "line", "data": {"labels": ["Mon", "Tue", "Wed"], "datasets": [{"label": "Visits", "data": [120, 180, 150]}]}}}'
```

To get the image itself as the response, call `run-sync` instead. It returns the run's `OUTPUT`, which is the first chart (or the error as JSON):

```bash
curl -X POST "https://api.apify.com/v2/acts/jumblemog~chart-image-generator/run-sync?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"labels": ["A", "B", "C"], "values": [3, 7, 5], "chartType": "doughnut", "showValues": true}' \
  -o chart.png
```

### Credits

- [Chart.js](https://github.com/chartjs/Chart.js) with [chartjs-plugin-datalabels](https://github.com/chartjs/chartjs-plugin-datalabels), [chartjs-plugin-annotation](https://github.com/chartjs/chartjs-plugin-annotation), [chartjs-adapter-date-fns](https://github.com/chartjs/chartjs-adapter-date-fns) and [date-fns](https://github.com/date-fns/date-fns), and the [financial](https://github.com/chartjs/chartjs-chart-financial), [matrix](https://github.com/kurkle/chartjs-chart-matrix), [sankey](https://github.com/kurkle/chartjs-chart-sankey), [treemap](https://github.com/kurkle/chartjs-chart-treemap), [box plot](https://github.com/sgratzl/chartjs-chart-boxplot) and [word cloud](https://github.com/sgratzl/chartjs-chart-wordcloud) charts (all MIT), [d3-cloud](https://github.com/jasondavies/d3-cloud) (BSD-3-Clause), [Apache ECharts](https://github.com/apache/echarts) (Apache-2.0) with [ZRender](https://github.com/ecomfe/zrender) (BSD-3-Clause), drawn with [Skia](https://skia.org) (BSD-3-Clause) through [@napi-rs/canvas](https://github.com/Brooooooklyn/canvas) (MIT), and [Pillow](https://python-pillow.org) (MIT-CMU).
- Fonts (SIL Open Font License): Inter, Roboto, Open Sans, Lato, Montserrat, Poppins, Source Sans 3, Noto Sans, IBM Plex Sans, Nunito, Arimo (drawn for Arial and Helvetica), Noto Serif and JetBrains Mono from Google Fonts, Noto Color Emoji and Noto Sans CJK, and DejaVu Sans (Bitstream Vera).
- This Actor isn't affiliated with QuickChart, Chart.js, Apache ECharts or the projects above.

# Actor input Schema

## `chart` (type: `object`):

A Chart.js config with type, data and options (the format QuickChart uses; Chart.js 2 configs are converted automatically) or an Apache ECharts option with series. Leave empty to chart the data in the next section instead.

## `chartCode` (type: `string`):

The same kind of config written as JavaScript, which may contain functions such as a ticks callback, like QuickChart's c= parameter. Markdown code fences are removed. Used when Chart config is empty.

## `engine` (type: `string`):

Which library draws the config. Detected automatically: Chart.js configs have type and data, ECharts options have series.

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

More charts in one run. Each entry is a Chart.js config, an ECharts option, a config written as JavaScript text, or an object with chart (or data fields such as labels and series, csv or datasetId) and settings of its own, such as {"chart": {...}, "name": "sales", "width": 1200}. An entry that sets only chartType, xField or yFields charts the data given above, so one dataset can be drawn several ways. Look settings left out come from this form.

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

The kind of chart to draw from the data.

## `labels` (type: `array`):

The categories along the axis (or the slices of a pie), such as months or product names.

## `series` (type: `array`):

One or more named lists of numbers, one number per label: \[{"name": "Sales", "values": \[3, 5, 8]}]. A series can also have "type": "line" (a line over bars), "axis": "right" (a second value axis) and "color".

## `values` (type: `array`):

A single list of numbers, one per label, instead of Series: \[3, 5, 8].

## `csv` (type: `string`):

CSV or TSV text with a header row, such as month,sales,costs. The first text column gives the labels and the number columns the series, unless X field and Y fields say otherwise. Numbers like $1,200 and 45% are understood.

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

Rows as JSON objects, like a dataset's items: \[{"month": "Jan", "sales": 12}, ...]. Nested fields can be picked with dots, such as stats.views.

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

A dataset in your Apify account, such as the results of a scraper run, to chart its items (its ID or name). Up to 100,000 items are read. The tool gets read access to this dataset only, so charts in the charts list can use it too but no other dataset.

## `dataUrl` (type: `string`):

A link to a public CSV, TSV or JSON file (up to 10 MB), a GitHub file, or a Google Sheet shared as "Anyone with the link". The site's robots.txt is respected.

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

The column or field that gives the labels (or the x values of a scatter chart). Default: the first text column.

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

The columns or fields to chart as series. Default: every number column. With none, rows are counted per label.

## `aggregate` (type: `string`):

How to combine rows that share a label, such as many orders per region.

## `sortBy` (type: `string`):

The order of the labels. Dates on line charts are always put in order.

## `limit` (type: `integer`):

Keep only this many labels after sorting, such as the top 10.

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

The chart's title, shown at the top left.

## `subtitle` (type: `string`):

A smaller line under the title, such as the unit or the source.

## `xAxisTitle` (type: `string`):

Text along the horizontal axis.

## `yAxisTitle` (type: `string`):

Text along the vertical axis.

## `showValues` (type: `boolean`):

Write each value on its bar, point or slice.

## `valuePrefix` (type: `string`):

Put before every number on the value axis and labels, such as $.

## `valueSuffix` (type: `string`):

Put after every number, such as %, k or " kg" (with its space).

## `decimals` (type: `integer`):

Show numbers with exactly this many decimals. Default: up to 2, as needed.

## `legend` (type: `string`):

Where the legend goes.

## `beginAtZero` (type: `boolean`):

Off lets the axis start near the smallest value, which shows small changes in large numbers.

## `smooth` (type: `boolean`):

Curved lines for line and area charts.

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

Chart width in CSS pixels. PNG files are this times the pixel scale (1600 px wide by default).

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

Chart height in CSS pixels.

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

Light or dark background, text and grid lines.

## `background` (type: `string`):

Any CSS color (#ffffff, white, rgb(0, 0, 0)) or transparent. Default: white, or dark gray with the dark theme.

## `palette` (type: `string`):

Colors for series and slices that don't set their own. ECharts options keep ECharts' colors unless you choose a palette here.

## `colors` (type: `array`):

Your own colors in order, such as #2563eb, #f97316, #16a34a. Used instead of the palette.

## `fontFamily` (type: `string`):

The font for all text. Emoji, Chinese, Japanese and Korean always work.

## `fontSize` (type: `integer`):

The base font size. Titles of charts made from data are 1.5 times bigger.

## `locale` (type: `string`):

A locale such as en-US, de-DE or fr-FR for thousands separators, decimals and month names.

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

PNG for chats, emails, docs and slides; SVG and PDF are vector files that stay sharp at any size; WebP is small and lossless; JPEG fits anywhere. One charge per chart, whatever the number of formats.

## `scale` (type: `number`):

Pixel density of PNG, WebP and JPEG files: 2 (default) is sharp on high-resolution screens, 1 gives smaller files, 3 or 4 for print.

## `name` (type: `string`):

A name for the chart's files and dataset row. Default: the title or the chart type.

## `inlineImage` (type: `boolean`):

Also put each image in its dataset row as a base64 data URI, for emails and HTML that can't load links. Images up to 2 MB.

## `maxCharts` (type: `integer`):

Stop after this many charts, so the cost of a run stays predictable.

## Actor input object example

```json
{
  "engine": "auto",
  "chartType": "bar",
  "labels": [
    "Q1",
    "Q2",
    "Q3",
    "Q4"
  ],
  "series": [
    {
      "name": "2025",
      "values": [
        42,
        58,
        61,
        75
      ]
    },
    {
      "name": "2026",
      "values": [
        51,
        66,
        78,
        94
      ]
    }
  ],
  "aggregate": "auto",
  "sortBy": "none",
  "showValues": false,
  "legend": "auto",
  "beginAtZero": true,
  "smooth": false,
  "width": 800,
  "height": 450,
  "theme": "light",
  "palette": "tableau10",
  "fontFamily": "Inter",
  "fontSize": 12,
  "locale": "en-US",
  "formats": [
    "png"
  ],
  "scale": 2,
  "inlineImage": false,
  "maxCharts": 100
}
```

# Actor output Schema

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

One item per chart: image links, size and type, or the error.

## `files` (type: `string`):

The PNG, SVG, PDF, WebP and JPEG files saved in the run's key-value store.

# 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 = {
    "labels": [
        "Q1",
        "Q2",
        "Q3",
        "Q4"
    ],
    "series": [
        {
            "name": "2025",
            "values": [
                42,
                58,
                61,
                75
            ]
        },
        {
            "name": "2026",
            "values": [
                51,
                66,
                78,
                94
            ]
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jumblemog/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 = {
    "labels": [
        "Q1",
        "Q2",
        "Q3",
        "Q4",
    ],
    "series": [
        {
            "name": "2025",
            "values": [
                42,
                58,
                61,
                75,
            ],
        },
        {
            "name": "2026",
            "values": [
                51,
                66,
                78,
                94,
            ],
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("jumblemog/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 '{
  "labels": [
    "Q1",
    "Q2",
    "Q3",
    "Q4"
  ],
  "series": [
    {
      "name": "2025",
      "values": [
        42,
        58,
        61,
        75
      ]
    },
    {
      "name": "2026",
      "values": [
        51,
        66,
        78,
        94
      ]
    }
  ]
}' |
apify call jumblemog/chart-image-generator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jumblemog/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/GJzLQMtcHxmwoRTbR/builds/EOIHKta2BvemAY9R4/openapi.json
