Server-side D3 Visualization

4.0.1 · active · verified Sun Apr 19

d3-node is a utility library designed to facilitate server-side rendering of D3.js visualizations within a Node.js environment. It enables developers to generate static SVG or HTML strings, or raster images (PNG) via the optional `node-canvas` library, entirely on the backend. This capability is crucial for use cases like pre-rendering charts and maps for improved initial page load performance, offloading data processing from client browsers, and creating static image outputs for reports or social media sharing. The current stable version is 4.0.1. The project demonstrates active maintenance with consistent updates, including enhancements like explicit SVG attribute parameters and robust canvas support. Its key differentiators include the ability to leverage the entire D3 ecosystem and npm packages, produce portable SVG with embedded stylesheets, and simplify the adaptation of existing D3 examples for server-side generation.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to create a simple bar chart SVG using d3-node, including setting up axes and styling, and then saving the output to a file. It shows integration with both d3-node's D3 instance and explicit D3 imports for scales.

import { D3Node } from 'd3-node';
import * as d3 from 'd3'; // Import D3 for specific utilities like scaleLinear
import fs from 'fs';

const options = { 
  selector: '#chart', 
  container: '<div id="container"><div id="chart"></div></div>', 
  styles: '.bar { fill: steelblue; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; }'
};

const d3n = new D3Node(options);
const d3Local = d3n.d3; // Get the D3 instance associated with D3Node

const width = 400;
const height = 200;
const margin = { top: 20, right: 20, bottom: 30, left: 40 };

const svg = d3n.createSVG(width, height);

const data = [10, 20, 40, 60, 80];

const xScale = d3.scaleBand()
  .range([margin.left, width - margin.right])
  .padding(0.1)
  .domain(data.map((d, i) => i));

const yScale = d3.scaleLinear()
  .range([height - margin.bottom, margin.top])
  .domain([0, d3.max(data)]);

svg.append('g')
  .attr('fill', 'steelblue')
  .selectAll('rect')
  .data(data)
  .join('rect')
    .attr('class', 'bar')
    .attr('x', (d, i) => xScale(i))
    .attr('y', d => yScale(d))
    .attr('height', d => yScale(0) - yScale(d))
    .attr('width', xScale.bandwidth());

// Add X axis
svg.append('g')
  .attr('class', 'axis x-axis')
  .attr('transform', `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(xScale).tickFormat(i => `Item ${i + 1}`));

// Add Y axis
svg.append('g')
  .attr('class', 'axis y-axis')
  .attr('transform', `translate(${margin.left},0)`)
  .call(d3.axisLeft(yScale));

const svgOutput = d3n.svgString();
fs.writeFileSync('output.svg', svgOutput);
console.log('SVG written to output.svg');

// For canvas output (requires 'canvas' package):
// import Canvas from 'canvas';
// const d3nCanvas = new D3Node({ canvasModule: Canvas });
// const canvas = d3nCanvas.createCanvas(width, height);
// const context = canvas.getContext('2d');
// // ... draw on context with D3-Canvas specific methods ...
// canvas.createPNGStream().pipe(fs.createWriteStream('output.png'));

view raw JSON →