Skip to content

Commit cc7fde3

Browse files
authored
Merge pull request #2610 from plotly/feat/pjs-from-ppy
Load plotly.js from plotly.py
2 parents 7dd07d5 + f3f03cd commit cc7fde3

File tree

12 files changed

+72
-63
lines changed

12 files changed

+72
-63
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
All notable changes to `dash` will be documented in this file.
33
This project adheres to [Semantic Versioning](https://semver.org/).
44

5+
## [UNRELEASED]
6+
## Changed
7+
8+
- [#2610](https://github.com/plotly/dash/pull/2610) Load plotly.js bundle/version from plotly.py
59

610
## [2.12.1] - 2023-08-16
711

components/dash-core-components/dash_core_components_base/__init__.py

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import os as _os
33
import sys as _sys
4+
45
import dash as _dash
56

67
from ._imports_ import * # noqa: F401, F403, E402
@@ -121,33 +122,6 @@
121122
"namespace": "dash",
122123
"dynamic": True,
123124
},
124-
{
125-
"relative_package_path": "dcc/plotly.min.js",
126-
"external_url": (
127-
"https://unpkg.com/dash-core-components@{}"
128-
"/dash_core_components/plotly.min.js"
129-
).format(__version__),
130-
"namespace": "dash",
131-
"async": "eager",
132-
},
133-
{
134-
"relative_package_path": "dcc/async-plotlyjs.js",
135-
"external_url": (
136-
"https://unpkg.com/dash-core-components@{}"
137-
"/dash_core_components/async-plotlyjs.js"
138-
).format(__version__),
139-
"namespace": "dash",
140-
"async": "lazy",
141-
},
142-
{
143-
"relative_package_path": "dcc/async-plotlyjs.js.map",
144-
"external_url": (
145-
"https://unpkg.com/dash-core-components@{}"
146-
"/dash_core_components/async-plotlyjs.js.map"
147-
).format(__version__),
148-
"namespace": "dash",
149-
"dynamic": True,
150-
},
151125
]
152126
)
153127

components/dash-core-components/package-lock.json

Lines changed: 0 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

components/dash-core-components/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
"test": "run-s -c lint test:intg test:pyimport",
2424
"test:intg": "pytest --nopercyfinalize --headless tests/integration ",
2525
"test:pyimport": "python -m unittest tests/test_dash_import.py",
26-
"prebuild:js": "cp node_modules/plotly.js-dist-min/plotly.min.js dash_core_components_base/plotly.min.js",
2726
"build:js": "webpack --mode production",
2827
"build:backends": "dash-generate-components ./src/components dash_core_components -p package-info.json && cp dash_core_components_base/** dash_core_components/ && dash-generate-components ./src/components dash_core_components -p package-info.json -k RangeSlider,Slider,Dropdown,RadioItems,Checklist,DatePickerSingle,DatePickerRange,Input,Link --r-prefix 'dcc' --r-suggests 'dash,dashHtmlComponents,jsonlite,plotly' --jl-prefix 'dcc' && black dash_core_components",
2928
"build": "run-s prepublishOnly build:js build:backends",
@@ -49,7 +48,6 @@
4948
"mathjax": "^3.2.2",
5049
"moment": "^2.29.4",
5150
"node-polyfill-webpack-plugin": "^2.0.1",
52-
"plotly.js-dist-min": "2.25.2",
5351
"prop-types": "^15.8.1",
5452
"ramda": "^0.29.0",
5553
"rc-slider": "^9.7.5",
Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1-
export default () => Promise.resolve(window.Plotly ||
2-
import(/* webpackChunkName: "plotlyjs" */ 'plotly.js-dist-min').then(({ default: Plotly }) => {
3-
window.Plotly = Plotly;
4-
return Plotly;
5-
}));
1+
export default () => {
2+
return Promise.resolve(window.Plotly || new Promise((resolve, reject) => {
3+
/* eslint-disable prefer-const */
4+
let timeoutId;
5+
6+
const element = document.createElement('script');
7+
element.src = window._dashPlotlyJSURL;
8+
element.async = true;
9+
element.onload = () => {
10+
clearTimeout(timeoutId);
11+
resolve();
12+
};
13+
element.onerror = (error) => {
14+
clearTimeout(timeoutId);
15+
reject(error);
16+
};
617

18+
timeoutId = setTimeout(() => {
19+
element.src = '';
20+
reject(new Error(`plotly.js did not load after 30 seconds`));
21+
}, 3 * 10 * 1000);
22+
23+
document.querySelector('body').appendChild(element);
24+
}));
25+
}

components/dash-core-components/tests/integration/graph/test_graph_varia.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ def show_relayout_data(data):
128128

129129
dash_dcc.start_server(app)
130130

131+
time.sleep(1)
132+
131133
# use this opportunity to test restyleData, since there are multiple
132134
# traces on this graph
133135
legendToggle = dash_dcc.find_element(

components/dash-core-components/tests/integration/tooltip/test_tooltip.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def update_tooltip_content(hoverData):
8080
assert 175 < coords[0] < 185, "x0 is about 200 minus half a marker size"
8181
assert 175 < coords[1] < 185, "y0 is about 200 minus half a marker size"
8282

83+
elem = dash_dcc.find_element("#graph .nsewdrag")
84+
8385
ActionChains(dash_dcc.driver).move_to_element_with_offset(
8486
elem, 5, elem.size["height"] - 5
8587
).perform()

dash/dash-renderer/src/APIController.react.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ const UnconnectedContainer = props => {
7272
}
7373
});
7474

75+
useEffect(() => {
76+
if (config.serve_locally) {
77+
window._dashPlotlyJSURL = `${config.requests_pathname_prefix}_dash-component-suites/plotly/package_data/plotly.min.js`;
78+
} else {
79+
window._dashPlotlyJSURL = config.plotlyjs_url;
80+
}
81+
}, []);
82+
7583
let content;
7684
if (
7785
layoutRequest.status &&

dash/dash-renderer/src/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ type Config = {
1919
'Content-Type': string;
2020
};
2121
};
22+
serve_locally?: boolean;
23+
plotlyjs_url?: string;
2224
};
2325

2426
export default function getConfigFromDOM(): Config {

dash/dash.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ class Dash:
341341
if not added previously.
342342
"""
343343

344+
_plotlyjs_url: str
345+
344346
def __init__( # pylint: disable=too-many-statements
345347
self,
346348
name=None,
@@ -588,6 +590,8 @@ def _handle_error(_):
588590
_get_app.APP = self
589591
self.enable_pages()
590592

593+
self._setup_plotlyjs()
594+
591595
def _add_url(self, name, view_func, methods=("GET",)):
592596
full_name = self.config.routes_pathname_prefix + name
593597

@@ -619,6 +623,25 @@ def _setup_routes(self):
619623
# catch-all for front-end routes, used by dcc.Location
620624
self._add_url("<path:path>", self.index)
621625

626+
def _setup_plotlyjs(self):
627+
# pylint: disable=import-outside-toplevel
628+
from plotly.offline import get_plotlyjs_version
629+
630+
url = f"https://cdn.plot.ly/plotly-{get_plotlyjs_version()}.min.js"
631+
632+
# pylint: disable=protected-access
633+
dcc._js_dist.extend(
634+
[
635+
{
636+
"relative_package_path": "package_data/plotly.min.js",
637+
"external_url": url,
638+
"namespace": "plotly",
639+
"async": "eager",
640+
}
641+
]
642+
)
643+
self._plotlyjs_url = url
644+
622645
@property
623646
def layout(self):
624647
return self._layout
@@ -702,7 +725,10 @@ def _config(self):
702725
"suppress_callback_exceptions": self.config.suppress_callback_exceptions,
703726
"update_title": self.config.update_title,
704727
"children_props": ComponentRegistry.children_props,
728+
"serve_locally": self.config.serve_locally,
705729
}
730+
if not self.config.serve_locally:
731+
config["plotlyjs_url"] = self._plotlyjs_url
706732
if self._dev_tools.hot_reload:
707733
config["hot_reload"] = {
708734
# convert from seconds to msec as used by js `setInterval`

0 commit comments

Comments
 (0)