chartjs2img 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -30
- package/dist/cache.d.ts +1 -1
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +3 -0
- package/dist/cache.js.map +1 -1
- package/dist/chart-registry.d.ts +6 -0
- package/dist/chart-registry.d.ts.map +1 -0
- package/dist/chart-registry.js +60 -0
- package/dist/chart-registry.js.map +1 -0
- package/dist/engine-skia.d.ts +8 -0
- package/dist/engine-skia.d.ts.map +1 -0
- package/dist/engine-skia.js +149 -0
- package/dist/engine-skia.js.map +1 -0
- package/dist/lib.d.ts +2 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +12 -1
- package/dist/renderer.js.map +1 -1
- package/dist/skia-polyfills.d.ts +3 -0
- package/dist/skia-polyfills.d.ts.map +1 -0
- package/dist/skia-polyfills.js +55 -0
- package/dist/skia-polyfills.js.map +1 -0
- package/dist/template.d.ts +11 -0
- package/dist/template.d.ts.map +1 -1
- package/dist/template.js +8 -0
- package/dist/template.js.map +1 -1
- package/package.json +27 -5
- package/src/index.ts +22 -4
package/README.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# chartjs2img
|
|
2
2
|
|
|
3
|
-
Server-side Chart.js rendering service. Takes a Chart.js configuration as JSON, renders it to an image
|
|
3
|
+
Server-side Chart.js rendering service. Takes a Chart.js configuration as JSON, renders it to an image, and returns the result. Ships as an HTTP API, a CLI, and a TypeScript / Node library.
|
|
4
|
+
|
|
5
|
+
Two rendering engines are built in:
|
|
6
|
+
|
|
7
|
+
- **`skia`** *(default)* — [skia-canvas](https://github.com/samizdatco/skia-canvas). Renders in-process with **no browser**: fast (tens of ms per chart), small footprint, nothing to launch. Chart.js and every bundled plugin run against a native Skia canvas.
|
|
8
|
+
- **`browser`** — headless Chromium via `puppeteer-core`. Maximum fidelity / real-browser pixel parity and DOM-dependent behavior. Chromium is installed automatically on first use of this engine.
|
|
9
|
+
|
|
10
|
+
Pick per render: `engine: 'skia' | 'browser'` (library), `--engine` (CLI), or the `engine` field (HTTP). The default is `skia`, so the common path needs no browser at all.
|
|
4
11
|
|
|
5
12
|
Built for generating charts in contexts where a browser isn't available — email campaigns, PowerPoint generation, PDF reports, Slack bots, LLM tool calls, etc.
|
|
6
13
|
|
|
@@ -8,6 +15,7 @@ Full documentation (EN / JA): <https://chartjs2img.ideamans.com>
|
|
|
8
15
|
|
|
9
16
|
## Features
|
|
10
17
|
|
|
18
|
+
- **Two rendering engines** — `skia` (default, no browser) and `browser` (headless Chromium), selectable per render (see [Rendering Engines](#rendering-engines))
|
|
11
19
|
- **Chart.js 4.4 + 11 plugins + date-fns adapter** built-in (see [Included Plugins](#included-plugins))
|
|
12
20
|
- **HTTP API** — POST JSON, get an image back
|
|
13
21
|
- **CLI** — pipe JSON in, get an image out
|
|
@@ -41,9 +49,48 @@ Verify it's working:
|
|
|
41
49
|
bun --version
|
|
42
50
|
```
|
|
43
51
|
|
|
44
|
-
##
|
|
52
|
+
## Rendering Engines
|
|
53
|
+
|
|
54
|
+
Every render runs on one of two engines. The default is `skia`.
|
|
55
|
+
|
|
56
|
+
| | `skia` *(default)* | `browser` |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| Backend | skia-canvas (native Skia, in-process) | headless Chromium (`puppeteer-core`) |
|
|
59
|
+
| Browser needed | **No** | Yes (auto-installed on first use) |
|
|
60
|
+
| Speed | Fast — tens of ms/chart, no process launch | Slower — browser startup + page load |
|
|
61
|
+
| Fidelity | Matches the browser for all 35 built-in examples | Real-browser pixel parity, reference |
|
|
62
|
+
| Plugins | Bundled from npm | Loaded from CDN inside the page |
|
|
63
|
+
| Best for | Default / high throughput / no-browser hosts | Exact pixel parity, DOM-dependent needs |
|
|
64
|
+
|
|
65
|
+
Select the engine per render:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# CLI
|
|
69
|
+
chartjs2img render -i chart.json -o chart.png --engine skia # default
|
|
70
|
+
chartjs2img render -i chart.json -o chart.png --engine browser
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
// Library
|
|
75
|
+
await renderChart({ chart, engine: 'skia' }) // default
|
|
76
|
+
await renderChart({ chart, engine: 'browser' })
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
// HTTP POST /render body
|
|
81
|
+
{ "chart": { }, "engine": "skia" }
|
|
82
|
+
```
|
|
45
83
|
|
|
46
|
-
|
|
84
|
+
Notes on the `skia` engine:
|
|
85
|
+
|
|
86
|
+
- `chartjs-plugin-zoom` is **not** included (it is an interaction-only plugin that needs a live DOM); use the `browser` engine if you rely on it.
|
|
87
|
+
- In a `bun build --compile` standalone binary, `euler` / `venn` charts fall back to an ellipse renderer (minor overlap-fill artifacts) due to a skia-canvas quirk under the compiled runtime. `bun run`, the npm library, and the server render them at full fidelity.
|
|
88
|
+
|
|
89
|
+
The two engines cache independently (the cache hash includes the engine).
|
|
90
|
+
|
|
91
|
+
## Chrome / Chromium (browser engine)
|
|
92
|
+
|
|
93
|
+
The `browser` engine requires Chrome or Chromium. (The default `skia` engine does **not** — you can skip this entirely if you only use `skia`.) On first use of the `browser` engine, chartjs2img searches for an existing installation in this order:
|
|
47
94
|
|
|
48
95
|
1. `CHROMIUM_PATH` environment variable
|
|
49
96
|
2. `ms-playwright` browser cache (`~/Library/Caches/ms-playwright/` etc. — reused if a prior Playwright install is present)
|
|
@@ -77,7 +124,7 @@ This installs the Node.js packages. Bun uses `node_modules` just like npm, but i
|
|
|
77
124
|
|
|
78
125
|
### 2. Start the development server
|
|
79
126
|
|
|
80
|
-
> **Zero-config:**
|
|
127
|
+
> **Zero-config:** The default `skia` engine needs no browser at all. If you request the `browser` engine, Chromium is downloaded automatically on first use if not found (~250 MB one-time download) — no manual install needed.
|
|
81
128
|
|
|
82
129
|
```bash
|
|
83
130
|
bun run dev
|
|
@@ -165,7 +212,8 @@ Render a chart from a JSON body.
|
|
|
165
212
|
"devicePixelRatio": 1,
|
|
166
213
|
"backgroundColor": "white",
|
|
167
214
|
"format": "png",
|
|
168
|
-
"quality": 90
|
|
215
|
+
"quality": 90,
|
|
216
|
+
"engine": "skia"
|
|
169
217
|
}
|
|
170
218
|
```
|
|
171
219
|
|
|
@@ -178,6 +226,7 @@ Render a chart from a JSON body.
|
|
|
178
226
|
| `backgroundColor` | string | `"white"` | CSS background color (`"transparent"` supported) |
|
|
179
227
|
| `format` | string | `"png"` | Output format: `png` or `jpeg` |
|
|
180
228
|
| `quality` | number | 90 | JPEG quality (0-100) |
|
|
229
|
+
| `engine` | string | `"skia"` | Rendering engine: `skia` or `browser` |
|
|
181
230
|
|
|
182
231
|
**Response headers:**
|
|
183
232
|
|
|
@@ -322,6 +371,7 @@ bun run src/index.ts render -i chart.json -o chart.png -w 1200 -h 400 -f jpeg -q
|
|
|
322
371
|
| `--background-color <color>` | Background (default: white) |
|
|
323
372
|
| `-f, --format <fmt>` | png, jpeg (default: png) |
|
|
324
373
|
| `-q, --quality <0-100>` | JPEG quality (default: 90) |
|
|
374
|
+
| `--engine <engine>` | Rendering engine: skia, browser (default: skia) |
|
|
325
375
|
|
|
326
376
|
### Batch rendering built-in examples
|
|
327
377
|
|
|
@@ -347,7 +397,7 @@ This iterates the 35 bundled chart configs (the same set shown by `GET /examples
|
|
|
347
397
|
Use chartjs2img programmatically from any Bun or Node program:
|
|
348
398
|
|
|
349
399
|
```ts
|
|
350
|
-
import { renderChart, closeBrowser, computeHash, BUNDLED_LIBS, VERSION } from 'chartjs2img'
|
|
400
|
+
import { renderChart, closeBrowser, computeHash, DEFAULT_ENGINE, BUNDLED_LIBS, VERSION } from 'chartjs2img'
|
|
351
401
|
|
|
352
402
|
const result = await renderChart({
|
|
353
403
|
chart: {
|
|
@@ -360,12 +410,14 @@ const result = await renderChart({
|
|
|
360
410
|
width: 800,
|
|
361
411
|
height: 600,
|
|
362
412
|
format: 'png',
|
|
413
|
+
engine: 'skia', // default — omit for skia, or pass 'browser'
|
|
363
414
|
})
|
|
364
415
|
|
|
365
416
|
await Bun.write('chart.png', result.buffer)
|
|
366
417
|
if (result.messages.length) console.warn(result.messages)
|
|
367
418
|
|
|
368
|
-
// Call once on process shutdown
|
|
419
|
+
// Call once on process shutdown. A no-op if the browser engine was never
|
|
420
|
+
// used (the skia engine launches nothing to close).
|
|
369
421
|
await closeBrowser()
|
|
370
422
|
```
|
|
371
423
|
|
|
@@ -374,14 +426,15 @@ Exports:
|
|
|
374
426
|
| Symbol | Purpose |
|
|
375
427
|
|--------|---------|
|
|
376
428
|
| `renderChart(options)` | Render a single chart using a lazily-created default `Renderer` |
|
|
377
|
-
| `closeBrowser()` | Close the shared headless browser on shutdown |
|
|
429
|
+
| `closeBrowser()` | Close the shared headless browser on shutdown (no-op if only `skia` was used) |
|
|
378
430
|
| `rendererStats()` | Browser / concurrency / page counters (same shape as `/health`) |
|
|
379
431
|
| `Renderer` | Class for advanced callers that want isolated browser pools / concurrency |
|
|
380
432
|
| `computeHash(options)` | Deterministic hash of a render input (for your own cache layer) |
|
|
433
|
+
| `DEFAULT_ENGINE` | The engine used when none is specified (`'skia'`) |
|
|
381
434
|
| `BUNDLED_LIBS` | Frozen table of Chart.js + plugin versions baked into the page |
|
|
382
435
|
| `VERSION`, `NAME` | Package identification |
|
|
383
436
|
|
|
384
|
-
Types: `RenderOptions`, `RenderResult`, `ConsoleMessage`, `RendererConfig`, `RendererStats`.
|
|
437
|
+
Types: `RenderOptions`, `RenderResult`, `ConsoleMessage`, `RendererConfig`, `RendererStats`, `Engine`.
|
|
385
438
|
|
|
386
439
|
## Error Feedback
|
|
387
440
|
|
|
@@ -437,7 +490,7 @@ All settings can be configured via environment variables, making it easy to conf
|
|
|
437
490
|
|
|
438
491
|
## Included Plugins
|
|
439
492
|
|
|
440
|
-
|
|
493
|
+
Both engines bundle the same Chart.js + plugin versions: the `skia` engine imports them from npm, and the `browser` engine loads them from CDN inside the page. No extra installation needed. (`chartjs-plugin-zoom` runs on the `browser` engine only — see [Rendering Engines](#rendering-engines).)
|
|
441
494
|
|
|
442
495
|
### Core
|
|
443
496
|
|
|
@@ -494,8 +547,9 @@ docker run -p 3000:3000 \
|
|
|
494
547
|
|
|
495
548
|
The Docker image includes:
|
|
496
549
|
- Bun runtime
|
|
497
|
-
-
|
|
498
|
-
-
|
|
550
|
+
- skia-canvas (the default engine — works out of the box)
|
|
551
|
+
- Chromium (headless), for the `browser` engine
|
|
552
|
+
- Noto Sans CJK fonts (Japanese, Chinese, Korean — no tofu characters, used by both engines)
|
|
499
553
|
|
|
500
554
|
### Docker Compose
|
|
501
555
|
|
|
@@ -522,14 +576,16 @@ bun run build
|
|
|
522
576
|
bun build src/index.ts --compile --outfile chartjs2img
|
|
523
577
|
```
|
|
524
578
|
|
|
525
|
-
This produces a `./chartjs2img` binary that can be distributed without requiring Bun or Node.js on the target machine.
|
|
579
|
+
This produces a `./chartjs2img` binary that can be distributed without requiring Bun or Node.js on the target machine. The `skia` engine (native Skia canvas) is fully embedded — the binary renders every built-in example type on the default engine with no external dependencies.
|
|
526
580
|
|
|
527
|
-
> **Note:**
|
|
581
|
+
> **Note:** The `browser` engine's Chromium is **not** bundled into the binary, but it is **downloaded automatically** on first use if not found. For the default `skia` engine nothing extra is needed. (One caveat: `euler` / `venn` charts on the `skia` engine use an ellipse fallback inside the compiled binary — see [Rendering Engines](#rendering-engines).)
|
|
528
582
|
|
|
529
583
|
```bash
|
|
530
|
-
#
|
|
531
|
-
./chartjs2img serve --port 3000
|
|
584
|
+
# Default skia engine — no browser needed
|
|
532
585
|
./chartjs2img render -i chart.json -o chart.png
|
|
586
|
+
# Browser engine — Chromium auto-installs on first use
|
|
587
|
+
./chartjs2img render -i chart.json -o chart.png --engine browser
|
|
588
|
+
./chartjs2img serve --port 3000
|
|
533
589
|
```
|
|
534
590
|
|
|
535
591
|
## Claude Code Plugin
|
|
@@ -576,21 +632,20 @@ Request flow:
|
|
|
576
632
|
│ Acquired
|
|
577
633
|
▼
|
|
578
634
|
┌──────────┐
|
|
579
|
-
│
|
|
580
|
-
│
|
|
581
|
-
└──────────┘
|
|
582
|
-
│
|
|
583
|
-
▼
|
|
584
|
-
┌──────────┐
|
|
585
|
-
│ New Page │──▶ Fresh tab with 60s timeout
|
|
586
|
-
│ (Tab) │
|
|
587
|
-
└──────────┘
|
|
588
|
-
│
|
|
589
|
-
▼
|
|
590
|
-
┌──────────┐
|
|
591
|
-
│ Render │──▶ Load HTML + Chart.js + plugins
|
|
592
|
-
│ Chart │ Screenshot canvas element
|
|
635
|
+
│ Engine │──▶ skia (default) or browser?
|
|
636
|
+
│ Dispatch │
|
|
593
637
|
└──────────┘
|
|
638
|
+
│ │
|
|
639
|
+
skia ◀─────┘ └─────▶ browser
|
|
640
|
+
│ │
|
|
641
|
+
▼ ▼
|
|
642
|
+
┌──────────────┐ ┌──────────────┐
|
|
643
|
+
│ skia-canvas │ │ Ensure browser│──▶ launch/restart Chromium
|
|
644
|
+
│ Chart.js + │ │ New page (tab)│
|
|
645
|
+
│ plugins │ │ Load HTML + │
|
|
646
|
+
│ (in-process) │ │ Chart.js + │
|
|
647
|
+
│ toBuffer() │ │ plugins, shot │
|
|
648
|
+
└──────────────┘ └──────────────┘
|
|
594
649
|
│
|
|
595
650
|
▼
|
|
596
651
|
┌──────────┐
|
package/dist/cache.d.ts
CHANGED
package/dist/cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/D,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;CAClB;AA8BD,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAa1D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAQ7D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAOhF;AAED,wBAAgB,UAAU,IAAI;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAErF"}
|
package/dist/cache.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
+
import { DEFAULT_ENGINE } from './template';
|
|
2
3
|
const store = new Map();
|
|
3
4
|
/** Max cache entries (env: CACHE_MAX_ENTRIES, default: 1000) */
|
|
4
5
|
const MAX_ENTRIES = Number(process.env.CACHE_MAX_ENTRIES ?? '1000');
|
|
@@ -32,6 +33,8 @@ export function computeHash(options) {
|
|
|
32
33
|
backgroundColor: options.backgroundColor ?? 'white',
|
|
33
34
|
format: options.format ?? 'png',
|
|
34
35
|
quality: options.quality ?? 90,
|
|
36
|
+
// Engines can differ pixel-for-pixel, so they must cache separately.
|
|
37
|
+
engine: options.engine ?? DEFAULT_ENGINE,
|
|
35
38
|
});
|
|
36
39
|
return createHash('sha256').update(json).digest('hex').slice(0, 16);
|
|
37
40
|
}
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Chart, BasicPlatform } from 'chart.js';
|
|
2
|
+
import 'chartjs-adapter-date-fns';
|
|
3
|
+
/** Register Chart.js + all bundled plugins exactly once (idempotent). */
|
|
4
|
+
export declare function ensureRegistered(): void;
|
|
5
|
+
export { Chart, BasicPlatform };
|
|
6
|
+
//# sourceMappingURL=chart-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-registry.d.ts","sourceRoot":"","sources":["../src/chart-registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAiB,aAAa,EAAE,MAAM,UAAU,CAAA;AAU9D,OAAO,0BAA0B,CAAA;AA6BjC,yEAAyE;AACzE,wBAAgB,gBAAgB,IAAI,IAAI,CAkBvC;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Chart.js + plugin registration for the skia engine.
|
|
2
|
+
import { installSkiaPolyfills } from './skia-polyfills';
|
|
3
|
+
import { Chart, registerables, BasicPlatform } from 'chart.js';
|
|
4
|
+
// chart.js ships DISTINCT esm (dist/chart.js) and cjs (dist/chart.cjs) builds
|
|
5
|
+
// whose element classes are NOT `===`. chartjs-plugin-datalabels has no
|
|
6
|
+
// `exports` map, so a bare specifier resolves its CJS build under Node ESM,
|
|
7
|
+
// binding the CJS chart.js — then `el instanceof BarElement` is always false
|
|
8
|
+
// and bar labels mis-position. Import its ESM build explicitly so it binds the
|
|
9
|
+
// SAME chart.js instance we register into.
|
|
10
|
+
import ChartDataLabels from 'chartjs-plugin-datalabels/dist/chartjs-plugin-datalabels.esm.js';
|
|
11
|
+
import annotationPlugin from 'chartjs-plugin-annotation';
|
|
12
|
+
import gradient from 'chartjs-plugin-gradient';
|
|
13
|
+
import 'chartjs-adapter-date-fns';
|
|
14
|
+
import * as matrix from 'chartjs-chart-matrix';
|
|
15
|
+
import * as sankey from 'chartjs-chart-sankey';
|
|
16
|
+
import * as treemap from 'chartjs-chart-treemap';
|
|
17
|
+
import * as wordcloud from 'chartjs-chart-wordcloud';
|
|
18
|
+
import * as geo from 'chartjs-chart-geo';
|
|
19
|
+
import * as graph from 'chartjs-chart-graph';
|
|
20
|
+
import * as venn from 'chartjs-chart-venn';
|
|
21
|
+
// NOTE: chartjs-plugin-zoom is intentionally NOT bundled into the skia engine.
|
|
22
|
+
// It depends on Hammer.js, which touches `document.documentElement.style` at
|
|
23
|
+
// import time and expects a live DOM for gesture handling. Zoom is an
|
|
24
|
+
// interaction plugin with no effect on a static render, so the browser engine
|
|
25
|
+
// keeps it and the skia engine skips it.
|
|
26
|
+
function registerNamespace(mod) {
|
|
27
|
+
for (const v of Object.values(mod)) {
|
|
28
|
+
if (v && typeof v.id === 'string') {
|
|
29
|
+
try {
|
|
30
|
+
Chart.register(v);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// already registered
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let registered = false;
|
|
39
|
+
/** Register Chart.js + all bundled plugins exactly once (idempotent). */
|
|
40
|
+
export function ensureRegistered() {
|
|
41
|
+
// Install DOM globals before any plugin code can run. Safe to call every
|
|
42
|
+
// time (idempotent); doing it here means the polyfills are guaranteed in
|
|
43
|
+
// place before the first render regardless of import order or tree-shaking.
|
|
44
|
+
installSkiaPolyfills();
|
|
45
|
+
if (registered)
|
|
46
|
+
return;
|
|
47
|
+
registered = true;
|
|
48
|
+
Chart.register(...registerables);
|
|
49
|
+
for (const mod of [matrix, sankey, treemap, wordcloud, geo, graph, venn]) {
|
|
50
|
+
registerNamespace(mod);
|
|
51
|
+
}
|
|
52
|
+
Chart.register(annotationPlugin);
|
|
53
|
+
Chart.register(gradient);
|
|
54
|
+
Chart.register(ChartDataLabels);
|
|
55
|
+
// Match src/template.ts (the browser engine): datalabels hidden unless a
|
|
56
|
+
// chart explicitly turns it on.
|
|
57
|
+
Chart.defaults.set('plugins.datalabels', { display: false });
|
|
58
|
+
}
|
|
59
|
+
export { Chart, BasicPlatform };
|
|
60
|
+
//# sourceMappingURL=chart-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-registry.js","sourceRoot":"","sources":["../src/chart-registry.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC9D,8EAA8E;AAC9E,wEAAwE;AACxE,4EAA4E;AAC5E,6EAA6E;AAC7E,+EAA+E;AAC/E,2CAA2C;AAC3C,OAAO,eAAe,MAAM,iEAAiE,CAAA;AAC7F,OAAO,gBAAgB,MAAM,2BAA2B,CAAA;AACxD,OAAO,QAAQ,MAAM,yBAAyB,CAAA;AAC9C,OAAO,0BAA0B,CAAA;AACjC,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,MAAM,MAAM,sBAAsB,CAAA;AAC9C,OAAO,KAAK,OAAO,MAAM,uBAAuB,CAAA;AAChD,OAAO,KAAK,SAAS,MAAM,yBAAyB,CAAA;AACpD,OAAO,KAAK,GAAG,MAAM,mBAAmB,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,IAAI,MAAM,oBAAoB,CAAA;AAE1C,+EAA+E;AAC/E,6EAA6E;AAC7E,sEAAsE;AACtE,8EAA8E;AAC9E,yCAAyC;AAEzC,SAAS,iBAAiB,CAAC,GAA4B;IACrD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,OAAQ,CAAsB,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YACxD,IAAI,CAAC;gBACH,KAAK,CAAC,QAAQ,CAAC,CAAyC,CAAC,CAAA;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,IAAI,UAAU,GAAG,KAAK,CAAA;AAEtB,yEAAyE;AACzE,MAAM,UAAU,gBAAgB;IAC9B,yEAAyE;IACzE,yEAAyE;IACzE,4EAA4E;IAC5E,oBAAoB,EAAE,CAAA;IACtB,IAAI,UAAU;QAAE,OAAM;IACtB,UAAU,GAAG,IAAI,CAAA;IAEjB,KAAK,CAAC,QAAQ,CAAC,GAAG,aAAa,CAAC,CAAA;IAChC,KAAK,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;QACzE,iBAAiB,CAAC,GAA8B,CAAC,CAAA;IACnD,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAChC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACxB,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAA;IAC/B,yEAAyE;IACzE,gCAAgC;IAChC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAA;AAC9D,CAAC;AAED,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RenderOptions } from './template';
|
|
2
|
+
import type { ConsoleMessage } from './renderer';
|
|
3
|
+
export interface SkiaRenderResult {
|
|
4
|
+
buffer: Buffer;
|
|
5
|
+
messages: ConsoleMessage[];
|
|
6
|
+
}
|
|
7
|
+
export declare function renderSkia(options: RenderOptions): Promise<SkiaRenderResult>;
|
|
8
|
+
//# sourceMappingURL=engine-skia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-skia.d.ts","sourceRoot":"","sources":["../src/engine-skia.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AA8EhD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmFlF"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { Chart, BasicPlatform, ensureRegistered } from './chart-registry';
|
|
2
|
+
import { Canvas } from 'skia-canvas';
|
|
3
|
+
// Chart types from chartjs-chart-graph apply their layout over rAF ticks, so a
|
|
4
|
+
// naive capture can race a blank/half-laid-out frame. We poll until the node
|
|
5
|
+
// coordinates are finite and stable instead of guessing a fixed delay.
|
|
6
|
+
const GRAPH_TYPES = new Set(['forceDirectedGraph', 'tree', 'graph', 'dendrogram']);
|
|
7
|
+
// Matches a value that is two-or-more CSS colors joined (what an array of
|
|
8
|
+
// colors stringifies to). Used by the fill/strokeStyle shim below.
|
|
9
|
+
const MULTI_COLOR = /^\s*((?:rgba?|hsla?)\([^)]*\)|#[0-9a-fA-F]+)\s*,\s*(?:rgba?|hsla?|#)/;
|
|
10
|
+
/**
|
|
11
|
+
* skia diverges from browser <canvas> in three ways that affect Chart.js /
|
|
12
|
+
* plugins. Patch the 2D context to match browser behavior:
|
|
13
|
+
*
|
|
14
|
+
* 1. fillText/strokeText's 4th `maxWidth` arg is a HARD CLIP in skia, not the
|
|
15
|
+
* CSS "condense to fit". chartjs-plugin-datalabels passes a maxWidth from
|
|
16
|
+
* its own measureText (sub-pixel narrower than skia's glyph advance), so
|
|
17
|
+
* trailing glyphs get chopped ("120" -> "12"). Drop the 4th arg.
|
|
18
|
+
* 2. Assigning an invalid value to fillStyle/strokeStyle is IGNORED by skia
|
|
19
|
+
* (the style keeps its previous value), whereas browsers coerce e.g. an
|
|
20
|
+
* array via toString and latch onto its first color. chartjs-chart-treemap
|
|
21
|
+
* assigns a raw backgroundColor array straight to fillStyle, so cells
|
|
22
|
+
* stayed default black. Coerce array / multi-color values to their first
|
|
23
|
+
* color.
|
|
24
|
+
*/
|
|
25
|
+
function patchContext(ctx) {
|
|
26
|
+
const anyCtx = ctx;
|
|
27
|
+
const fill = anyCtx.fillText.bind(ctx);
|
|
28
|
+
const stroke = anyCtx.strokeText.bind(ctx);
|
|
29
|
+
anyCtx.fillText = (t, x, y) => fill(t, x, y);
|
|
30
|
+
anyCtx.strokeText = (t, x, y) => stroke(t, x, y);
|
|
31
|
+
patchStyle(ctx, 'fillStyle');
|
|
32
|
+
patchStyle(ctx, 'strokeStyle');
|
|
33
|
+
}
|
|
34
|
+
function patchStyle(ctx, prop) {
|
|
35
|
+
const proto = Object.getPrototypeOf(ctx);
|
|
36
|
+
const desc = Object.getOwnPropertyDescriptor(proto, prop);
|
|
37
|
+
if (!desc || !desc.set || !desc.get)
|
|
38
|
+
return;
|
|
39
|
+
const { get, set } = desc;
|
|
40
|
+
Object.defineProperty(ctx, prop, {
|
|
41
|
+
configurable: true,
|
|
42
|
+
get() {
|
|
43
|
+
return get.call(this);
|
|
44
|
+
},
|
|
45
|
+
set(v) {
|
|
46
|
+
let value = v;
|
|
47
|
+
if (Array.isArray(value))
|
|
48
|
+
value = value[0];
|
|
49
|
+
else if (typeof value === 'string') {
|
|
50
|
+
const m = value.match(MULTI_COLOR);
|
|
51
|
+
if (m)
|
|
52
|
+
value = m[1];
|
|
53
|
+
}
|
|
54
|
+
set.call(this, value);
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
async function settleLayout(chart) {
|
|
59
|
+
const nodes = () => chart.getDatasetMeta(0).data.map((e) => [e.x, e.y]);
|
|
60
|
+
const allFinite = (ns) => ns.every(([x, y]) => Number.isFinite(x) && Number.isFinite(y));
|
|
61
|
+
const same = (a, b) => a.length === b.length && a.every(([x, y], i) => Math.abs(x - b[i][0]) < 0.01 && Math.abs(y - b[i][1]) < 0.01);
|
|
62
|
+
let prev = nodes();
|
|
63
|
+
for (let tick = 0; tick < 200; tick++) {
|
|
64
|
+
await new Promise((r) => setTimeout(r, 16));
|
|
65
|
+
const cur = nodes();
|
|
66
|
+
if (allFinite(cur) && same(cur, prev))
|
|
67
|
+
break;
|
|
68
|
+
prev = cur;
|
|
69
|
+
}
|
|
70
|
+
chart.draw();
|
|
71
|
+
}
|
|
72
|
+
export async function renderSkia(options) {
|
|
73
|
+
ensureRegistered();
|
|
74
|
+
const width = options.width ?? 800;
|
|
75
|
+
const height = options.height ?? 600;
|
|
76
|
+
const dpr = options.devicePixelRatio ?? 1;
|
|
77
|
+
const format = options.format ?? 'png';
|
|
78
|
+
const background = options.backgroundColor ?? 'white';
|
|
79
|
+
const messages = [];
|
|
80
|
+
// Capture Chart.js warnings/errors the way the browser engine scrapes the
|
|
81
|
+
// page console, so both engines surface the same diagnostics.
|
|
82
|
+
const origWarn = console.warn;
|
|
83
|
+
const origError = console.error;
|
|
84
|
+
console.warn = (...a) => messages.push({ level: 'warn', message: a.join(' ') });
|
|
85
|
+
console.error = (...a) => messages.push({ level: 'error', message: a.join(' ') });
|
|
86
|
+
const canvas = new Canvas(width, height);
|
|
87
|
+
const ctx = canvas.getContext('2d');
|
|
88
|
+
patchContext(ctx);
|
|
89
|
+
let chart;
|
|
90
|
+
try {
|
|
91
|
+
// JSON round-trip mirrors the browser engine's JSON.stringify(chart) — it
|
|
92
|
+
// deep-clones (so we never mutate the caller's config) and drops any
|
|
93
|
+
// function values identically, keeping the two engines in lockstep.
|
|
94
|
+
const config = JSON.parse(JSON.stringify(options.chart));
|
|
95
|
+
config.platform = BasicPlatform;
|
|
96
|
+
const opts = (config.options ?? {});
|
|
97
|
+
opts.devicePixelRatio = dpr;
|
|
98
|
+
opts.responsive = false;
|
|
99
|
+
opts.maintainAspectRatio = false;
|
|
100
|
+
opts.animation = false;
|
|
101
|
+
config.options = opts;
|
|
102
|
+
// Background fill. The browser engine renders onto a coloured <body>;
|
|
103
|
+
// reproduce that with a beforeDraw pass, unless the caller asked for a
|
|
104
|
+
// transparent canvas (PNG alpha).
|
|
105
|
+
const inlinePlugins = Array.isArray(config.plugins) ? config.plugins : [];
|
|
106
|
+
if (background !== 'transparent') {
|
|
107
|
+
inlinePlugins.push({
|
|
108
|
+
id: 'chartjs2img_background',
|
|
109
|
+
beforeDraw(c) {
|
|
110
|
+
const cctx = c.ctx;
|
|
111
|
+
cctx.save();
|
|
112
|
+
cctx.globalCompositeOperation = 'destination-over';
|
|
113
|
+
cctx.fillStyle = background;
|
|
114
|
+
cctx.fillRect(0, 0, c.width, c.height);
|
|
115
|
+
cctx.restore();
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
config.plugins = inlinePlugins;
|
|
120
|
+
const type = (config.type ?? config.data?.type);
|
|
121
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
122
|
+
chart = new Chart(ctx, config);
|
|
123
|
+
if (type && GRAPH_TYPES.has(type)) {
|
|
124
|
+
await settleLayout(chart);
|
|
125
|
+
}
|
|
126
|
+
const buffer = format === 'jpeg'
|
|
127
|
+
? await canvas.toBuffer('jpeg', { quality: (options.quality ?? 90) / 100 })
|
|
128
|
+
: await canvas.toBuffer('png');
|
|
129
|
+
return { buffer, messages };
|
|
130
|
+
}
|
|
131
|
+
catch (e) {
|
|
132
|
+
// Mirror the browser engine: a construction failure is reported as a
|
|
133
|
+
// message, not thrown — the caller still gets a (blank) buffer.
|
|
134
|
+
messages.push({ level: 'error', message: e instanceof Error ? e.message : String(e) });
|
|
135
|
+
const buffer = format === 'jpeg' ? await canvas.toBuffer('jpeg', { quality: (options.quality ?? 90) / 100 }) : await canvas.toBuffer('png');
|
|
136
|
+
return { buffer, messages };
|
|
137
|
+
}
|
|
138
|
+
finally {
|
|
139
|
+
try {
|
|
140
|
+
chart?.destroy();
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// ignore
|
|
144
|
+
}
|
|
145
|
+
console.warn = origWarn;
|
|
146
|
+
console.error = origError;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=engine-skia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-skia.js","sourceRoot":"","sources":["../src/engine-skia.ts"],"names":[],"mappings":"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"}
|
package/dist/lib.d.ts
CHANGED
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
*/
|
|
28
28
|
export { renderChart, closeBrowser, rendererStats, Renderer } from './renderer';
|
|
29
29
|
export type { RenderResult, ConsoleMessage, RendererConfig, RendererStats } from './renderer';
|
|
30
|
-
export type { RenderOptions } from './template';
|
|
30
|
+
export type { RenderOptions, Engine } from './template';
|
|
31
|
+
export { DEFAULT_ENGINE } from './template';
|
|
31
32
|
export { computeHash } from './cache';
|
|
32
33
|
export { VERSION, NAME } from './version';
|
|
33
34
|
/**
|
package/dist/lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAQH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC/E,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAK7F,YAAY,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAI3C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAIrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/lib.js
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
// configure concurrency per-instance) can instantiate `Renderer`
|
|
33
33
|
// directly.
|
|
34
34
|
export { renderChart, closeBrowser, rendererStats, Renderer } from './renderer';
|
|
35
|
+
export { DEFAULT_ENGINE } from './template';
|
|
35
36
|
// Deterministic hash computation — useful for building a CDN-facing
|
|
36
37
|
// cache layer or for deduping submissions before rendering.
|
|
37
38
|
export { computeHash } from './cache';
|
package/dist/lib.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,gEAAgE;AAChE,uEAAuE;AACvE,mEAAmE;AACnE,qEAAqE;AACrE,iEAAiE;AACjE,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,gEAAgE;AAChE,uEAAuE;AACvE,mEAAmE;AACnE,qEAAqE;AACrE,iEAAiE;AACjE,YAAY;AACZ,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAO/E,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3C,oEAAoE;AACpE,4DAA4D;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAErC,iEAAiE;AACjE,qCAAqC;AACrC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAaA,OAAO,
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAaA,OAAO,EAA6B,KAAK,aAAa,EAAE,MAAM,YAAY,CAAA;AAS1E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,OAAO,CAAA;IACf,wEAAwE;IACxE,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;;;;OAUG;IACH,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,gBAAgB,EAAE,OAAO,CAAA;IACzB,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7D,WAAW,EAAE,MAAM,CAAA;IACnB,oEAAoE;IACpE,oBAAoB,EAAE,MAAM,CAAA;IAC5B,oFAAoF;IACpF,oBAAoB,EAAE,MAAM,CAAA;IAC5B;;;OAGG;IACH,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AA+BD,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAQ;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IAErC,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,aAAa,CAAgC;IAKrD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;gBAElD,MAAM,GAAE,cAAmB;YASzB,aAAa;YAmBb,aAAa;IA6B3B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,gBAAgB;IAUlB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAwHrD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5B,KAAK,IAAI,aAAa;CAWvB;AAaD,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAE/E;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAKlD;AAED,wBAAgB,aAAa,IAAI,aAAa,CAa7C"}
|
package/dist/renderer.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// can spin up an isolated Renderer and tear it down without affecting
|
|
12
12
|
// whatever other code the same process is running.
|
|
13
13
|
import puppeteer from 'puppeteer-core';
|
|
14
|
-
import { buildHtml } from './template';
|
|
14
|
+
import { buildHtml, DEFAULT_ENGINE } from './template';
|
|
15
15
|
import { Semaphore } from './semaphore';
|
|
16
16
|
import { computeHash, getCache, setCache } from './cache';
|
|
17
17
|
import { ensureChromiumInstalled } from './chromium';
|
|
@@ -145,6 +145,17 @@ export class Renderer {
|
|
|
145
145
|
messages: [],
|
|
146
146
|
};
|
|
147
147
|
}
|
|
148
|
+
// Engine dispatch. The skia engine is the default and needs no browser,
|
|
149
|
+
// so we branch BEFORE ensureBrowser — a skia-only process never launches
|
|
150
|
+
// Chromium. The engine module is imported lazily so browser-only or
|
|
151
|
+
// library-metadata callers don't pull in skia-canvas + Chart.js either.
|
|
152
|
+
const engine = options.engine ?? DEFAULT_ENGINE;
|
|
153
|
+
if (engine === 'skia') {
|
|
154
|
+
const { renderSkia } = await import('./engine-skia');
|
|
155
|
+
const { buffer, messages } = await renderSkia(options);
|
|
156
|
+
setCache(hash, buffer, contentType);
|
|
157
|
+
return { buffer, hash, contentType, cached: false, messages };
|
|
158
|
+
}
|
|
148
159
|
const b = await this.ensureBrowser();
|
|
149
160
|
const page = await b.newPage();
|
|
150
161
|
this.schedulePageCleanup(page);
|
package/dist/renderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,qEAAqE;AACrE,qEAAqE;AACrE,8DAA8D;AAC9D,aAAa;AACb,EAAE;AACF,qEAAqE;AACrE,sEAAsE;AACtE,mDAAmD;AACnD,OAAO,SAAsC,MAAM,gBAAgB,CAAA;AACnE,OAAO,EAAE,SAAS,EAAsB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skia-polyfills.d.ts","sourceRoot":"","sources":["../src/skia-polyfills.ts"],"names":[],"mappings":"AAsBA,qEAAqE;AACrE,wBAAgB,oBAAoB,IAAI,IAAI,CAoC3C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Minimal DOM globals for the skia rendering engine.
|
|
2
|
+
//
|
|
3
|
+
// A handful of Chart.js community plugins reach for browser globals that
|
|
4
|
+
// don't exist in Node/Bun, all at RENDER time (not module-eval time):
|
|
5
|
+
// - chartjs-chart-graph (force / tree) -> requestAnimationFrame
|
|
6
|
+
// - chartjs-chart-wordcloud -> document.createElement('canvas')
|
|
7
|
+
// - chartjs-chart-venn -> window.Path2D
|
|
8
|
+
//
|
|
9
|
+
// This is exposed as a CALLED function (not a bare side-effect import) on
|
|
10
|
+
// purpose: the package is published with "sideEffects" scoped tightly, and a
|
|
11
|
+
// side-effect-only module gets tree-shaken out of the `bun build --compile`
|
|
12
|
+
// binary. An imported-and-invoked function survives. `renderSkia` calls it
|
|
13
|
+
// before creating any chart, so the globals are always in place in time.
|
|
14
|
+
//
|
|
15
|
+
// Everything is guarded so a real browser/Electron host (or a prior polyfill)
|
|
16
|
+
// is never clobbered. Defining `window`/`document` would normally make
|
|
17
|
+
// Chart.js pick DomPlatform; the skia engine forces `platform: BasicPlatform`
|
|
18
|
+
// on every chart to stay on the headless code path regardless.
|
|
19
|
+
import { Canvas, Path2D } from 'skia-canvas';
|
|
20
|
+
let installed = false;
|
|
21
|
+
/** Install the DOM globals the bundled plugins need (idempotent). */
|
|
22
|
+
export function installSkiaPolyfills() {
|
|
23
|
+
if (installed)
|
|
24
|
+
return;
|
|
25
|
+
installed = true;
|
|
26
|
+
const g = globalThis;
|
|
27
|
+
if (typeof g.requestAnimationFrame === 'undefined') {
|
|
28
|
+
g.requestAnimationFrame = (cb) => setTimeout(() => cb(performance.now()), 16);
|
|
29
|
+
g.cancelAnimationFrame = (id) => clearTimeout(id);
|
|
30
|
+
}
|
|
31
|
+
if (typeof g.Path2D === 'undefined') {
|
|
32
|
+
g.Path2D = Path2D;
|
|
33
|
+
}
|
|
34
|
+
if (typeof g.window === 'undefined') {
|
|
35
|
+
// venn probes `window.Path2D`; a real skia Path2D (which parses SVG path
|
|
36
|
+
// strings) lets it render its arc-slice fills faithfully.
|
|
37
|
+
//
|
|
38
|
+
// EXCEPTION: inside a `bun build --compile` standalone binary,
|
|
39
|
+
// chartjs-chart-venn's internal `new Path2D(...)` hits a skia-canvas
|
|
40
|
+
// native-binding quirk (`this.native[fn]`) that does NOT occur under
|
|
41
|
+
// `bun run`, the npm library, or the server. Detect the compiled binary
|
|
42
|
+
// (its modules live under a `/$bunfs/` virtual FS) and leave window.Path2D
|
|
43
|
+
// unset there, so venn falls back to its ctx.ellipse path — minor
|
|
44
|
+
// overlap-fill artifacts, but it renders instead of throwing.
|
|
45
|
+
const isCompiledBinary = import.meta.url.includes('/$bunfs/');
|
|
46
|
+
g.window = isCompiledBinary ? {} : { Path2D };
|
|
47
|
+
}
|
|
48
|
+
if (typeof g.document === 'undefined') {
|
|
49
|
+
g.document = {
|
|
50
|
+
createElement: (tag) => (tag === 'canvas' ? new Canvas(1, 1) : {}),
|
|
51
|
+
fonts: { addEventListener() { }, ready: Promise.resolve() },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=skia-polyfills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skia-polyfills.js","sourceRoot":"","sources":["../src/skia-polyfills.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,EAAE;AACF,yEAAyE;AACzE,sEAAsE;AACtE,mEAAmE;AACnE,8EAA8E;AAC9E,2DAA2D;AAC3D,EAAE;AACF,0EAA0E;AAC1E,6EAA6E;AAC7E,4EAA4E;AAC5E,2EAA2E;AAC3E,yEAAyE;AACzE,EAAE;AACF,8EAA8E;AAC9E,uEAAuE;AACvE,8EAA8E;AAC9E,+DAA+D;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAE5C,IAAI,SAAS,GAAG,KAAK,CAAA;AAErB,qEAAqE;AACrE,MAAM,UAAU,oBAAoB;IAClC,IAAI,SAAS;QAAE,OAAM;IACrB,SAAS,GAAG,IAAI,CAAA;IAEhB,MAAM,CAAC,GAAG,UAAgD,CAAA;IAE1D,IAAI,OAAO,CAAC,CAAC,qBAAqB,KAAK,WAAW,EAAE,CAAC;QACnD,CAAC,CAAC,qBAAqB,GAAG,CAAC,EAAuB,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;QAClG,CAAC,CAAC,oBAAoB,GAAG,CAAC,EAAW,EAAE,EAAE,CAAC,YAAY,CAAC,EAAmC,CAAC,CAAA;IAC7F,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAA;IACnB,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QACpC,yEAAyE;QACzE,0DAA0D;QAC1D,EAAE;QACF,+DAA+D;QAC/D,qEAAqE;QACrE,qEAAqE;QACrE,wEAAwE;QACxE,2EAA2E;QAC3E,kEAAkE;QAClE,8DAA8D;QAC9D,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;QAC7D,CAAC,CAAC,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAA;IAC/C,CAAC;IAED,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;QACtC,CAAC,CAAC,QAAQ,GAAG;YACX,aAAa,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1E,KAAK,EAAE,EAAE,gBAAgB,KAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE;SAC3D,CAAA;IACH,CAAC;AACH,CAAC"}
|
package/dist/template.d.ts
CHANGED
|
@@ -65,6 +65,15 @@ export declare const LIBS: {
|
|
|
65
65
|
readonly file: "dist/chartjs-adapter-date-fns.bundle.min.js";
|
|
66
66
|
};
|
|
67
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Rendering engine:
|
|
70
|
+
* - 'skia' : skia-canvas (default) — no browser, fast, small footprint.
|
|
71
|
+
* - 'browser' : headless Chromium (Puppeteer) — maximum fidelity / pixel
|
|
72
|
+
* parity with a real browser and DOM-dependent plugins.
|
|
73
|
+
*/
|
|
74
|
+
export type Engine = 'skia' | 'browser';
|
|
75
|
+
/** Engine used when a caller doesn't specify one. */
|
|
76
|
+
export declare const DEFAULT_ENGINE: Engine;
|
|
68
77
|
export interface RenderOptions {
|
|
69
78
|
/** Chart.js configuration object */
|
|
70
79
|
chart: Record<string, unknown>;
|
|
@@ -80,6 +89,8 @@ export interface RenderOptions {
|
|
|
80
89
|
format?: 'png' | 'jpeg';
|
|
81
90
|
/** JPEG quality 0-100 (default: 90) */
|
|
82
91
|
quality?: number;
|
|
92
|
+
/** Rendering engine (default: 'skia'). See {@link Engine}. */
|
|
93
|
+
engine?: Engine;
|
|
83
94
|
}
|
|
84
95
|
export declare function buildHtml(options: RenderOptions): string;
|
|
85
96
|
//# sourceMappingURL=template.d.ts.map
|
package/dist/template.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqBP,CAAA;AAMV,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqBP,CAAA;AAMV;;;;;GAKG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;AAEvC,qDAAqD;AACrD,eAAO,MAAM,cAAc,EAAE,MAAe,CAAA;AAE5C,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,kDAAkD;IAClD,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACvB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAuGxD"}
|
package/dist/template.js
CHANGED
|
@@ -26,6 +26,8 @@ export const LIBS = {
|
|
|
26
26
|
function cdnUrl(lib) {
|
|
27
27
|
return `${CDN}/${lib.pkg}@${lib.version}/${lib.file}`;
|
|
28
28
|
}
|
|
29
|
+
/** Engine used when a caller doesn't specify one. */
|
|
30
|
+
export const DEFAULT_ENGINE = 'skia';
|
|
29
31
|
export function buildHtml(options) {
|
|
30
32
|
const { chart, width = 800, height = 600, devicePixelRatio = 1, backgroundColor = 'white', } = options;
|
|
31
33
|
return `<!DOCTYPE html>
|
|
@@ -90,6 +92,12 @@ ${Object.values(LIBS)
|
|
|
90
92
|
if (v && v.id) Chart.register(v);
|
|
91
93
|
});
|
|
92
94
|
}
|
|
95
|
+
// chartjs-plugin-gradient exposes its plugin object on the global under the
|
|
96
|
+
// package name but does NOT call Chart.register itself, so gradient configs
|
|
97
|
+
// silently fall back to the dataset's flat colors unless we register it here.
|
|
98
|
+
if (window['chartjs-plugin-gradient']) {
|
|
99
|
+
Chart.register(window['chartjs-plugin-gradient']);
|
|
100
|
+
}
|
|
93
101
|
|
|
94
102
|
// Force all animations off for instant rendering
|
|
95
103
|
config.options.animation = false;
|
package/dist/template.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,iFAAiF;AAEjF,MAAM,GAAG,GAAG,8BAA8B,CAAA;AAE1C,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE;IAC7E,UAAU;IACV,UAAU,EAAE,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uCAAuC,EAAE;IACjH,UAAU,EAAE,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uCAAuC,EAAE;IACjH,IAAI,EAAE,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iCAAiC,EAAE;IAC/F,QAAQ,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,qCAAqC,EAAE;IAC3G,yBAAyB;IACzB,MAAM,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,kCAAkC,EAAE;IACnG,MAAM,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,kCAAkC,EAAE;IACpG,OAAO,EAAE,EAAE,GAAG,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,mCAAmC,EAAE;IACtG,uEAAuE;IACvE,6DAA6D;IAC7D,SAAS,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IAC/F,GAAG,EAAE,EAAE,GAAG,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACnF,KAAK,EAAE,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACvF,IAAI,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACrF,uEAAuE;IACvE,uEAAuE;IACvE,8DAA8D;IAC9D,cAAc,EAAE,EAAE,GAAG,EAAE,0BAA0B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,6CAA6C,EAAE;CAClH,CAAA;AAEV,SAAS,MAAM,CAAC,GAAqC;IACnD,OAAO,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,CAAA;AACvD,CAAC;
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,iFAAiF;AAEjF,MAAM,GAAG,GAAG,8BAA8B,CAAA;AAE1C,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,OAAO,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE;IAC7E,UAAU;IACV,UAAU,EAAE,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uCAAuC,EAAE;IACjH,UAAU,EAAE,EAAE,GAAG,EAAE,2BAA2B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,uCAAuC,EAAE;IACjH,IAAI,EAAE,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,iCAAiC,EAAE;IAC/F,QAAQ,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,qCAAqC,EAAE;IAC3G,yBAAyB;IACzB,MAAM,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,kCAAkC,EAAE;IACnG,MAAM,EAAE,EAAE,GAAG,EAAE,sBAAsB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,kCAAkC,EAAE;IACpG,OAAO,EAAE,EAAE,GAAG,EAAE,uBAAuB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,mCAAmC,EAAE;IACtG,uEAAuE;IACvE,6DAA6D;IAC7D,SAAS,EAAE,EAAE,GAAG,EAAE,yBAAyB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IAC/F,GAAG,EAAE,EAAE,GAAG,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACnF,KAAK,EAAE,EAAE,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACvF,IAAI,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,wBAAwB,EAAE;IACrF,uEAAuE;IACvE,uEAAuE;IACvE,8DAA8D;IAC9D,cAAc,EAAE,EAAE,GAAG,EAAE,0BAA0B,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,6CAA6C,EAAE;CAClH,CAAA;AAEV,SAAS,MAAM,CAAC,GAAqC;IACnD,OAAO,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,CAAA;AACvD,CAAC;AAUD,qDAAqD;AACrD,MAAM,CAAC,MAAM,cAAc,GAAW,MAAM,CAAA;AAqB5C,MAAM,UAAU,SAAS,CAAC,OAAsB;IAC9C,MAAM,EACJ,KAAK,EACL,KAAK,GAAG,GAAG,EACX,MAAM,GAAG,GAAG,EACZ,gBAAgB,GAAG,CAAC,EACpB,eAAe,GAAG,OAAO,GAC1B,GAAG,OAAO,CAAA;IAEX,OAAO;;;;;;uBAMc,eAAe;;aAEzB,KAAK;cACJ,MAAM;;;EAGlB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;SACd,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC;SACtD,IAAI,CAAC,IAAI,CAAC;;;;;;;;iBAQA,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;;;;sCAIA,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAmE9C,CAAA;AACR,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chartjs2img",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Render Chart.js charts to images via a TypeScript API, CLI, or HTTP server
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "Render Chart.js charts to images via a TypeScript API, CLI, or HTTP server. Two engines: skia-canvas by default (no browser) or headless Chromium for full fidelity. Chart.js 4.4 + 12 plugins bundled.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/lib.js",
|
|
7
7
|
"module": "./dist/lib.js",
|
|
@@ -18,7 +18,10 @@
|
|
|
18
18
|
"README.md",
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
|
-
"sideEffects":
|
|
21
|
+
"sideEffects": [
|
|
22
|
+
"**/chart-registry.js",
|
|
23
|
+
"**/chart-registry.ts"
|
|
24
|
+
],
|
|
22
25
|
"bin": {
|
|
23
26
|
"chartjs2img": "src/index.ts"
|
|
24
27
|
},
|
|
@@ -30,6 +33,8 @@
|
|
|
30
33
|
"png",
|
|
31
34
|
"jpeg",
|
|
32
35
|
"webp",
|
|
36
|
+
"skia",
|
|
37
|
+
"skia-canvas",
|
|
33
38
|
"puppeteer",
|
|
34
39
|
"headless-chromium",
|
|
35
40
|
"visualization",
|
|
@@ -60,7 +65,21 @@
|
|
|
60
65
|
"docs:deploy": "bun run docs:build && rsync -av docs/.vitepress/dist/ web-g6:web/vhosts/chartjs2img.ideamans.com/html/"
|
|
61
66
|
},
|
|
62
67
|
"dependencies": {
|
|
63
|
-
"
|
|
68
|
+
"chart.js": "4.4.9",
|
|
69
|
+
"chartjs-adapter-date-fns": "3.0.0",
|
|
70
|
+
"chartjs-chart-geo": "4.3.3",
|
|
71
|
+
"chartjs-chart-graph": "4.3.3",
|
|
72
|
+
"chartjs-chart-matrix": "2.0.1",
|
|
73
|
+
"chartjs-chart-sankey": "0.12.1",
|
|
74
|
+
"chartjs-chart-treemap": "2.3.1",
|
|
75
|
+
"chartjs-chart-venn": "4.3.3",
|
|
76
|
+
"chartjs-chart-wordcloud": "4.4.3",
|
|
77
|
+
"chartjs-plugin-annotation": "3.1.0",
|
|
78
|
+
"chartjs-plugin-datalabels": "2.2.0",
|
|
79
|
+
"chartjs-plugin-gradient": "0.6.1",
|
|
80
|
+
"date-fns": "^4.4.0",
|
|
81
|
+
"puppeteer-core": "^24.40.0",
|
|
82
|
+
"skia-canvas": "^3.0.8"
|
|
64
83
|
},
|
|
65
84
|
"devDependencies": {
|
|
66
85
|
"@tailwindcss/vite": "^4.2.2",
|
|
@@ -71,5 +90,8 @@
|
|
|
71
90
|
"vitepress": "^2.0.0-alpha.17",
|
|
72
91
|
"vitepress-daisyui-theme": "^0.2.1",
|
|
73
92
|
"vue": "^3.5.0"
|
|
74
|
-
}
|
|
93
|
+
},
|
|
94
|
+
"trustedDependencies": [
|
|
95
|
+
"skia-canvas"
|
|
96
|
+
]
|
|
75
97
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,10 +7,14 @@ import { getLlmDocs } from './llm-docs'
|
|
|
7
7
|
import { parseArgs, CliArgError } from './cli-args'
|
|
8
8
|
|
|
9
9
|
function printUsage(): void {
|
|
10
|
-
console.log(`chartjs2img v${VERSION} - Render Chart.js charts to images
|
|
10
|
+
console.log(`chartjs2img v${VERSION} - Render Chart.js charts to images
|
|
11
11
|
|
|
12
12
|
Converts a Chart.js configuration JSON into a PNG or JPEG image. Works as an
|
|
13
|
-
HTTP server or a one-shot CLI.
|
|
13
|
+
HTTP server or a one-shot CLI. Two rendering engines are available:
|
|
14
|
+
skia (default) skia-canvas — no browser, fast, small footprint
|
|
15
|
+
browser headless Chromium (Puppeteer) — maximum fidelity / pixel parity
|
|
16
|
+
Select per render with --engine (CLI) or the "engine" field (HTTP).
|
|
17
|
+
Chromium is installed automatically on first use of the browser engine.
|
|
14
18
|
|
|
15
19
|
COMMANDS
|
|
16
20
|
chartjs2img serve [options] Start HTTP server
|
|
@@ -33,11 +37,13 @@ RENDER OPTIONS
|
|
|
33
37
|
--background-color <color> CSS color or "transparent" (default: white)
|
|
34
38
|
--format, -f <fmt> png | jpeg (default: png)
|
|
35
39
|
--quality, -q <0-100> JPEG quality (default: 90)
|
|
40
|
+
--engine <engine> skia | browser (default: skia)
|
|
36
41
|
|
|
37
42
|
EXAMPLES OPTIONS
|
|
38
43
|
--outdir, -o <dir> Output directory (default: ./examples)
|
|
39
44
|
--format, -f <fmt> png | jpeg (default: png)
|
|
40
45
|
--quality, -q <0-100> JPEG quality (default: 90)
|
|
46
|
+
--engine <engine> skia | browser (default: skia)
|
|
41
47
|
|
|
42
48
|
ENVIRONMENT VARIABLES
|
|
43
49
|
PORT Server listen port (default: 3000)
|
|
@@ -98,7 +104,8 @@ INPUT JSON SCHEMA (for "render" CLI and POST /render)
|
|
|
98
104
|
"devicePixelRatio": 1, // optional, default 1 — N scales output to width*N x height*N
|
|
99
105
|
"backgroundColor": "white",// optional, default "white"
|
|
100
106
|
"format": "png", // optional, "png" | "jpeg"
|
|
101
|
-
"quality": 90
|
|
107
|
+
"quality": 90, // optional, 0-100 for jpeg
|
|
108
|
+
"engine": "skia" // optional, "skia" (default) | "browser"
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
CHART.JS CONFIGURATION REFERENCE
|
|
@@ -141,7 +148,7 @@ BUILT-IN PLUGINS (all pre-loaded, no configuration needed)
|
|
|
141
148
|
chart.js 4.4.9 Core charting library
|
|
142
149
|
chartjs-plugin-datalabels 2.2.0 Show values on chart elements
|
|
143
150
|
chartjs-plugin-annotation 3.1.0 Lines, boxes, labels as overlays
|
|
144
|
-
chartjs-plugin-zoom 2.2.0 Pan & zoom (
|
|
151
|
+
chartjs-plugin-zoom 2.2.0 Pan & zoom (browser engine only)
|
|
145
152
|
chartjs-plugin-gradient 0.6.1 Gradient fills via simple config
|
|
146
153
|
chartjs-chart-matrix 2.0.1 Heatmap / matrix charts
|
|
147
154
|
chartjs-chart-sankey 0.12.1 Sankey flow diagrams
|
|
@@ -237,6 +244,15 @@ async function main(): Promise<void> {
|
|
|
237
244
|
throw err
|
|
238
245
|
}
|
|
239
246
|
|
|
247
|
+
// Validate --engine up front (mirrors the HTTP 400 for an invalid engine).
|
|
248
|
+
// Without this an unknown value would silently fall through to the browser
|
|
249
|
+
// engine in the renderer dispatch.
|
|
250
|
+
const engineArg = args['engine']
|
|
251
|
+
if (engineArg !== undefined && engineArg !== 'skia' && engineArg !== 'browser') {
|
|
252
|
+
console.error(`Invalid --engine: ${String(engineArg)} (must be "skia" or "browser")`)
|
|
253
|
+
process.exit(2)
|
|
254
|
+
}
|
|
255
|
+
|
|
240
256
|
if (command === '--version' || command === 'version') {
|
|
241
257
|
console.log(`chartjs2img v${VERSION}`)
|
|
242
258
|
process.exit(0)
|
|
@@ -287,6 +303,7 @@ async function main(): Promise<void> {
|
|
|
287
303
|
outdir,
|
|
288
304
|
format: format as 'png' | 'jpeg',
|
|
289
305
|
quality,
|
|
306
|
+
engine: args['engine'] as 'skia' | 'browser' | undefined,
|
|
290
307
|
})
|
|
291
308
|
} else if (command === 'render') {
|
|
292
309
|
await cliRender({
|
|
@@ -298,6 +315,7 @@ async function main(): Promise<void> {
|
|
|
298
315
|
backgroundColor: args['background-color'] as string,
|
|
299
316
|
format: (args['format'] ?? args['f']) as 'png' | 'jpeg' | undefined,
|
|
300
317
|
quality: args['quality'] ? Number(args['quality']) : args['q'] ? Number(args['q']) : undefined,
|
|
318
|
+
engine: args['engine'] as 'skia' | 'browser' | undefined,
|
|
301
319
|
})
|
|
302
320
|
} else {
|
|
303
321
|
console.error(`Unknown command: ${command}`)
|