|
| 1 | +# Chart.js server side rendering example on the node.js environment. |
| 2 | + |
| 3 | +Render various charts using Chart.js into the SVG format. |
| 4 | + |
| 5 | +Chart.js uses the HTML5 Canvas API. |
| 6 | +However, the node.js environment does not have the Canvas API by default. |
| 7 | +With [red-agate-svg-canvas](https://www.npmjs.com/package/red-agate-svg-canvas), |
| 8 | +you can render the charts on the server side. |
| 9 | + |
| 10 | + |
| 11 | +## Get started |
| 12 | + |
| 13 | +```bash |
| 14 | +$ git clone https://github.com/shellyln/chart.js-node-ssr-example.git |
| 15 | +$ cd chart.js-node-ssr-example |
| 16 | +$ rm -rf ./.git |
| 17 | + |
| 18 | +$ npm install |
| 19 | +$ npm run build |
| 20 | +$ npm start |
| 21 | +``` |
| 22 | + |
| 23 | + |
| 24 | +## Example |
| 25 | + |
| 26 | +```ts |
| 27 | +import { SvgCanvas, |
| 28 | + Rect2D, |
| 29 | + SvgCanvas2DGradient } from 'red-agate-svg-canvas/modules'; |
| 30 | +import * as ChartJs from 'chart.js'; |
| 31 | + |
| 32 | +// Get the global scope. |
| 33 | +// If running on a node, "g" points to a "global" object. |
| 34 | +// When running on the browser, "g" points to the "window" object. |
| 35 | +const g = Function('return this')(); |
| 36 | + |
| 37 | +// Chart options |
| 38 | +// https://www.chartjs.org/docs/latest/getting-started/usage.html |
| 39 | +const opts: any = { ... }; |
| 40 | + |
| 41 | + |
| 42 | +function main() { |
| 43 | + // SvgCanvas has a "CanvasRenderingContext2D"-compatible interface. |
| 44 | + const ctx = new SvgCanvas(); |
| 45 | + |
| 46 | + // SvgCanvas lacks the canvas property. |
| 47 | + (ctx as any).canvas = { |
| 48 | + width: 800, |
| 49 | + height: 400, |
| 50 | + style: { |
| 51 | + width: '800px', |
| 52 | + height: '400px', |
| 53 | + }, |
| 54 | + }; |
| 55 | + |
| 56 | + // SvgCanvas does not have font glyph information, |
| 57 | + // so manually set the ratio of (font height / font width). |
| 58 | + ctx.fontHeightRatio = 2; |
| 59 | + |
| 60 | + // Chart.js needs a "HTMLCanvasElement"-like interface that has "getContext()" method. |
| 61 | + // "getContext()" should returns a "CanvasRenderingContext2D"-compatible interface. |
| 62 | + const el = { getContext: () => ctx }; |
| 63 | + |
| 64 | + // If "devicePixelRatio" is not set, Chart.js get the devicePixelRatio from "window" object. |
| 65 | + // node.js environment has no window object. |
| 66 | + opts.options.devicePixelRatio = 1; |
| 67 | + |
| 68 | + // Disable animations. |
| 69 | + opts.options.animation = false; |
| 70 | + opts.options.events = []; |
| 71 | + opts.options.responsive = false; |
| 72 | + |
| 73 | + // Chart.js needs the "CanvasGradient" in the global scope. |
| 74 | + const savedGradient = g.CanvasGradient; |
| 75 | + g.CanvasGradient = SvgCanvas2DGradient; |
| 76 | + try { |
| 77 | + const chart = new ChartJs.Chart(el as any, opts); |
| 78 | + } finally { |
| 79 | + if (savedGradient) { |
| 80 | + g.CanvasGradient = savedGradient; |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | + // Render as SVG. |
| 85 | + const svgString = ctx.render(new Rect2D(0, 0 , 800, 400), 'px'); |
| 86 | + console.log(svgString); |
| 87 | +} |
| 88 | +``` |
| 89 | + |
| 90 | + |
| 91 | +## Notes |
| 92 | + |
| 93 | +To import the [red-agate-svg-canvas](https://www.npmjs.com/package/red-agate-svg-canvas), you need to use `babel` + `webpack`. |
0 commit comments