{"id":50962819,"url":"https://github.com/iliaal/fastchart","last_synced_at":"2026-06-18T16:30:47.235Z","repository":{"id":355967416,"uuid":"1230453222","full_name":"iliaal/fastchart","owner":"iliaal","description":"Fast chart rendering for PHP as a native extension. SVG-canonical, 26 chart families + barcodes (Code128, QrCode). PNG/JPEG/WebP","archived":false,"fork":false,"pushed_at":"2026-06-09T19:53:11.000Z","size":36414,"stargazers_count":29,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-06-09T21:20:49.938Z","etag":null,"topics":["barcode","chart","charts","code128","graph","graphics","php","php-extension","qrcode","svg","visualization"],"latest_commit_sha":null,"homepage":"https://iliaal.github.io/fastchart/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/iliaal.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-06T02:31:11.000Z","updated_at":"2026-06-09T19:53:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/iliaal/fastchart","commit_stats":null,"previous_names":["iliaal/fastchart"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/iliaal/fastchart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliaal%2Ffastchart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliaal%2Ffastchart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliaal%2Ffastchart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliaal%2Ffastchart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iliaal","download_url":"https://codeload.github.com/iliaal/fastchart/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iliaal%2Ffastchart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34499403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["barcode","chart","charts","code128","graph","graphics","php","php-extension","qrcode","svg","visualization"],"created_at":"2026-06-18T16:30:46.233Z","updated_at":"2026-06-18T16:30:47.222Z","avatar_url":"https://github.com/iliaal.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fastchart\n\n[![Tests](https://github.com/iliaal/fastchart/actions/workflows/tests.yml/badge.svg)](https://github.com/iliaal/fastchart/actions/workflows/tests.yml)\n[![Version](https://img.shields.io/github/v/tag/iliaal/fastchart?label=version\u0026sort=semver)](https://github.com/iliaal/fastchart/releases)\n[![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD--3--Clause-green.svg)](https://opensource.org/licenses/BSD-3-Clause)\n[![Follow @iliaa](https://img.shields.io/badge/Follow-@iliaa-000000?style=flat\u0026logo=x\u0026logoColor=white)](https://x.com/intent/follow?screen_name=iliaa)\n\nNative C PHP extension. 26 chart types behind a modern OO API with\nfluent setters and `final` classes. Line, area, bar, scatter, bubble,\npie, radar, polar, surface, contour, gauge, gantt, box-plot, treemap,\nfunnel, waterfall, heatmap, linear meter, plus a deep `StockChart`\n(seven candle styles, SMA / EMA / WMA overlays, volume + indicator\npanes).\n\nSVG is the canonical render format. PNG / JPG / WebP outputs flatten\ntext to glyph paths, run plutovg over the resulting SVG, and encode\nthe RGBA buffer with libpng / libjpeg-turbo / libwebp. The same chart\nobject serves a sharp `\u003csvg\u003e` for dashboards or a PNG for emails\nwithout rebuilding state. `renderToFile()` picks the encoder from the\nextension; `renderPng()` / `renderJpeg()` / `renderWebp()` /\n`renderSvg()` return bytes in-process.\n\n![fastchart: 26 chart types in one PHP extension](images/fastchart-hero.jpg)\n\n**[Live gallery →](https://iliaal.github.io/fastchart/v1-gallery.html)**. Side-by-side SVG / PNG / JPG / WebP renders for every chart family, with the source PHP shown above each row.\n\n## Status\n\nv1.1: confidence-band area charts, cone-style funnels, smooth polar\ncurves with overlay vectors, log-scale bubble plots, HTML image-map\nhot-spots on Bar / Pie / Scatter (`setImageMap` + `getImageMap`).\nv1.0 dropped libgd as a runtime dependency, rebuilt rasterization\naround vendored plutovg, and replaced `draw($canvas)` with\n`renderSvg/Png/Jpeg/Webp` + `renderToFile`. 26 chart types, 2-class\nSymbol family, 138 phpt tests. See [`CHANGELOG.md`](CHANGELOG.md)\nfor the full breaking-change list.\n\n## Install\n\n### Via PIE (recommended)\n\n[PIE](https://github.com/php/pie) handles the configure / make /\ninstall cycle for you against your active PHP install:\n\n```sh\npie install iliaal/fastchart\n```\n\nPIE picks up the latest tagged release from Packagist and respects\nyour platform's `pkg-config` for the FreeType / libpng /\nlibjpeg-turbo / libwebp probes. After install, enable the\nextension via your distribution's mechanism (e.g.\n`docker-php-ext-enable fastchart` on the official PHP images, or\nadd `extension=fastchart` to `php.ini`).\n\n### From source\n\nBuild manually against the PHP install you want to extend:\n\n```sh\nphpize\n./configure --enable-fastchart\nmake -j\nmake test\n```\n\nStrict-warnings dev build (recommended for contributors):\n\n```sh\n./configure --enable-fastchart --enable-fastchart-dev\n```\n\nRuntime check:\n\n```sh\nphp -d extension=./modules/fastchart.so \\\n  -r 'echo FastChart\\Chart::version(), PHP_EOL;'\n```\n\n## Requirements\n\n- PHP 8.1 or later (NTS or ZTS).\n- **FreeType** development headers (`libfreetype-dev` /\n  `freetype-devel`). Required, since text rendering depends on FreeType.\n- **libpng / libjpeg-turbo / libwebp** development headers. Each is\n  optional; config.m4 probes them independently via pkg-config and\n  the corresponding `renderPng()` / `renderJpeg()` / `renderWebp()`\n  is wired up only for libs that resolve at build time. A missing\n  lib turns the matching method into a \"format not compiled in\"\n  Error at call time; SVG output stays available regardless.\n  `phpinfo()` reports the resolved version of each lib (or `(not\n  compiled in)`) so you can audit a build.\n- plutovg + plutosvg are vendored under `vendor/`; no separate install\n  required.\n\n## Quick start\n\nThe shortest path is the `renderToFile()` helper, which picks the\nencoder from the file extension:\n\n```php\n(new FastChart\\LineChart(640, 320))\n    -\u003esetTitle('Daily active users')\n    -\u003esetSeries([['data' =\u003e [820, 940, 870, 1020, 1180, 1250, 1340]]])\n    -\u003esetCategoryLabels(['Mon','Tue','Wed','Thu','Fri','Sat','Sun'])\n    -\u003erenderToFile('/tmp/dau.png');\n```\n\n`renderPng()`, `renderJpeg()`, and `renderWebp()` return the encoded\nbytes if you need them in memory. Raster compression knobs:\n\n```php\n$chart-\u003esetJpegQuality(75);              // sticks on the chart instance;\n$chart-\u003erenderJpeg();                    // ...used by every render call\n$chart-\u003erenderJpeg(95);                  // per-call override (1..100)\n\n$chart-\u003erenderWebp();                    // default quality 90\n$chart-\u003erenderWebp(60);                  // smaller, lossier (1..100)\n\n$chart-\u003erenderToFile('/tmp/out.webp');   // setJpegQuality only affects\n                                         // .jpg; renderToFile uses the\n                                         // built-in WebP default\n```\n\nPNG is always lossless; there's no quality knob. The encoder is\nlibpng with default filter selection.\n\nWebP has four encoder modes selectable via `setWebpMode()`. The\ndefault `WEBP_DRAWING` is tuned for chart-shaped content (flat\nfills, sharp edges); see the table in\n[`docs/examples/50_webp_modes.php`](docs/examples/50_webp_modes.php)\nfor the speed/size trade-offs each mode picks.\n\n```php\n$chart-\u003esetWebpMode(FastChart\\Chart::WEBP_LOSSLESS);  // archival\n$chart-\u003esetWebpMode(FastChart\\Chart::WEBP_FAST);      // preview pipelines\n$chart-\u003esetWebpMode(FastChart\\Chart::WEBP_PHOTO);     // photo backgrounds\n$chart-\u003esetWebpMode(FastChart\\Chart::WEBP_DRAWING);   // back to default\n```\n\nCall `renderSvg()` on the same chart object for vector output:\ndashboards, print, anywhere infinite-zoom matters.\n\n```php\n$chart = (new FastChart\\LineChart(640, 320))\n    -\u003esetTitle('Daily active users')\n    -\u003esetSeries([['data' =\u003e [820, 940, 870, 1020, 1180, 1250, 1340]]])\n    -\u003esetCategoryLabels(['Mon','Tue','Wed','Thu','Fri','Sat','Sun']);\n\n$svg = $chart-\u003erenderSvg();              // full \u003c?xml ?\u003e\u003csvg\u003e...\u003c/svg\u003e\n$chart-\u003erenderToFile('/tmp/dau.svg');    // same, written to disk\n\n// Stitch several charts into one outer SVG document:\n$fragment = $chart-\u003edrawSvgFragment();   // \u003cg class=\"fastchart\"\u003e...\u003c/g\u003e\n```\n\nConstruction is identical for every output format; only the final\nrender call differs. By default, SVG text is flattened to glyph\noutline paths (`SVG_TEXT_PATHS` mode). The resulting SVG is self-\ncontained and renders identically in any viewer or rasterizer.\nFor smaller files with selectable text, switch to native `\u003ctext\u003e`\nmode:\n\n```php\n$chart-\u003esetSvgTextMode(FastChart\\Chart::SVG_TEXT_NATIVE);\n$svg = $chart-\u003erenderSvg();  // ~30% smaller; needs consumer text support\n```\n\nRaster outputs (PNG/JPG/WebP) always use the PATHS mode internally;\nplutovg has no text support of its own, so glyph flattening is what\nmakes labels appear in the rasterized output.\n\nPDF is a second vector format, available when the extension is built\nwith `--with-pdfio` (it links a system [pdfio](https://www.msweet.org/pdfio);\noff by default). Chart bodies emit PDF path operators directly — no\nrasterization — so every chart class renders as sharp vector output:\n\n```php\n$pdf = $chart-\u003erenderPdf();              // PDF document bytes\n$chart-\u003erenderToFile('/tmp/dau.pdf');    // inferred from the extension\n```\n\nWithout `--with-pdfio`, both methods throw `\"PDF support not compiled\nin\"`. This first cut falls back to solid fills for gradients, omits\nraster background images, and renders fills opaque (alpha is ignored).\n\nThree static methods on `FastChart\\Chart` rasterize caller-supplied\nSVG bytes through the same plutovg + libpng / libjpeg-turbo /\nlibwebp pipeline. Useful for round-tripping `renderSvg()` output, or\nfor stitching multiple `drawSvgFragment()` calls into one outer SVG\nand rasterizing the result, all in-process:\n\n```php\n$png  = FastChart\\Chart::svgToPng($svg);\n$jpg  = FastChart\\Chart::svgToJpeg($svg, 88, 0xFFFFFF);  // bg + quality\n$webp = FastChart\\Chart::svgToWebp($svg, 90, FastChart\\Chart::WEBP_LOSSLESS);\n```\n\nOutput dimensions come from the SVG's `width` / `height` / `viewBox`.\nSVG `\u003ctext\u003e` elements render blank because plutovg has no text\nengine, so text must be path-flattened first (fastchart's own SVG\nbuilder does this automatically). See\n[`docs/examples/51_svg_to_raster.php`](docs/examples/51_svg_to_raster.php)\nfor a runnable demo and\n[`docs/specs/svg-to-raster.md`](docs/specs/svg-to-raster.md) for the\nfull contract.\n\n## 📊 Performance\n\nMedian in-memory render time at 1920×1080 on a single core (Intel\ni9-13950HX, PHP 8.4 release build NTS -O2, default font + DPI).\nSVG is the canonical output; PNG / WebP / JPG go through the same\nSVG build, then plutosvg + plutovg rasterize, then the format\nencoder (libpng / libwebp / libjpeg-turbo). The raster columns\ntherefore add the rasterize cost on top of the SVG-only number.\n\n| Chart        | SVG ms | PNG ms | WebP ms | JPG ms |\n|--------------|-------:|-------:|--------:|-------:|\n| AreaChart    |   0.12 |  45.19 |   34.04 |  11.45 |\n| BarChart     |   0.22 |  43.54 |   35.18 |  12.35 |\n| BoxPlot      |   0.09 |  40.26 |   30.74 |   9.95 |\n| BubbleChart  |   0.06 |  52.84 |   44.18 |  14.84 |\n| ContourChart |   0.11 |  48.46 |   41.14 |  12.97 |\n| Funnel       |   0.08 |  40.15 |   31.59 |   9.53 |\n| GanttChart   |   0.12 |  40.08 |   30.98 |  10.22 |\n| GaugeChart   |   0.02 |  44.75 |   33.78 |  10.19 |\n| Heatmap      |   0.05 |  43.28 |   35.62 |  11.85 |\n| LineChart    |   0.11 |  45.45 |   37.23 |  11.81 |\n| LinearMeter  |   0.02 |  38.64 |   29.10 |   8.98 |\n| PieChart     |   0.06 |  44.42 |   33.84 |  11.75 |\n| PolarChart   |   0.02 |  47.60 |   37.10 |  11.48 |\n| RadarChart   |   0.06 |  47.89 |   36.48 |  13.39 |\n| ScatterChart |   0.11 |  43.05 |   32.48 |  10.38 |\n| StockChart   |   0.20 |  46.00 |   40.86 |  14.19 |\n| SurfaceChart |   0.06 |  40.09 |   34.50 |  10.35 |\n| Treemap      |   0.11 |  39.76 |   31.74 |   9.74 |\n| Waterfall    |   0.09 |  39.21 |   32.05 |  10.08 |\n\nSVG stays well under a quarter-millisecond across the board (0.02 to\n0.22 ms) because there's no rasterization; the backend appends strings\ninto a `smart_str` via an allocation-free integer/fraction number\nemitter.\nThe raster encoders split into three bands: JPG fastest (9-15 ms,\nlibjpeg-turbo with 4:2:0 subsampling + SSSE3/NEON RGBA-pack), WebP\nmiddle (29-44 ms, libwebp with `WEBP_PRESET_DRAWING` + method=2 +\nmulti-thread), PNG slowest (38-53 ms, libpng's deflate dominates).\nAll four formats stay under 55 ms at 1080p on one thread.\n\nThese numbers reflect the optimization series in v1.1.x (allocation-free\nSVG number formatting, glyph outline cache, opaque-detect un-premultiply\nwith SSSE3/NEON shuffle, deferred text overlays, larger FT raster pool);\nsee\n[`optimization.md`](optimization.md) for the per-finding breakdown.\n\nRepro the numbers locally:\n\n```sh\nphp -d extension=./modules/fastchart.so docs/bench/bench.php\n```\n\nIteration count via `FC_BENCH_ITERS` (default 50). Bench source at\n[`docs/bench/bench.php`](docs/bench/bench.php).\n\n## What you can render\n\n26 chart classes plus a 2-class symbology family, all under the\n`FastChart\\` namespace. Each name links to its rendered example image:\n\n- **Cartesian:** [`LineChart`](docs/examples/01_line_basic.png),\n  [`AreaChart`](docs/examples/27a_area_stacked.png),\n  [`BarChart`](docs/examples/03_bar_grouped.png) (vertical, horizontal,\n  stacked, grouped, floating, layered),\n  [`ScatterChart`](docs/examples/06_scatter_trend.png),\n  [`BubbleChart`](docs/examples/14_bubble.png).\n- **Financial:** [`StockChart`](docs/examples/07_stock_candle_ma.png)\n  with seven candle styles (`STYLE_CANDLE`, `STYLE_BAR`,\n  `STYLE_DIAMOND`, `STYLE_I_CAP`, `STYLE_HOLLOW`, `STYLE_VOLUME`,\n  `STYLE_VECTOR`), SMA / EMA / WMA overlays, optional volume pane and\n  custom indicator panes (RSI, MACD, Bollinger, OBV, stochastic, PSAR).\n- **Non-Cartesian:** [`RadarChart`](docs/examples/08_radar.png),\n  [`PolarChart`](docs/examples/16_polar.png),\n  [`SurfaceChart`](docs/examples/15a_surface.png),\n  [`ContourChart`](docs/examples/15b_contour.png).\n- **Specialised:** [`PieChart`](docs/examples/05_pie_donut.png) (with\n  optional donut hole + leader lines),\n  [`GaugeChart`](docs/examples/10_gauge.png),\n  [`LinearMeter`](docs/examples/36a_linear_meter_horizontal.png),\n  [`GanttChart`](docs/examples/17_gantt.png),\n  [`BoxPlot`](docs/examples/09_boxplot.png),\n  [`Treemap`](docs/examples/32_treemap.png),\n  [`Funnel`](docs/examples/33_funnel.png),\n  [`Waterfall`](docs/examples/34_waterfall.png),\n  [`Heatmap`](docs/examples/35_heatmap.png),\n  [`BulletChart`](docs/examples/43_bullet.png),\n  [`ParetoChart`](docs/examples/44_pareto.png),\n  [`CalendarHeatmap`](docs/examples/45_calendar_heatmap.png).\n- **Hierarchical / flow:**\n  [`SunburstChart`](docs/examples/46_sunburst.png),\n  [`SankeyChart`](docs/examples/47_sankey.png),\n  [`MarimekkoChart`](docs/examples/48_marimekko.png),\n  [`VectorChart`](docs/examples/49_vector.png).\n- **Symbology:** [`Code128`](docs/examples/41a_code128_alphanumeric.png)\n  (1D barcode, ISO/IEC 15417, auto-switching A/B/C subsets, optional\n  human-readable text), [`QrCode`](docs/examples/42b_qrcode_ecc_m.png)\n  (2D matrix code, ISO/IEC 18004, ECC L/M/Q/H, versions 1..40).\n\nCross-cutting features available on most chart types:\n\n- TrueType / OpenType labels via `setFontPath()` (and per-role\n  `setTitleFont()`, `setAxisFont()`, `setLabelFont()`).\n- Light and dark themes (`THEME_LIGHT`, `THEME_DARK`); per-series colors\n  via `setSeriesColors()`; full custom palettes via `setPalette()`.\n- Legend positioning (`LEGEND_TOP_RIGHT`, `_TOP_LEFT`, `_BOTTOM_RIGHT`,\n  `_BOTTOM_LEFT`, `_NONE`).\n- Annotations: plot bands, vertical bands, horizontal / vertical lines,\n  text labels, icon plots, error bars, zones.\n- Strict-mode input validation (`setStrict(true)` rejects malformed\n  series with a `TypeError` instead of silently coercing to NaN).\n- Background images, drop shadows, anti-aliased lines and markers.\n- Image map output: `getImageMap()` returns category-aligned\n  rectangles for HTML overlay; `getImageMapAreas()` returns the same\n  hot-spots as structured array data.\n\n## Examples\n\nA gallery of code + rendered chart pairs lives in\n[`docs/README.md`](docs/README.md). Forty-two runnable scripts in\n[`docs/examples/`](docs/examples/) regenerate the images and exercise\nevery public method on the API surface.\n\n## Public classes\n\nAll under the `FastChart\\` namespace:\n\n- `Chart`: abstract base. Carries shared geometry / theme / font /\n  legend / annotation setters, the `version()` static, and the chart-\n  family enums (themes, candle styles, legend positions, line styles,\n  marker styles, MA kinds).\n- `LineChart`, `AreaChart`, `BarChart`, `ScatterChart`,\n  `BubbleChart`: series-based plots.\n- `PieChart`: slice-based, with optional donut hole.\n- `StockChart`: OHLC(V) candlesticks, moving-average overlays,\n  volume + indicator panes.\n- `RadarChart`, `PolarChart`, `SurfaceChart`,\n  `ContourChart`: non-Cartesian plots.\n- `GaugeChart`, `LinearMeter`: single-value readouts with zoned ranges.\n- `GanttChart`: time-axis task bars with dependency links and\n  milestones.\n- `BoxPlot`: five-number summaries with per-category outliers.\n- `Treemap`, `Funnel`, `Waterfall`: value-encoded layouts (rectangle\n  packing, stage drop-off, signed-delta running totals). `Funnel`\n  supports a triangle-with-bands layout via `setStyle(STYLE_PYRAMID)`\n  for callers who want the classic pyramid shape.\n- `Heatmap`: 2D grid with linear color-ramp interpolation.\n\nEvery setter returns `static`, so a single fluent expression configures\nand emits a chart.\n\nThe Symbol family lives parallel to `Chart` (no shared base, since\naxes / palettes / plot rect have no meaning for a barcode):\n\n- `Symbol`: abstract base for all 1D + 2D codes. Carries shared\n  setters: `setSize()`, `setData()`, `setQuietZone()`, `setForeground()`,\n  `setBackground()`, `setTransparentBackground()`, `setDpi()`,\n  `setSvgTextMode()`, `setJpegQuality()`, plus the same `renderPng()`\n  / `renderJpeg()` / `renderWebp()` / `renderSvg()` /\n  `drawSvgFragment()` / `renderToFile()` helpers as `Chart`. Reload\n  via `imagecreatefromstring()` to composite onto an existing canvas.\n- `Barcode`: abstract 1D linear-barcode base.\n- `Code128` (extends `Barcode`): ISO/IEC 15417, alphanumeric, three\n  subsets (A: control + uppercase, B: full ASCII printable, C: digit\n  pairs). Auto-switches between subsets to minimise encoded length;\n  mod-103 checksum appended automatically. `setShowText(true)`\n  renders the human-readable payload below the bars using the\n  auto-detected default font.\n- `QrCode` (extends `Symbol`): ISO/IEC 18004, four error-correction\n  levels (`ECC_L` ~7%, `ECC_M` ~15%, `ECC_Q` ~25%, `ECC_H` ~30%),\n  versions 1..40. Encoder is the vendored nayuki/QR-Code-generator\n  C library. `setMinVersion()` / `setMaxVersion()` pin the symbol\n  size; the encoder picks the smallest version that fits within the\n  range. Input must be valid UTF-8.\n\n## 🔗 PHP Performance Toolkit\n\nCompanion native PHP extensions for high-throughput PHP workloads:\n\n- **[php_excel](https://github.com/iliaal/php_excel)**: native Excel I/O. 7-10× faster than PhpSpreadsheet, full XLS/XLSX with formulas, formatting, and styling. Powered by LibXL.\n- **[mdparser](https://github.com/iliaal/mdparser)**: native CommonMark + GFM parser. 15-30× faster than pure-PHP alternatives, full CommonMark 0.31 compliance.\n- **[php_clickhouse](https://github.com/iliaal/php_clickhouse)**: native ClickHouse client speaking the wire protocol directly. Picks up where SeasClick left off.\n\n## License\n\nBSD 3-Clause for the extension itself; see [`LICENSE`](LICENSE).\nVendored third-party code (all MIT):\n\n- `vendor/plutovg/`: Samuel Ugochukwu's\n  [plutovg](https://github.com/sammycage/plutovg) 2D rasterizer.\n  See [`vendor/plutovg/LICENSE`](vendor/plutovg/LICENSE).\n- `vendor/plutosvg/`: Samuel Ugochukwu's\n  [plutosvg](https://github.com/sammycage/plutosvg) SVG document\n  parser. See [`vendor/plutosvg/LICENSE`](vendor/plutosvg/LICENSE).\n- `vendor/qrcodegen/`: nayuki's\n  [QR-Code-generator](https://github.com/nayuki/QR-Code-generator)\n  (C variant). See [`vendor/qrcodegen/LICENSE`](vendor/qrcodegen/LICENSE).\n\nSPDX: `(BSD-3-Clause AND MIT)`.\n\n---\n\n[Follow @iliaa on X](https://x.com/iliaa) • [Blog](https://ilia.ws/blog/fastchart-1-x-why-i-rewrote-it-after-0-2-release) • If this saved you a chart-rendering microservice, ⭐ star it!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filiaal%2Ffastchart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Filiaal%2Ffastchart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Filiaal%2Ffastchart/lists"}