Plotly.js: Native ES6 modules vs. the bundle

Created on 6 Feb 2019  Â·  33Comments  Â·  Source: plotly/plotly.js

When plotly.js is loaded in Chrome by the native ES6 import, the loading crashes with Cannot read property 'document' of undefined at line 18178, i.e. at var d3_document = this.document;

The problem is that the bundler assumes that when a function is executed without any this, the this will automatically be set to window. This is not the case with ES6 modules, where this will be undefined.

I fixed it by changing line 27724 from }(); to }.apply(self); but this is just a hack :)

bug ♥ NEEDS SPON$OR

Most helpful comment

Is there a 'real' solutions for this available? I'd like to use Plotly for an Angular 8 project - but reverting to es5 is not really an option (it will break for Angular 9 I think). I was so hoping to use plotly as a Highchart replacement - but no dice I'm afraid.

All 33 comments

Thanks for writing in.

When plotly.js is loaded in Chrome by the native ES6 import,

Can you share a reproducible example of how you're going about doing this. Thank you!

Try:

<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
</head>
<body>
<script type="module" src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</body>
</html>

or alternatively:

<script type="module">
    import 'https://cdn.plot.ly/plotly-latest.min.js'
</script>

In a codepen: https://codepen.io/alexcjohnson/pen/aXEbOa?editors=1011

That particular error is with d3v3 - seems like v4 fixes it so we should get it when we leapfrog to v5. Will be interesting to see if there's anything else in our code that uses this to mean the window (or anything else that's incompatible with ES6 modules... I'm not very familiar) but it doesn't seem like there's much point trying before the d3 upgrade.

@oldrich-svec

I fixed it by changing line 27724 from }(); to }.apply(self); but this is just a hack :)

Can you please provide which particular line had to be changed. I am stuck with this for the past two days (tried many things with babel options - nothing worked)

Any fix for this?

Fix for version 1.48.2; the change is at line number 32481 '/node_modules/plotly.js/dist/plotly.js'

Anybody know if there is a issue for this filed in the d3 project?

@jmsuresh In this file:

https://cdnjs.cloudflare.com/ajax/libs/plotly.js/1.49.1/plotly.js

search for define(d3). You will find:

if (typeof define === "function" && define.amd) this.d3 = d3, define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; else this.d3 = d3;
}();

Change }(); to }.apply(self);

From https://github.com/plotly/plotly.js/issues/4130 @Arjun-Shinojiya wrote:

I am trying to integrate plotly.js in my Angular 8 project. I successfully integrated it and tested it in local ,that time it is working fine without any error. But when I check it in live server ,that time I am getting cannot read property 'document ' of undefined error.. I also similar issue blog in this repository.`.I wanted to try this hack
changing line 27724 from }(); to }.apply(self); but this is just a hack :)
But I dont know in which module file I can get this line.Currently none of the plotly.js file have 27724 lines

Maybe someone here can help.

When plotly.js is loaded in Chrome by the native ES6 import, the loading crashes with Cannot read property 'document' of undefined at line 18178, i.e. at var d3_document = this.document;

The problem is that the bundler assumes that when a function is executed without any this, the this will automatically be set to window. This is not the case with ES6 modules, where this will be undefined.

I fixed it by changing line 27724 from }(); to }.apply(self); but this is just a hack :)

@oldrich-svec can you please tell the exact location of the file which you mentioned in this questions last line? .I am facing the same issue.

see #3518 (comment)

So I should use plotly.js via CDN in angular 8 right?

@Arjun-Shinojiya it is up to you how you use plotly.js ;). The comment just shows you what line you want to edit.

Is editing the line of code the only solution? What happens when I want to upgrade to a new version of plotly? I have to edit it every time?

@TravisLRiffle yes you have to reapply your hack every time! For me, it is not a solution for enterprise applications.

After fixing this, I got a d3_xhr-not found-error although it's defined

_Alternative workaround for Angular 8 upgraders:_ For those of us coming here having encountered this issue when upgrading to Angular 8, an alternative workaround solution to editing the plotly.js file is to not use the new "Differential Loading by Default" as mentioned in this comment on angular-plotly.js: https://github.com/plotly/angular-plotly.js/issues/75#issuecomment-526871836

I could solve the issue forcing the typescript to be generated as "target": "es5" making it not use the

I managed to get it working in ng9 with ivy by including plotly.min.js as a regular script reference on the page and then PlotlyModule.plotlyjs = (<any>window).Plotly; with the PlotlyModule. I could not get PlotlyViaWindowModule, it compiled but got some invalid plotly version error.

Used angular.json to copy it to assets from the node_modules.
"assets": ["src/assets", { "glob": "plotly.min.js", "input": "./node_modules/plotly.js/dist/", "output": "./" }],

I managed to include the dist/plotly.js into some angular project. I found some issue around d3_document = this.document and some other places like var d3_mouse_bug44083 = this.navigator && /WebKit/.test(this.navigator.userAgent) ? -1 : 0;

On some places the this is undefined in case we run the project with es2015 and this is windows object in case we run the project with es5.

As far I see the line d3_document = this.document exist only in dist folder not in the src

Question: Where is the correct place to edit this d3_document = this.document line in order to correct each distribution version (plotly.js, plotly.basic.js, plotly.min.js, etc)

d3_document would be in the d3 source, not the plotly.js source at all. Presumably this has been addressed in more recent d3 versions? Could be another bit of motivation to upgrade https://github.com/plotly/plotly.js/issues/424 although unfortunately this is a substantial project

@oldrich-svec can you please tell the exact location of the file which you mentioned in this questions last line? .I am facing the same issue.

In Plotly v1.54.1, I've found it to be line 34472. It's immediately after an if statement that seems to be talking about modules,

  if (typeof define === "function" && define.amd) this.d3 = d3, define(d3); else if (typeof module === "object" && module.exports) module.exports = d3; else this.d3 = d3;
}.apply(self);
},{}],166:[function(_dereq_,module,exports){

Any real fix for this?
reproducable example

After making the change I get self not defined

I had this working for Angular 9. I think { "compilerOptions": { "target": "es5" } } had fixed it but its been a while since we added this. I just tried upgrading to Angular 10 and I am getting the following error:

TypeError: Cannot read property 'document' of undefined
    at plotly.js:24924

Which is:

var d3_document = this.document;

I am on "angular-plotly.js": "^2.0.0", and "plotly.js": "^1.54.5".

@fourgates I am using Plotly.js 1.54.5 with angular-plotly.js 2.0.0 in Angular 10 successfully. The property read issue only occurred when plotly.js/dist/plotly.js was imported into a shared module or a file imported into a shared module. I resolved the issue by ensuring the following two things:

  1. The PlotlyModule is imported only in leaf modules. Shared modules require leaf modules to import the dependency if they use angular-plotly.js or plotly.js.
  2. Import the PlotlyService and use PlotlyService.getPlotly to access the global Plotly.js API. I only experience problems with shared files, but I use this practice everywhere.

@oldrich-svec have you tried the above solution?
Wondering should we keep this issue open?
If so could you please provide an update using latest plotly.js version?
Thanks.

I have just tried to execute v1.54.7 code as described in https://github.com/plotly/plotly.js/issues/3518#issuecomment-461310766 and yes it is still failing with

Uncaught TypeError: Cannot read property 'document' of undefined
    at plotly-latest.min.js:20
    at Object.164 (plotly-latest.min.js:20)
    at a (plotly-latest.min.js:7)
    at plotly-latest.min.js:7
    at Object.728.../constants/numerical (plotly-latest.min.js:61)
    at a (plotly-latest.min.js:7)
    at plotly-latest.min.js:7
    at Object.1.../src/lib (plotly-latest.min.js:7)
    at a (plotly-latest.min.js:7)
    at plotly-latest.min.js:7

I do not use Angular so I did not test the above solution.

If I am not mistaken, all the solutions are either

  • to hack the plotly file as I did
  • or to load plotly as normal script and not ES6 module

This issue has been tagged with NEEDS SPON$OR

A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.

Sponsorship range: $10k-$15k

What Sponsorship includes:

  • Completion of this feature to the Sponsor's satisfaction, in a manner coherent with the rest of the Plotly.js library and API
  • Tests for this feature
  • Long-term support (continued support of this feature in the latest version of Plotly.js)
  • Documentation at plotly.com/javascript
  • Possibility of integrating this feature with Plotly Graphing Libraries (Python, R, F#, Julia, MATLAB, etc)
  • Possibility of integrating this feature with Dash
  • Feature announcement on community.plotly.com with shout out to Sponsor (or can remain anonymous)
  • Gratification of advancing the world's most downloaded, interactive scientific graphing libraries (>50M downloads across supported languages)

Please include the link to this issue when contacting us to discuss.

Looks like plotly needs to upgrade d3 to at least v4

(This isn't just an angular issue, all the codesandbox URLs on https://github.com/plotly/react-plotly.js are having this now)

Could anyone here get a working version of typescript + plotly.js on code sandbox?

All versions of those are failing as well. (for the sake of demos on this project and others)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

WG- picture WG-  Â·  3Comments

deecay picture deecay  Â·  3Comments

boleslawmaliszewski picture boleslawmaliszewski  Â·  3Comments

etpinard picture etpinard  Â·  3Comments

tim-sauchuk picture tim-sauchuk  Â·  3Comments