# wmap-renderer-canvas A Canvas-based renderer for `wmap` formatted wardley maps parsed with [`wmap-parser`][wmap-parser-js]. ## Features - Can render to canvas, raster images (PDF / JPEG), or vector (PDF) - Rendering logic attempts to replicate [map][map]'s output. ## Installation ```bash npm install wmap-renderer-canvas ``` ```bash yarn add wmap-renderer-canvas ``` ```bash pnpm add wmap-renderer-canvas ``` ## Usage ### Browser ```javascript import { parse } from "wmap-parser"; import { renderToCanvas } from "wmap-renderer-canvas"; const wmapSource = ` Tea (0.9, 0.5) Cup (0.8, 0.4) Tea -> Cup `; const map = parse(wmapSource); const canvas = document.getElementById("myCanvas"); await renderToCanvas(map, canvas); ``` ### Node.js - Render to Canvas ```javascript import { createCanvas } from "canvas"; import { parse } from "wmap-parser"; import { renderToCanvas, StageType } from "wmap-renderer-canvas"; const map = parse(wmapSource); const canvas = createCanvas(1384, 1084); // No overrides await renderToCanvas(map, canvas); // Stage Type override await renderToCanvas(map, canvas, StageType.DECISION_DRIVERS); ``` ### Node.js - Render to Image File ```javascript import { parse } from "wmap-parser"; import { renderToImage, ImageType, StageType } from "wmap-renderer-canvas"; import fs from "fs"; const map = parse(wmapSource); // PNG const pngStream = await renderToImage(map, ImageType.PNG); pngStream.pipe(fs.createWriteStream("map.png")); // JPEG, with a stage type override const jpegStream = await renderToImage(map, ImageType.JPEG, StageType.UBIQUITY); jpegStream.pipe(fs.createWriteStream("map.jpeg")); // PDF, with a stage type override const pdfStream = await renderToImage(map, ImageType.PDF, StageType.PUBLICATION_TYPES); pdfStream.pipe(fs.createWriteStream("map.pdf")); ``` ### Configuration All functions accept an optional configuration object that can override how the map is rendered. See the type definitions for more info on each value. Here's all the defaults. ```javascript { options: { showBackground: true, smartLabelPositioning: true, }, theme: { colors: { background: "#FFFFFF", axis: "#0F261F", vertex: "#0F261F", label: "#0F261F", stageForeground: "#DAE6E3", stageBackground: "#FFFFFF", inertia: "#FA2B00", evolution: "#4F8FE6", groups: [ "#4F8FE6", "#FA2B00", "#23C17C", "#FAED8F", "#FFB3F0", ], }, sizes: { mapWidth: 1300, mapHeight: 1000, padding: 42, lineWidth: 0.5, vertexWidth: 25, vertexHeight: 25, arrowheadSize: 10, stageHeight: 100, }, fonts: { family: '"Helvetica Neue", Helvetica, Arial, sans-serif', axisLabel: 14, vertexLabel: 12, note: 12, }, lineHeights: { vertexLabel: 18, note: 18, }, opacity: { groups: 0.1, }, }, } ``` ## API ### `renderToCanvas(map, canvas, stageType, overrides)` Renders a parsed Wardley map to a canvas element. **Parameters:** - `map` (Map): Parsed map object from `wmap-parser` - `canvas` (HTMLCanvasElement|Canvas): Canvas element (browser) or Canvas instance (Node.js) - `stageType` (StageType): The type of stage to use. See StageType for all possible values. Defaults to `StageType.ACTIVITIES` - `overrides` (tConfiguration, optional): **Returns:** `Promise` **Canvas Size:** The canvas will be automatically sized to 1384×1084 pixels (1300×1000 map + 42px padding on each side). ### `renderToImage(map, imageType, stageType, overrides)` Renders a parsed Wardley map to an image stream. **Node.js only**. **Parameters:** - `map` (Map): Parsed map object from `wmap-parser` - `imageType` (ImageType): The image type to use. Can be: `ImageType.PNG`, `ImageType.JPEG`, or `ImageType.PDF` - `stageType` (StageType): The type of stage to use. See StageType for all possible values. Defaults to `StageType.ACTIVITIES` - `overrides` (tConfiguration, optional): **Returns:** `Promise` - Stream of the rendered image **Throws:** - Error if not in Node.js environment - Error if `canvas` module cannot be imported. - Error if `imageType` is not supported ## Performance The drawing is not optimized for live-editing. It's relatively quick to generate a single image. On an M1 Pro mac, ouexample map renders in about ~7ms, while a larger map with slightly under 2000 entities does so in ~210ms. You can run the benchmarks by using: ```bash make benchmark ``` ## Development This project uses a Makefile to run all commands. This is to keep the commands uniform with the other wmap-parser projects. ### Running Tests ```bash make test ``` Or to see coverage ```bash make coverage ``` ### Regenerating Types If you change the JSDocs, you'll need to regenerate the types ```bash make types ``` ## License AGPL-3.0 ## See Also - [Wardley Maps](https://wardleymaps.com/) - Learn about Wardley Mapping [wmap-parser-js]: https://www.npmjs.com/package/wmap-parser