d3 Renderer

Draws charts with d3, as SVG.
Pro ExtensionAlphaPilot program

Quick start

npm install d3
import { d3Renderer } from '@tiptap-pro/extension-diagrams/d3'

Diagrams.configure({ renderers: [d3Renderer()] })

Chart types

Line, bar (upright or on its side), area, scatter, pie, doughnut, radar, combo, tree and network.

  • Network is laid out by a force simulation that runs a fixed number of steps from a fixed start, so the same data is drawn the same way every time.
  • Sankey needs d3-sankey, see Sankey charts.

Options

OptionTypeDescription
idstringThe id charts store. Default 'd3'
labelstringThe name for a menu. Default 'd3'
customizersRecord<string, D3Customizer>Functions that change a drawn chart, by name. Default {}. See Customizers
measureText(text, fontSize) => numberReturns a label's width, for exact label widths. Without it, widths are estimated
createDocument() => DocumentA Document for toSVG where there is no document, such as on a server
sankeythe d3-sankey moduleFor sankey charts

Sankey charts

npm install d3-sankey
import * as sankey from 'd3-sankey'

d3Renderer({ sankey })

Without sankey, the d3 Renderer does not list sankey, and a sankey chart goes to another Renderer.

Customizers

A customizer is a function you register under a name. A chart refers to it by that name:

d3Renderer({
  customizers: {
    highlightMax(svg, { data }) {
      // change the drawn SVG element: add marks, reorder, restyle
    },
  },
})

editor.commands.updateChartSpec({ spec: { renderer: { d3: { customizer: 'highlightMax' } } } })
  • It receives the drawn SVGSVGElement and the render input { data, spec, theme, size }.
  • It runs after every draw, in the editor and in an export.
  • The document holds the name only.
  • A chart that names a customizer this editor does not have is drawn without one.

Export and servers

  • In a browser toSVG needs nothing else.
  • On a server pass a DOM implementation:
import { parseHTML } from 'linkedom'

d3Renderer({
  createDocument: () => parseHTML('<!doctype html><html><body></body></html>').document,
})