2.1.0 • Published 1 year ago

d3-no-dom v2.1.0

Weekly downloads
-
License
MIT
Repository
-
Last release
1 year ago

d3-no-dom

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 

!WARNINGjsdom may not work on the Cloudflare Workers without specifying nodejs_compat flag due to use of the Node native modules

How to use

  1. At first, you must supply your own d3 instance and dom provider to the d3-no-dom's prepreSvgServerSideRenderer
  • 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
    });
  1. Next, use the render function. 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   
    })
  2. (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!