Closed oldrich-svec closed 3 years ago
Thanks for writing in.
When
plotly.js
is loaded in Chrome by the native ES6import
,
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 ES6import
, the loading crashes withCannot read property 'document' of undefined
at line18178
, i.e. atvar d3_document = this.document;
The problem is that the bundler assumes that when a function is executed without any
this
, thethis
will automatically be set towindow
. This is not the case with ES6 modules, wherethis
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 , thus both plotly.js and angular code is served by "legacy" way. Please check this link for more informations: https://blog.angular.io/version-8-of-angular-smaller-bundles-cli-apis-and-alignment-with-the-ecosystem-af0261112a27
So changing the following property in the tsconfig.json file hides the issue:
{ "compilerOptions": { "target": "es5" } }
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.
Just tried with the current latest version (1.52.2), and it's still broken. Angular 9 has also been released, so it's now the two latest versions that are affected. :(
We have a large Angular-based application, that we cannot update because of this issue. :(
Just tried with the current latest version (1.52.2), and it's still broken. Angular 9 has also been released, so it's now the two latest versions that are affected. :(
We have a large Angular-based application, that we cannot update because of this issue. :(
First, I would recommend taking a look at https://github.com/plotly/angular-plotly.js as that is apparently working with Angular 8.x+.
Otherwise, if it is an option for your project, I would recommend loading plotly.js via the CDN. I have upgraded to Angular 9 by lazy-loading the minified plotly.js this way and it is working very well. The main bundle is then also much smaller :-) (I'm no longer using the workaround I mentioned in my previous comment)
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:
@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
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:
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)
(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)
@tony same issue here. Cannot use react-plotly.js
on Codesandbox and Stackblitz, neither JavaScript or TypeScript.
It seems it is a plotly.js
issue.
OP's fix works for me. Should there be a PR for this?
I haven't been able to use the precompiled bundles in a Svelte+rollup application that I've been building, but I have been able to use the ES6 module e.g. plotly.js/lib/core
. Here's a solution that works for me in rollup.config.js
:
import replace from "@rollup/plugin-replace";
export default {
....
plugins([
replace({
"}()": "this.d3 = d3;\n}.apply(self);",
delimiters: ["this.d3 = d3;\n", ";"],
}),
...
])
}
I can't use plotly.js-dist
because I get an issue about process
.
Related: https://community.plotly.com/t/issue-in-electron-built-version/31303/5 (although this fix of marking as external does not work for me).
Solution for vue-cli-service
(using https://www.npmjs.com/package/string-replace-webpack-plugin)
const StringReplacePlugin = require("string-replace-webpack-plugin");
module.exports = {
chainWebpack: config => {
config.module
.rule('plotly')
.test(/plotly\.js$/)
.use('stringreplace')
.loader(StringReplacePlugin.replace({
replacements: [
{
pattern: /module.exports = d3; else this.d3 = d3;\n}\(\);/,
replacement: function() { return 'module.exports = d3; else this.d3 = d3;\n}.apply(self);' }
}
]}))
.end()
}
};
Seems it is not going to be fixed even in v.2.0.0 :(. So if anybody needs to fix this in minified version, look for:
"object"==typeof e&&e.exports?e.exports=t:this.d3=t}()
and replace it with:
"object"==typeof e&&e.exports?e.exports=t:this.d3=t}.apply(self)
In v2 we are no longer exporting d3 so we will have a path towards upgrading it to a version that doesn't suffer from this problem, but indeed, this current problem doesn't automatically go away in v2.
If anyone wants to implement the change in node_module and use a much more radical approach, leverage the patch-package utility.
In package.json scripts, one can use it following command to patch the node_modules
"postinstall": "./node_modules/.bin/patch-package"
The patches for plotly 1.58.4
diff --git a/node_modules/plotly.js/dist/plotly-with-meta.js b/node_modules/plotly.js/dist/plotly-with-meta.js
index 1aaac5a..cb3ecfe 100644
--- a/node_modules/plotly.js/dist/plotly-with-meta.js
+++ b/node_modules/plotly.js/dist/plotly-with-meta.js
@@ -35864,7 +35864,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
return request.responseXML;
});
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);
},{}],170:[function(_dereq_,module,exports){
module.exports = function () {
for (var i = 0; i < arguments.length; i++) {
diff --git a/node_modules/plotly.js/dist/plotly.js b/node_modules/plotly.js/dist/plotly.js
index 365230c..6268511 100644
--- a/node_modules/plotly.js/dist/plotly.js
+++ b/node_modules/plotly.js/dist/plotly.js
@@ -35864,7 +35864,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
return request.responseXML;
});
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);
},{}],170:[function(_dereq_,module,exports){
module.exports = function () {
for (var i = 0; i < arguments.length; i++) {
The patches for d3 3.5.17
diff --git a/node_modules/d3/d3.js b/node_modules/d3/d3.js
index aded45c..d5b3cad 100644
--- a/node_modules/d3/d3.js
+++ b/node_modules/d3/d3.js
@@ -9551,4 +9551,4 @@
return request.responseXML;
});
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;
-}();
\ No newline at end of file
+}.apply(self);
When
plotly.js
is loaded in Chrome by the native ES6import
, the loading crashes withCannot read property 'document' of undefined
at line18178
, i.e. atvar d3_document = this.document;
The problem is that the bundler assumes that when a function is executed without any
this
, thethis
will automatically be set towindow
. This is not the case with ES6 modules, wherethis
will be undefined.I fixed it by changing line
27724
from}();
to}.apply(self);
but this is just a hack :)