How to use Plotly with Stencil?

I’m trying to use Plotly.js with Stencil, but one of Plotly’s dependencies uses glslify, which apparently has an “Octal literal in strict mode”. Is no one else using Plotly with Stencil, or is there another way to get past this issue? I’m currently using the @types/plotly.js TypeScript types and running on Windows using the Stencil app template.

[ ERROR ]  Rollup: Parse Error
           Octal literal in strict mode (Note that you need plugins to import files that are not        
           JavaScript) 1: export default
           '...\node_modules\glslify' ^ 

I saw the note about Strict Mode, but I am not sure how to lobby the authors for such a large package.

Below is how i solve this problem for my to be app by importing it as external module loaded via script tag,
this way the typescript compiler will exclude plotly.js-dist and only include @types/plotly.js for the ambient declaration.

package.json:

  "devDependencies": {
    ...,
    "@types/plotly.js": "^1.50.16"
  },
  "dependencies": {
    ...,
    "plotly.js-dist": "^1.54.7"
  }

stencil.config.ts:

  outputTargets: [{
    ...,
    copy: [
      {
        src: '../node_modules/plotly.js-dist/plotly.js',
        dest: 'lib/plotly.js'
      }
    ],

tsconfig.json:

  "compilerOptions": {
    ...,
    "allowUmdGlobalAccess": true,
    "files": [
      "node_modules/@types/plotly.js/index.d.ts"
    ],

index.html:

...
<script nomodule src="/build/app.js"></script>
<script src="/lib/plotly.js"></script>

then in your tsx file you will be able to use Plotly.xxx

import { Component, h } from '@stencil/core';
@Component({
    tag: 'app-draw'
})

export class AppDraw {
    componentDidRender() {
        // mousewheel or two-finger scroll zooms the plot
        let trace1 = {
            x:['2020-10-04', '2021-11-04', '2023-12-04'],
            y: [90, 40, 60],
            type: 'scatter'
        } as Plotly.PlotData;

        var data = [trace1];

        var layout = {
            title: 'Scroll and Zoom',
            showlegend: false
        };

        Plotly.newPlot('myDiv', data, layout, {scrollZoom: true});
    }

    render() {
        return [
            <app-head head="Draw"></app-head>,
            <div id="myDiv"></div>
        ];
    }
}
1 Like

That is a fantastic solution! Thank you!

Seems this works great for an app. However, when I tried to move my components to a library, Stencil tries to load plotly.js, which is not there. I cannot determine why it won’t ignore the dependency.

Uncaught TypeError: Cannot set property 'traces' of undefined
    at HTMLDocument.<anonymous> ((index):24)
index-1eb1703e.js:2694 TypeError: Failed to resolve module specifier "plotly.js". Relative references must start with either "/", "./", or "../". undefined
consoleError @ index-1eb1703e.js:2694
index-1eb1703e.js:1938 Uncaught (in promise) Error: Constructor for "plotly-plot#undefined" was not found
    at initializeComponent (index-1eb1703e.js:1938)

Have you tried this with Stencil 2? It seems something changed. This was working with Stencil v1.17.3, but with 2.20 and 2.30, I see the error.

This approach only works without shadow DOM ?.
Is there a way to make plotly work inside shadow dom ?
Thanks in advance

Hello ,

This approach only works without shadow DOM ?.
Is there a way to make plotly work inside shadow dom ?
Thanks in advance