question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Plotly.js is incompatible with Chrome's native shadow DOM implementation

See original GitHub issue

Context

I develop and maintain ginkgobioworks/plotly-plot, a Polymer element that encapsulates plotly.js. Polymer is a web-component framework written by Google, which uses browser functionality known as the “shadow DOM” to isolate the internals of web components from the rest of the page.

Polymer 1.x has two kinds of shadow DOM implementations: native shadow DOM (v0), and a shim called “shady DOM.” Native shadow DOM is newer and yields improved performance, but it has poor support in browsers outside of Chrome and can cause problems with existing code. For this reason, shady DOM is still the default implementation in Polymer 1.x.

Issue

Unfortunately, native shadow DOM is currently incompatible with plotly.js. The icon toolbar layout code in the plotly.js library fails for all plotly plots rendered inside a shadow DOM.

Example

Since it’s a pain to create your own elements without the tools in a code pen, the easiest example to observe is on the plotly-plot demo page.

You can render the page either with shady DOM (the default) or with shadow DOM by passing in the ?dom=shadow GET parameter, which forces Polymer to use native shadow DOM v0 in browsers that support it.

Expected/Observed

Under shady DOM (no GET parameter), the elements behave as expected. Under shadow DOM (with the GET parameter), however, the toolbars fail to render entirely.

Impact

I don’t know why this is the case. It might have to do with SVG support for the buttons, or CSS effects.

The work-around on my side is that anyone who consumes my element must not turn on native shadow DOM rendering on any page that renders a plotly-plot widget. This is fine for small, simple pages, but can be a real drag when front-end performance is at stake.

I’m wondering if there might be a relatively easy fix that would prevent this from happening—if there is, it’d be nice to do it. If not, it’s probably not worth doing any serious rewriting for this use case.

In any case, thought you’d be interested to know.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:11 (2 by maintainers)

github_iconTop GitHub Comments

4reactions
jdfergasoncommented, Jul 3, 2017

I believe the problem is in the way that plotly adds style to the document. When the plotly.js script is loaded it initializes itself by running the following function for a number of css styles:

lib.addStyleRule = function(selector, styleString) {
    if(!lib.styleSheet) {
        var style = document.createElement('style');
        // WebKit hack :(
        style.appendChild(document.createTextNode(''));
        document.head.appendChild(style);
        lib.styleSheet = style.sheet;
    }
    var styleSheet = lib.styleSheet;

    if(styleSheet.insertRule) {
        styleSheet.insertRule(selector + '{' + styleString + '}', 0);
    }
    else if(styleSheet.addRule) {
        styleSheet.addRule(selector, styleString, 0);
    }
    else lib.warn('addStyleRule failed');
};

This appends a new style tag to the head of the document. Chrome doesn’t seem to totally understand this because if you try to inspect the element it just appears empty. This is not a problem if you are not using a shadowRoot as the styles are still correctly applied. However, in a shadowRoot the style encapsulation screws things up and the styles are not found.

You can get around this by adding the required styles to your template style section. This is kind of a mess but it does work. I have created an example project that shows the initial problem and the hack working at: plotly-polymer-fix

There is a script at happybase that claims to be a cross-browser way to create css styles dynamically. I replaced the original implementation of addStyleRule with this one and it also does not work.

2reactions
darkenginescommented, Sep 13, 2020

This is because css must be defined inside the component’s shadow dom. Just generate the final css and do what you need with it:

sass .\node_modules\plotly.js\src\css\style.scss > plolty.css

Then do what you want with css, if you are using lit-element your can expose the css this way:

import { css } from 'lit-element';

const plotlyStyle = css`
	.js-plotly-plot .plotly,
	.js-plotly-plot .plotly div {
		direction: ltr;
		font-family: 'Open Sans', verdana, arial, sans-serif;
		margin: 0;
		padding: 0;
	}
        ........
        *** css from generated plotly.css file ***
        ........
	.plotly-notifier .notifier-close:hover {
		color: #444;
		text-decoration: none;
		cursor: pointer;
	}
`;
export default plotlyStyle;

Then you are free to import this piece of css in your individual components.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Developers - Plotly.js is incompatible with Chrome's native shadow ...
Plotly.js is incompatible with Chrome's native shadow DOM implementation. ... I develop and maintain ginkgobioworks/plotly-plot, a Polymer element that ...
Read more >
ginkgobioworks/plotly-plot - webcomponents.org
NOTE: The plotly.js library is incompatible with shadow DOM. Polymer elements, and web components in general, depend on being able to "hide" their...
Read more >
plotly-plot documentation - GitHub Pages
Unfortunately, native shadow DOM is currently incompatible with plotly.js. The icon toolbar layout code in the plotly.js library fails for all plotly plots ......
Read more >
Plotly.js in ShadowDOM - CodePen
Hack to correctly style plotly inside of Shadow DOM. -->. 9. <style>. 10 .js-plotly-plot .plotly,.js-plotly-plot .plotly div {. 11. direction:ltr;.
Read more >
plotly.js-finance-dist | Yarn - Package Manager
Contains trace modules bar , candlestick , funnel , funnelarea , histogram , indicator , ohlc , pie , scatter and waterfall ....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found