Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Using this package for server-side D3 rendering #35

Open
ErikBoesen opened this issue Aug 10, 2023 · 2 comments
Open

[Question] Using this package for server-side D3 rendering #35

ErikBoesen opened this issue Aug 10, 2023 · 2 comments

Comments

@ErikBoesen
Copy link

Hello and thank you for writing an excellent package!

I'm attempting to use it for generating graphs of Spotify users' listening history (example). As I built out the rendering code, the large quantity of data and rendered SVG components led to huge slowdowns of my browser. Due to that and other operational constraints, I decided to instead render the graphic on the server-side and send the SVG file to my front end. I am using JSDOM to simulate a DOM for D3 rendering (something similar to this) and that's generally working alright.

However, the one issue I'm having is with this line: https://github.com/curran/d3-area-label/blob/master/src/area-label.js#L79

SVGElement.getBBox() is undefined in the context of JSDOM. This of course makes sense, as JSDOM does not actually lay out and render elements, and rather handles only DOM manipulation. I have been tweaking the dependency code of d3-area-label and struggling to reproduce the functionality of getBBox in a way that can enable the package to properly position and scale labels.

As you mentioned in #26, measuring text labels is quite tricky. That said, I thought it would be worth reaching out to ask if you have any insight on how I might be able to tweak d3-area-label to support JSDOM or another non-browser environment.

Please let me know if you have any thoughts, and thanks again for creating this!

@curran
Copy link
Owner

curran commented Aug 14, 2023

Thanks for dropping this note!

Some approaches I can think of trying:

  • Detect if we're in a server environment, and if so swap out that measuring logic with a rough approximation of width based on character count and font size. It won't be exact but would probably be close. This should be, in theory, fairly low hanging fruit. I'd welcome a PR with this change!
  • If accuracy is desired, maybe the Canvas API could be used in a Node environment using node-canvas to measure the text exactly. Once the first solution is working, we could try this approach in place of the approximation.
  • Probably overkill, but it's also possible to spin up a headless Chrome instance on the server using something like Puppeteer. Then the code could run in that browser context inside the server, with full access to the CSS and SVG runtimes that support measuring text with the right font.

@Fil
Copy link

Fil commented Aug 14, 2023

Here's an example that uses the canvas API to measure text:
https://observablehq.com/@fil/automated-label-placement-france#textMeasure

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants