diff --git a/src/components/Graph.react.js b/src/components/Graph.react.js index 20b4da617..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) => { @@ -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 (intersection( + 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; + } } - }); + ); + } } 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') +