"global is undefined" when using viz.js through d3-graphviz

See https://beta.observablehq.com/@magjac/d3-graphviz-fiddling-not-working

I’m getting “global is undefined” when d3-graphviz is about to call Viz. The notebook shows that Viz is working when used directly, but not when called through d3-graphviz.

A similar example works outside of Observable:

I’m pretty sure it has something to do with module loading, but this is terra incognita for me.

How can I debug this better?
Is there a way to get normal stack traces in Observable?
I made a local debug version of d3-graphviz, but when I try to load it from a local server, I get “Error: unable to load module”. Is it only possible to load libraries from unpkg?

Here’s an even simpler example without loading viz.js at all and stepwise application of the d3-graphviz methods: https://beta.observablehq.com/@magjac/d3-graphviz-fiddling-without-viz-js-loading-not-working

Since the error is the same, I suspect that I haven’t been able to load viz.js correctly in the first example or that I use Viz incorrectly in d3-graphviz, but in a way that works when run outside Observable.

https://beta.observablehq.com/@fil/hello-d3-graphviz works

I’m not sure I answered your question though :wink:
The error I’m getting on your notebook is a bit different than what you have written down: Cannot read property 'Int8Array' of undefined

@Fil Thanks a lot! Deeply appreciate your help. Now I will try to understand it as well :grin:

In case you missed it, here’s a notebook that demonstrates how to use Graphviz in Observable using Viz.js:

To use this in your own notebook, you can require it:

dot = require("@observablehq/graphviz")

And then use the dot tagged template literal:

dot`digraph { a -> b; }`

Viz.js-lite is slightly smaller than d3-graphviz (1.6M versus 2.2M).

Thanks. Actually I started out with a fork of that notebook with the intention to add animated transitions to it with d3-graphviz, but couldn’t get it to work. Hopefully, I can come back with that soon now that I’ve gotten help.

@mbostock d3-graphviz is only 41 KB (15 KB minified) in itself. You’re probably comparing viz-lite.js with a bundle containing d3-graphviz, the full version of viz.js and some d3 core modules. The difference between viz-lite.js and viz.js is around 0.6 MB.

Where did you get the numbers from?

I would expect that the overhead added by d3-graphviz and the d3 core modules is negligible when comparing with viz.js or viz-lite.js.

I’m referring to the bundled d3-graphviz (check the network tab in your browser), which includes the D3 and Viz.js dependencies:

https://bundle.run/d3-graphviz

I got 2.78 MB for that link before I released a new version of d3-graphviz with viz.js upgraded to v1.8.1 which reduces the size of the bundle with 0.53 MB.

https://bundle.run/d3-graphviz@2.0.0: 2.78 MB
https://bundle.run/d3-graphviz@2.1.0: 2.25 MB

Do you see the same reduction with v2.1.0?

I collected some sizes in my very first (working) public notebook :grinning:: https://beta.observablehq.com/@magjac/size-of-libraries-and-bundles-related-to-d3-graphviz

I noticed that the bundle.run version of d3-graphviz seems to work fine in a standalone notebook:

https://beta.observablehq.com/d/45f9fc3edb7a529f

1 Like

I did a little more digging and this appears to be a problem with Viz.js 1.8.1, which uses a newer version of Emscripten than 1.8.0. So, this works fine:

Viz = require("viz.js@1.8.0/viz.js").catch(() => window.Viz)
html`${Viz("digraph {a -> c}")}`

But, if you change 1.8.0 to 1.8.1, you get TypeError: Cannot read property ‘Int8Array’ of undefined.

The doubly strange thing is that @observablehq/graphviz uses Viz.js-lite 1.8.1 and has no problems.

1 Like

And a little more digging… Viz.js 1.8.1 has a broken UMD block that causes it to export the Emscripten-generated Module rather than Viz. I’ve filed a bug here:

1 Like

Nice implementation! Thanks. Even better than @Fil’s Hello d3-graphviz (no offense)

1 Like

@mbostock Thanks a lot for digging into the problem and filing the issue on viz.js! With viz.js v1.8.2 my notebook is working: https://beta.observablehq.com/@magjac/d3-graphviz-fiddling-not-working (disregard the obsolete name :grin:).

:champagne:

1 Like

The https://beta.observablehq.com/d/45f9fc3edb7a529f example above no longer works. It doesn’t even load the notebook. In the console:

Error: 
bundle.86e27c12dc12d7cbbdac77c3b72faeab0dc9f0219789a2f82908792248171c66.js:2:68250
Source map error: request failed with status 403
Resource URL: https://static.observablehq.com/bundle.86e27c12dc12d7cbbdac77c3b72faeab0dc9f0219789a2f82908792248171c66.js
Source Map URL: bundle.86e27c12dc12d7cbbdac77c3b72faeab0dc9f0219789a2f82908792248171c66.js.map[Learn More]

I trashed the notebook because I thought things were resolved. Do you want me to restore it?

Things are indeed resolved, but I wanted to steal the implementation since I’m an Observable newbie😁. So yes please. Thank you.

The only thing in that notebook is:

d3_graphviz = require("https://bundle.run/d3-graphviz")
{
  const div = html`<div>`;
  d3_graphviz.graphviz(div, false).renderDot(`digraph { a -> b }`);
  return div;
}

So, there you go. :smile: