From 4a58d909576eeaf2895bd5588ce2d75a5bd609c1 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Mon, 9 Apr 2018 12:27:28 -0400 Subject: [PATCH 1/3] integration test --- test/test_integration.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/test_integration.py b/test/test_integration.py index 8b44cc0c9..019d39531 100644 --- a/test/test_integration.py +++ b/test/test_integration.py @@ -460,3 +460,39 @@ def update_pathname(n_clicks, current_pathname): self.wait_for_text_to_equal('#test-search', '?queryA=valueA') self.wait_for_text_to_equal('#test-hash', '') self.snapshot('link -- /test/pathname/a?queryA=valueA') + + + def test_candlestick(self): + app = dash.Dash(__name__) + app.layout = html.Div([ + html.Button( + id='button', + children='Update Candlestick', + n_clicks=0 + ), + dcc.Graph(id='graph') + ]) + + @app.callback(Output('graph', 'figure'), [Input('button', 'n_clicks')]) + def update_graph(n_clicks): + return { + 'data': [{ + 'open': [1] * 5, + 'high': [3] * 5, + 'low': [0] * 5, + 'close': [2] * 5, + 'x': [n_clicks] * 5 + }] + } + self.startServer(app=app) + + button = self.wait_for_element_by_css_selector('#button') + self.snapshot('candlestick - initial') + button.click() + time.sleep(2) + self.snapshot('candlestick - 1 click') + + button.click() + time.sleep(2) + self.snapshot('candlestick - 2 click') + From 56c5c01b5446178b23e3749ef7d498334df1e513 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Mon, 9 Apr 2018 12:09:57 -0400 Subject: [PATCH 2/3] newPlot if finance charts, react otherwise --- src/components/Graph.react.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/components/Graph.react.js b/src/components/Graph.react.js index 20b4da617..87a01a2ff 100644 --- a/src/components/Graph.react.js +++ b/src/components/Graph.react.js @@ -73,16 +73,31 @@ export default class PlotlyGraph extends Component { plot(props) { const {id, figure, animate, animation_options, config} = props; const gd = document.getElementById(id); + if (animate && this._hasPlotted && figure.data.length === gd.data.length) { return Plotly.animate(id, figure, animation_options); } else { - return Plotly.react(id, figure.data, figure.layout, config).then(() => { - if (!this._hasPlotted) { - this.bindEvents(); - Plotly.Plots.resize(document.getElementById(id)); - this._hasPlotted = true; + + let PlotMethod; + if (R.intersection( + R.pluck('type', figure.data), + ['candlestick', 'ohlc']).length + ) { + PlotMethod = Plotly.newPlot; + } else { + PlotMethod = Plotly.react; + } + + return PlotMethod(id, figure.data, figure.layout, config).then( + () => { + if (!this._hasPlotted) { + this.bindEvents(); + Plotly.Plots.resize(document.getElementById(id)); + this._hasPlotted = true; + } } - }); + ); + } } From 332606447c5b9e01ced75618d800d7b81f64ff90 Mon Sep 17 00:00:00 2001 From: chriddyp Date: Mon, 9 Apr 2018 12:52:31 -0400 Subject: [PATCH 3/3] imports --- src/components/Graph.react.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/Graph.react.js b/src/components/Graph.react.js index 87a01a2ff..0315567ba 100644 --- a/src/components/Graph.react.js +++ b/src/components/Graph.react.js @@ -1,6 +1,6 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import {contains, filter, has, isNil, type} from 'ramda'; +import {contains, intersection, filter, has, isNil, type, pluck} from 'ramda'; /* global Plotly:true */ const filterEventData = (gd, eventData, event) => { @@ -79,8 +79,8 @@ export default class PlotlyGraph extends Component { } else { let PlotMethod; - if (R.intersection( - R.pluck('type', figure.data), + if (intersection( + pluck('type', figure.data), ['candlestick', 'ohlc']).length ) { PlotMethod = Plotly.newPlot;