observablehq / plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
https://observablehq.com/plot/
ISC License
4.43k stars 180 forks source link

Static `Plot.tip` marks does not work with JSDOM #2187

Open legendre6891 opened 1 month ago

legendre6891 commented 1 month ago

Hi observableHQ plot team,

It seems like Plot.tip does not work with the JSDom renderer.

For example, the following code

(sample code)

```import {readFile} from "node:fs/promises"; import * as Plot from "@observablehq/plot"; import * as d3 from "d3"; import {JSDOM} from "jsdom"; const aapl = d3.csvParse(await readFile("./aapl.csv", "utf-8"), d3.autoType); const plot = Plot.plot({ document: new JSDOM("").window.document, y: {grid: true}, marks: [ Plot.lineY(aapl, {x: "Date", y: "Close"}), Plot.tip( [`Apple stock reaches a new high of $133 on Feb. 23, 2015. The release of the first Apple Watch, slated for April, is hotly anticipated.`], {x: new Date("2015-02-23"), y: 133, dy: -3, anchor: "bottom"} ), Plot.tip( [`Apple stock drops 8% after the company misses Q2 revenue targets and reports declining iPhone sales. It reaches a two-year low of $90.34 on May 12.`], {x: new Date("2016-05-12"), y: 90.34, dy: 3, anchor: "top"} ) ] }) plot.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.w3.org/2000/svg"); plot.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink"); process.stdout.write(plot.outerHTML); ```

results in an SVG which looks like following.

image

This example is taken from the documentation, which has the reference rendering with the tips:

image

Possibly related issue: https://github.com/observablehq/plot/issues/2160

Fil commented 1 month ago

Not connected to the pointer issue, but to the fact that we need to compute the text dimensions before we can make the box around it.

This is commented here: https://github.com/observablehq/plot/blob/9122f18afae894d3cbedcd8a73d1b3171a6f2bdb/src/marks/tip.js#L243-L250

There is a todo to maybe "guess" approximative dimensions to do it in SSR contexts such as a JSDOM document.