iliaal/fastchart

Native C PHP extension for fast chart rendering: 19 families (line, bar, pie, scatter, bubble, stock with technical indicators, radar, polar, surface, contour, treemap, funnel, waterfall, heatmap, gauge, linear meter, gantt, box plot, area) drawn onto ext/gd \GdImage canvases via libgd.

Maintainers

Package info

github.com/iliaal/fastchart

Language:C

Type:php-ext

Ext name:ext-fastchart

pkg:composer/iliaal/fastchart

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

0.1.1 2026-05-06 14:18 UTC

This package is auto-updated.

Last update: 2026-05-06 14:33:00 UTC


README

Tests License: BSD-3-Clause Follow @iliaa

Native C PHP extension. 19 chart types behind a modern OO API with fluent setters and final classes. Line, area, bar, scatter, bubble, pie, radar, polar, surface, contour, gauge, gantt, box-plot, treemap, funnel, waterfall, heatmap, linear meter, plus a deep StockChart (seven candle styles, SMA / EMA / WMA overlays, volume + indicator panes).

Two render paths. renderToFile() / renderPng() / renderJpeg() / renderWebp() / renderAvif() cover the common case: declare a chart, get a file or bytes back. draw($canvas) is the other path. Hand fastchart a \GdImage you own and it returns the same canvas, so you can composite several charts onto one image, stamp arbitrary ext/gd draw calls over the result, or drop the rendered chart into a larger image pipeline (PDF page, sprite sheet, dashboard tile).

fastchart: 19 chart types in one PHP extension

Status

Working. 19 chart types, 105 public methods, 97 phpt tests. The OO surface is stable for the v0.1 line. See CHANGELOG.md for what's shipped.

Install

Build from source against the PHP install you want to extend:

phpize
./configure --enable-fastchart
make -j
make test

Strict-warnings dev build (recommended for contributors):

./configure --enable-fastchart --enable-fastchart-dev

Runtime check:

php -d extension=./modules/fastchart.so \
  -r 'echo FastChart\Chart::version(), PHP_EOL;'

Requirements

  • PHP 8.3 or later (NTS or ZTS).
  • ext/gd enabled. fastchart pulls the underlying gdImagePtr out of caller-supplied \GdImage zvals via the one PHPAPI symbol ext/gd exports.
  • libgd development headers at build time (libgd-dev on Debian / Ubuntu, gd-devel on RHEL / Fedora).
  • FreeType (already a libgd dependency on every Linux distribution), used for TrueType / OpenType label rendering.

Quick start

The shortest path is the renderToFile() helper, which picks the encoder from the file extension:

(new FastChart\LineChart(640, 320))
    ->setTitle('Daily active users')
    ->setSeries([['data' => [820, 940, 870, 1020, 1180, 1250, 1340]]])
    ->setCategoryLabels(['Mon','Tue','Wed','Thu','Fri','Sat','Sun'])
    ->renderToFile('/tmp/dau.png');

renderPng(), renderJpeg(), renderWebp(), and renderAvif() return the encoded bytes if you need them in memory.

For pixel-level control or compositing several charts on one image, hand fastchart a \GdImage you own. draw() returns the same canvas back so call chains keep working:

$canvas = imagecreatetruecolor(1200, 600);

(new FastChart\StockChart())
    ->setSize(1200, 600)
    ->setTitle('AAPL last 90 days')
    ->setTheme(FastChart\Chart::THEME_DARK)
    ->setOhlcv($ohlcvRows)              // [[ts, o, h, l, c, v], …]
    ->setMovingAverages([20, 50, 200])
    ->setVolumePane(true)
    ->setCandleStyle(FastChart\Chart::STYLE_HOLLOW)
    ->draw($canvas);

imagepng($canvas, '/tmp/aapl.png');

📊 Performance

Median in-memory renderPng() time on a single core (Intel i9-13950HX, PHP 8.4 NTS, default font + DPI). Same data shape per chart type at both resolutions, alphabetical by class name.

Chart 640×480 ms 1920×1080 ms 1080p ops/sec
AreaChart 24 76 13
BarChart 39 84 12
BoxPlot 16 60 17
BubbleChart 13 62 16
ContourChart 9 52 19
Funnel 14 52 19
GanttChart 18 61 16
GaugeChart 10 60 17
Heatmap 9 56 18
LineChart 21 66 15
LinearMeter 9 50 20
PieChart 13 59 17
PolarChart 10 53 19
RadarChart 15 61 16
ScatterChart 17 60 17
StockChart 21 68 15
SurfaceChart 8 50 20
Treemap 18 60 17
Waterfall 18 61 16

Every chart type renders in under 100 ms at 1920×1080 on one thread. At dashboard-tile size (640×480), the lighter chart types break 100 renders per second per core.

Repro the numbers locally:

php -d extension=gd -d extension=./modules/fastchart.so \
    docs/bench/bench.php

Iteration counts via FC_BENCH_SMALL_ITERS (default 200) and FC_BENCH_LARGE_ITERS (default 50). Bench source at docs/bench/bench.php.

What you can render

19 chart classes, all under the FastChart\ namespace. Each name links to its rendered example image:

Cross-cutting features available on most chart types:

  • TrueType / OpenType labels via setFontPath() (and per-role setTitleFont(), setAxisFont(), setLabelFont()).
  • Light and dark themes (THEME_LIGHT, THEME_DARK); per-series colors via setSeriesColors(); full custom palettes via setPalette().
  • Legend positioning (LEGEND_TOP_RIGHT, _TOP_LEFT, _BOTTOM_RIGHT, _BOTTOM_LEFT, _NONE).
  • Annotations: plot bands, vertical bands, horizontal / vertical lines, text labels, icon plots, error bars, zones.
  • Strict-mode input validation (setStrict(true) rejects malformed series with a TypeError instead of silently coercing to NaN).
  • Background images, drop shadows, anti-aliased lines and markers.
  • Image map output (getImageMap() returns category-aligned rectangles for HTML overlay).

Examples

A gallery of code + rendered chart pairs lives in docs/README.md. Forty runnable scripts in docs/examples/ regenerate the images and exercise every public method on the API surface.

Public classes

All under the FastChart\ namespace:

  • Chart: abstract base. Carries shared geometry / theme / font / legend / annotation setters, the version() static, and the chart- family enums (themes, candle styles, legend positions, line styles, marker styles, MA kinds).
  • LineChart, AreaChart, BarChart, ScatterChart, BubbleChart: series-based plots.
  • PieChart: slice-based, with optional donut hole.
  • StockChart: OHLC(V) candlesticks, moving-average overlays, volume + indicator panes.
  • RadarChart, PolarChart, SurfaceChart, ContourChart: non-Cartesian plots.
  • GaugeChart, LinearMeter: single-value readouts with zoned ranges.
  • GanttChart: time-axis task bars with dependency links and milestones.
  • BoxPlot: five-number summaries with per-category outliers.
  • Treemap, Funnel, Waterfall: value-encoded layouts (rectangle packing, stage drop-off, signed-delta running totals).
  • Heatmap: 2D grid with linear color-ramp interpolation.

Every setter returns static, so a single fluent expression configures and emits a chart. draw($canvas) returns the same \GdImage for the same reason.

🔗 PHP Performance Toolkit

Companion native PHP extensions for high-throughput PHP workloads:

  • php_excel: native Excel I/O. 7-10× faster than PhpSpreadsheet, full XLS/XLSX with formulas, formatting, and styling. Powered by LibXL.
  • mdparser: native CommonMark + GFM parser. 15-30× faster than pure-PHP alternatives, full CommonMark 0.31 compliance.
  • php_clickhouse: native ClickHouse client speaking the wire protocol directly. Picks up where SeasClick left off.

License

BSD 3-Clause. See LICENSE.

Follow @iliaa on XBlog • If this saved you a chart-rendering microservice, ⭐ star it!