d3-no-dom
๐ Fully use D3.js (Data Driven Documents) in environments without DOM. Perfect for serverless e.g. Vercel Functions
Fully use d3.js in environments without DOM, such as Cloudflare Workers or Vercel Functions
Features
- Simple API with maximum extensibility.
- Support for asynchronous operations and API calls in render function
- Utilities like sanitizing the HTML or outputting the base64 from generated svg
- Tests covering most of the functionality ensuring robustness
Installation
npm i d3-no-dom d3
# or
yarn add d3-no-dom d3
# or
pnpm add d3-no-dom d3
The d3-no-dom library does not provide any underlying DOM implementation, giving users the flexibility to choose their preferred DOM library. Some options are:
linkedom: A lightweight and fast DOM implementation ideal for serverless environments such as Cloudflare Workers or Vercel Functions (recommended).
npm i linkedom
# or
yarn add linkedom
# or
pnpm add linkedom
jsdom: A more comprehensive and heavier DOM implementation, suitable for traditional backend environments like monolithic applications hosted on dedicated servers.
npm i jsdom
# or
yarn add jsdom
# or
pnpm add jsdom
How to use
- At first, you must supply your own d3 instance and dom provider to the
d3-no-dom'sprepreSvgServerSideRenderer
-
using linkedom (recommended)
import * as d3 from "d3" import { parseHTML } from "linkedom" // ... class Linkedom { window: { document: Document }; constructor(html: string) { const { document, window } = parseHTML(html); this.window = { document }; Object.assign(this.window, window); } } const { render } = prepareSvgServerSideRenderer({ domProvider: Linkedom, d3Instance: d3 }); -
using jsdom
import * as d3 from "d3" import { JSDOM } from "jsdom" // ... const { render } = prepareSvgServerSideRenderer({ domProvider: JSDOM, d3Instance: d3 });
- Next, use the
renderfunction. It provides everything you need in order to fully use d3.js on the server side (the underlying mechanism is integration with Virtual DOM)
// you can make e.g. API calls here
// it can also be synchronous if not needed!
// โญโโโโโโโโโโโโโค
// โ โ
// โ โ
const result = await render(async ({ d3Selection, svgNode, currentDom }) => {
// โ โ โ โ
// โ d3 selected โ โ โ
// โ object to work on โฏ โ โฐ whole DOM
// โ underlying
// โฐ rendered svg's svg DOM node to work on
// source, as HTML or base64
})
- (Optionally) adjust your configuration or the render function's options directly in order to e.g. disable sanitizing the HTML or control the return value (whether it should be HTML or base64 - where second is specifically useful with usage with satori)
License & contributing
The MIT License. All contributions are welcome!