1

I read that using jsdom is necessary for Observable Plot (derived module from D3js) to work in Nodejs.

However, there are very few examples about this and I cannot get to properly adapt the ones I found.

Here is the code I was trying to adapt:

import * as Plot from "@observablehq/plot";
import jsdom from "jsdom";

const { JSDOM } = jsdom;

const sales = [
  {units: 10, fruit: "fig"},
  {units: 20, fruit: "date"},
  {units: 40, fruit: "plum"},
  {units: 30, fruit: "plum"}
];

Plot.dot(sales, {x: "units", y: "fruit"}).plot();

I tried different things, like adding:

import {select} from "d3-selection";

Plot.select(JSDOM.window.document.body).dot(sales, {x: "units", y: "fruit"}).plot();

trying to reproduce what is done for d3 here.

I also saw this which might contain the answer, but this is not understandable for a javascript beginner like me.

How should I adapt my code ?

Escargot
  • 21
  • 7

2 Answers2

2

For anyone looking for this, I have a small library that handles this browser execution and opens up the resulting chart in a pop-up window using playwright: https://github.com/mhkeller/plot

mhkeller
  • 713
  • 1
  • 8
  • 19
1

I was finally able to obtain what I want like this:

import http from 'http';
import * as Plot from "@observablehq/plot";
import {JSDOM} from "jsdom";

const jsdom = new JSDOM(`
<!DOCTYPE html>
<head><meta charset="UTF-8"></head>
<body><div class='container'><figure id='graphic'>
</figure></div></body>`);

const sales = [
  {units: 10, fruit: "fig"},
  {units: 20, fruit: "date"},
  {units: 40, fruit: "plum"},
  {units: 30, fruit: "plum"}
];

jsdom.window.document.getElementById('graphic')
                     .appendChild(Plot.dot(sales, {x: "units", y: "fruit"})
                                      .plot({document: jsdom.window.document})
                                 );

http.createServer(function (req, res) {
  let html = jsdom.serialize();
  res.end(html);
}).listen(8080);

The jsdom object needed to be created less randomly and my way of using Plot.dot with jsdom was not correct. I also had to use the http module to render the graph in a browser, and access it at localhost:8080/.

Escargot
  • 21
  • 7