Hello, As the title suggests I’m having trouble with updating a range slider without getting a strange visual error. I have an application that allows the user to select a date, after selecting the date information is pulled from a database for that day and the range slider min is set to the earliest recorded time for that day) and the max is set to the latest recorded time, then finally the value is set to be from the min to the max. When a date is first selected the slider is fine. However if another date is selected and the earliest time for this day is earlier than the previous selection then the slider goes across the entire screen.
I am not sure how to fix this or if anyone has experienced this before, but any advice on how to prevent this would be appreciated. I will post the code for how the slider is built below but please let me know if you need any more information from me
@app.callback(
Output('slider-containter', 'children'),
[Input('data-store', 'data')])
def make_slider(data):
if data is None:
raise PreventUpdate
timestamps = data['timestamps']
start_time = min(timestamps)
end_time = max(timestamps)
return dcc.RangeSlider(
id='time-slider',
min = start_time,
max = end_time,
allowCross=False,
value = [start_time, end_time])
Thank you and have a wonderful day!
Edit:
Here is some code recreating the issue:
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from datetime import datetime
# Dash stylesheet setup
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.config['suppress_callback_exceptions']=True
app.layout = html.Div(children=[
html.H1(children='Dash App'),
html.Div(className='row', children=[
html.Div(
dcc.Dropdown
(
id='uid-select',
options=[{'label': 'A', 'value': 'A'}],
searchable=True,
clearable=False,
),
className='two columns'),
html.Div(
dcc.Dropdown
(
id='date-select',
searchable=True,
clearable=False,
),
className='two columns'),
html.Div(id='slider-containter', className='six columns'),
dcc.Store(id='data-store')
])
])
@app.callback(
Output('date-select', 'options'),
[Input('uid-select', 'value')])
def update_date_dropdown(uid):
if uid is None:
raise PreventUpdate
dates = []
if uid is 'A':
dates.append("04-16-2019")
dates.append("04-17-2019")
return [{'label': i,
'value': datetime.strptime(i, '%m-%d-%Y').timestamp()
} for i in dates]
'''
This callback does not accurately reflect its true purpose in the
full program. In the full code it involves a query based off a specific
identifier provided by the first dropdown, but here it should suffice
to say that this callback simply collects data including the time range
used to create the slider.
'''
@app.callback(
Output('data-store', 'data'),
[Input('date-select', 'value')])
def get_data(timestamp):
if timestamp is None:
raise PreventUpdate
timestamps = []
some_data = []
some_more_data = []
even_more_data = []
if timestamp == 1555387200:
timestamps.append(1555438040)
timestamps.append(1555442908)
if timestamp == 1555473600:
timestamps.append(1555497676)
timestamps.append(1555531820)
some_data.append("some data")
some_more_data.append("some more data")
even_more_data.append("even more data")
return {'some_data': some_data,
'some_more_data': some_more_data,
'even_more_data': even_more_data,
'timestamps': timestamps}
@app.callback(
Output('slider-containter', 'children'),
[Input('data-store', 'data')])
def make_slider(data):
if data is None:
raise PreventUpdate
timestamps = data['timestamps']
start_time = min(timestamps)
end_time = max(timestamps)
return dcc.RangeSlider(
id='time-slider',
min = start_time,
max = end_time,
allowCross=False,
value = [start_time, end_time])
if __name__ == '__main__':
app.run_server(debug=True)