Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit c5df0d3

Browse files
committed
Merge branch 'dev' into persistence
2 parents c725103 + 67ec2b7 commit c5df0d3

File tree

10 files changed

+125
-109
lines changed

10 files changed

+125
-109
lines changed

.github/CODEOWNERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# These owners will be the default owners for everything in
2+
# the repo. Unless a later match takes precedence
3+
* @alexcjohnson @byronz @Marc-Andre-Rivet

CHANGELOG.md

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

5+
## Unreleased
6+
### Fixed
7+
8+
- Fixed an infinite loop problem when `Graph` is wrapped by `Loading` component [#608](https://github.com/plotly/dash-core-components/issues/608)
9+
510
## [1.1.2] - 2019-08-27
611
### Fixed
712
- Fixed problems with `Graph` components leaking events and being recreated multiple times if declared with no ID [#604](https://github.com/plotly/dash-core-components/pull/604)

CONTRIBUTING.md

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ Please lint any additions to react components with `npm run lint`. Rules defined
1616

1717
Use the [GitHub flow][] when proposing contributions to this repository (i.e. create a feature branch and submit a PR against the master branch).
1818

19+
## Making a Contribution
20+
_For larger features, your contribution will have a higher likelihood of getting merged if you create an issue to discuss the changes that you'd like to make before you create a pull request._
21+
22+
1. Create a pull request.
23+
2. After a review has been done and your changes have been approved, they will be merged and included in a future release of Dash.
24+
3. If significant enough, you have created an issue about documenting the new feature or change and you have added it to the [dash-docs](https://github.com/plotly/dash-docs) project.
25+
1926
## Running the Tests
2027

2128
In order to run the tests, you first need to have built the JavaScript
@@ -24,33 +31,6 @@ you've pulled from upstream otherwise you may be running with an out of date
2431
`bundle.js`. See the instructions for building `bundle.js` in the [Testing
2532
Locally](README.md#testing-locally) section of README.md.
2633

27-
## Publishing New Components/Features
28-
29-
For now, multiple steps are necessary for publishing to NPM and PyPi,
30-
respectively. TODO:
31-
[#5](https://github.com/plotly/dash-components-archetype/issues/5) will roll up publishing steps into one workflow.
32-
33-
1. Create a pull request and tag the Plotly team (`@plotly/dash`) as well as an appropriate reviewer (frequent [contributors][] are a safe bet).
34-
2. After a review has been done and your changes have been approved, create a prerelease and comment in the PR. Version numbers should follow [semantic versioning][]. To create a prerelease:
35-
* Add `rc1` to `version.py` (`./dash_core_components/version.py`) e.g. `0.13.0rc1`
36-
* Add `-rc1` to `package.json` e.g. `0.13.0-rc1`
37-
* Update the `unpkg` link in `./dash_core_components/__init__.py`, replacing `__version__` with your release candidate (e.g. `"0.13.0-rc1"`)
38-
* Run `npm run publish-all`.
39-
- If needed, ask @chriddyp to get NPM / PyPi package publishing access.
40-
- If the `publish-all` script fails on the `twine` command, try running
41-
```sh
42-
twine upload dist/dash_core_components-X.X.X.tar.gz # where xx.x.x is the version number
43-
```
44-
3. Comment in the PR with the prerelease version
45-
4. Update the top-level comment to include info about how to install, a summary of the changes, and a simple example. For a good example, see the [Confirmation Modal component][].
46-
* This makes it easier for a community member to come in and try it out. As more folks review, it's harder to find the installation instructions deep in the PR
47-
* Keep this top-level comment updated with installation instructions (e.g. the `pip install` command)
48-
5. Make a post in the [Dash Community Forum][]
49-
* Title it `":mega: Announcement! New <Your Feature> - Feedback Welcome"`
50-
* In the description, link to the PR and any relevant issue(s)
51-
* Pin the topic so that it appears at the top of the forum for two weeks
52-
* For a good example, see the [Confirmation Modal announcement][]
53-
5434
## Updating Plotly.js
5535

5636
1. Download the latest plotly.js from the cdn: `$ wget https://github.com/plotly/plotly.js/releases/tag/v1.49.4`

LICENSE

Lines changed: 0 additions & 1 deletion
This file was deleted.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2019 Plotly Technologies
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

LICENSE.txt

Lines changed: 0 additions & 21 deletions
This file was deleted.

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ But, in order to do development locally, you need to install `dash` before every
1717
# python 2
1818
$ pip install virtualenv --user && virtualenv venv && . venv/bin/activate
1919
# python 3
20-
$ python -m venv && . venv/bin/activate
20+
$ python -m venv venv && . venv/bin/activate
2121

2222
# make sure dash is installed with dev and testing dependencies
2323
$ pip install dash[dev,testing] # in some shells you need \ to escape []
@@ -85,3 +85,7 @@ See the [dash-component-boilerplate](https://github.com/plotly/dash-component-bo
8585
[Dash Component Boilerplate]: (https://github.com/plotly/dash-component-boilerplate)
8686
[NPM package authors]: https://www.npmjs.com/package/dash-core-components/access
8787
[PyPi]: https://pypi.python.org/pypi
88+
89+
90+
## Big Thanks
91+
Cross-browser Testing Powered by [![image](https://user-images.githubusercontent.com/1394467/64290307-e4c66600-cf33-11e9-85a1-12c82230a597.png)](https://saucelabs.com)

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
"homepage": "https://github.com/plotly/dash-core-components",
1313
"main": "dash_core_components/dash_core_components.min.js",
1414
"scripts": {
15-
"prepare": "npm run build",
16-
"publish-all": "node scripts/publish.js",
1715
"start": "webpack-serve ./webpack.serve.config.js --open",
1816
"lint": "eslint src tests",
1917
"lint:py": "flake8 --ignore=E501,F401,F841,F811,W503 tests",

scripts/publish.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/components/Graph.react.js

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {Component} from 'react';
22
import PropTypes from 'prop-types';
3-
import {contains, filter, clone, has, isNil, type, omit} from 'ramda';
3+
import {contains, filter, clone, has, isNil, type, omit, equals} from 'ramda';
44
/* global Plotly:true */
55

66
const filterEventData = (gd, eventData, event) => {
@@ -83,7 +83,6 @@ class PlotlyGraph extends Component {
8383
plot(props) {
8484
const {figure, animate, animation_options, config} = props;
8585
const gd = this.gd.current;
86-
8786
if (
8887
animate &&
8988
this._hasPlotted &&
@@ -98,7 +97,6 @@ class PlotlyGraph extends Component {
9897
config: config,
9998
}).then(() => {
10099
const gd = this.gd.current;
101-
102100
// double-check gd hasn't been unmounted
103101
if (!gd) {
104102
return;
@@ -154,7 +152,14 @@ class PlotlyGraph extends Component {
154152
}
155153

156154
bindEvents() {
157-
const {setProps, clear_on_unhover} = this.props;
155+
const {
156+
setProps,
157+
clear_on_unhover,
158+
relayoutData,
159+
restyleData,
160+
hoverData,
161+
selectedData,
162+
} = this.props;
158163

159164
const gd = this.gd.current;
160165

@@ -172,30 +177,30 @@ class PlotlyGraph extends Component {
172177
setProps({clickAnnotationData});
173178
});
174179
gd.on('plotly_hover', eventData => {
175-
const hoverData = filterEventData(gd, eventData, 'hover');
176-
if (!isNil(hoverData)) {
177-
setProps({hoverData});
180+
const hover = filterEventData(gd, eventData, 'hover');
181+
if (!isNil(hover) && !equals(hover, hoverData)) {
182+
setProps({hoverData: hover});
178183
}
179184
});
180185
gd.on('plotly_selected', eventData => {
181-
const selectedData = filterEventData(gd, eventData, 'selected');
182-
if (!isNil(selectedData)) {
183-
setProps({selectedData});
186+
const selected = filterEventData(gd, eventData, 'selected');
187+
if (!isNil(selected) && !equals(selected, selectedData)) {
188+
setProps({selectedData: selected});
184189
}
185190
});
186191
gd.on('plotly_deselect', () => {
187192
setProps({selectedData: null});
188193
});
189194
gd.on('plotly_relayout', eventData => {
190-
const relayoutData = filterEventData(gd, eventData, 'relayout');
191-
if (!isNil(relayoutData)) {
192-
setProps({relayoutData});
195+
const relayout = filterEventData(gd, eventData, 'relayout');
196+
if (!isNil(relayout) && !equals(relayout, relayoutData)) {
197+
setProps({relayoutData: relayout});
193198
}
194199
});
195200
gd.on('plotly_restyle', eventData => {
196-
const restyleData = filterEventData(gd, eventData, 'restyle');
197-
if (!isNil(restyleData)) {
198-
setProps({restyleData});
201+
const restyle = filterEventData(gd, eventData, 'restyle');
202+
if (!isNil(restyle) && !equals(restyle, restyleData)) {
203+
setProps({restyleData: restyle});
199204
}
200205
});
201206
gd.on('plotly_unhover', () => {
@@ -236,17 +241,11 @@ class PlotlyGraph extends Component {
236241
*/
237242
return;
238243
}
239-
240-
const figureChanged = this.props.figure !== nextProps.figure;
241-
242-
if (figureChanged) {
244+
if (this.props.figure !== nextProps.figure) {
243245
this.plot(nextProps);
244246
}
245247

246-
const extendDataChanged =
247-
this.props.extendData !== nextProps.extendData;
248-
249-
if (extendDataChanged) {
248+
if (this.props.extendData !== nextProps.extendData) {
250249
this.extend(nextProps);
251250
}
252251
}

tests/integration/graph/test_graph_basics.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
import pytest
2+
import pandas as pd
3+
import numpy as np
14
import dash
25
import dash_html_components as html
36
import dash_core_components as dcc
7+
from dash.dependencies import Input, Output
8+
import dash.testing.wait as wait
49

510

611
def test_grbs001_graph_without_ids(dash_duo):
@@ -20,3 +25,59 @@ def test_grbs001_graph_without_ids(dash_duo):
2025
assert not dash_duo.wait_for_element(".graph-no-id-2").get_attribute(
2126
"id"
2227
), "the graph should contain no more auto-generated id"
28+
29+
30+
@pytest.mark.DCC608
31+
def test_grbs002_wrapped_graph_has_no_infinite_loop(dash_duo):
32+
33+
df = pd.DataFrame(np.random.randn(50, 50))
34+
figure = {
35+
"data": [
36+
{"x": df.columns, "y": df.index, "z": df.values, "type": "heatmap"}
37+
],
38+
"layout": {"xaxis": {"scaleanchor": "y"}},
39+
}
40+
41+
app = dash.Dash(__name__)
42+
app.layout = html.Div(
43+
style={
44+
"backgroundColor": "red",
45+
"height": "100vmin",
46+
"width": "100vmin",
47+
"overflow": "hidden",
48+
"position": "relative",
49+
},
50+
children=[
51+
dcc.Loading(
52+
children=[
53+
dcc.Graph(
54+
id="graph",
55+
figure=figure,
56+
style={
57+
"position": "absolute",
58+
"top": 0,
59+
"left": 0,
60+
"backgroundColor": "blue",
61+
"width": "100%",
62+
"height": "100%",
63+
"overflow": "hidden",
64+
},
65+
)
66+
]
67+
)
68+
],
69+
)
70+
71+
@app.callback(Output("graph", "figure"), [Input("graph", "relayoutData")])
72+
def selected_df_figure(selection):
73+
figure["data"][0]["x"] = df.columns
74+
figure["data"][0]["y"] = df.index
75+
figure["data"][0]["z"] = df.values
76+
return figure
77+
78+
dash_duo.start_server(app)
79+
80+
wait.until(lambda: dash_duo.driver.title == "Dash", timeout=2)
81+
assert (
82+
len({dash_duo.driver.title for _ in range(20)}) == 1
83+
), "after the first update, there should contain no extra Updating..."

0 commit comments

Comments
 (0)