plotly / dash

Data Apps & Dashboards for Python. No JavaScript Required.
https://plotly.com/dash
MIT License
21.15k stars 2.04k forks source link

Slider mark does not move accordingly #2433

Open asicoderOfficial opened 1 year ago

asicoderOfficial commented 1 year ago

Context Python dependencies:

dash                2.8.1
dash-bootstrap-components 1.3.1

Chrome version: 110.0.5481.105 (Official Build) (64-bit)

The bug

When pressing a button that changes the slider max to one that is bigger than the previous selected, the selecting circle moves to the corresponding location in the slider, but the tooltip that shows the value selected, remains at the end.

Expected behavior

The tooltip moves together with the circle.

Screenshots

The initial maximum (30) has been selected.

slider30

Then, the maximum is set to 60, and the tooltip does not move to the middle as the point does.

slider60

Reproducible code

import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
from dash import html, dcc, Dash, callback

app = Dash('Slider marks bug reproducible example')

app.layout = html.Div([
    dbc.Row([
        dcc.Slider(1, 10, 1,
            value=1,
            id='slider',
            marks=None,
            tooltip={"placement": "top", "always_visible": True}
        ),
    ]),
    dbc.Row([
        dbc.RadioItems(id='radioitem',
            options=[{'label':'30', 'value': 30}, {'label':'60', 'value': 60}],
            value='30',
            inline=True,
            style={'marginTop': '5px', 'display': 'flex', 'justifyContent': 'space-around', 'flex-wrap': 'wrap'},
            class_name="btn-group",
            input_class_name="btn-check",
            label_class_name="btn btn-outline-primary",
            label_checked_class_name="active",
            input_style={'display':'none'},
            input_checked_style={'display':'none'},
            label_checked_style={'borderColor': '#333138', 'backgroundColor': '#333138', 'color':'#fffffa'},
            label_style={'borderColor': '#333138', 'backgroundColor': '#fffffa', 'color': '#333138'}
        ),
    ])
])

@callback(
    Output('slider', 'max'),
    Input('radioitem', 'value')
)
def update_slider_max(selected_max):
    return selected_max

if __name__ == "__main__":
    app.run(debug=False, dev_tools_silence_routes_logging = False)
nickmelnikov82 commented 1 year ago

To solve your problem, I suggest using the following code:

import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
from dash import html, dcc, Dash, callback

app = Dash('Slider marks bug reproducible example')

app.layout = html.Div([
    dbc.Row([
        dcc.Slider(1, 10, 1,
                   value=1,
                   id='slider',
                   marks=None,
                   tooltip={"placement": "top", "always_visible": True}
                   ),
    ]),
    dbc.Row([
        dbc.RadioItems(id='radioitem',
                       options=[{'label': '30', 'value': 30}, {'label': '60', 'value': 60}],
                       value='30',
                       inline=True,
                       style={'marginTop': '5px', 'display': 'flex', 'justifyContent': 'space-around',
                              'flex-wrap': 'wrap'},
                       class_name="btn-group",
                       input_class_name="btn-check",
                       label_class_name="btn btn-outline-primary",
                       label_checked_class_name="active",
                       input_style={'display': 'none'},
                       input_checked_style={'display': 'none'},
                       label_checked_style={'borderColor': '#333138', 'backgroundColor': '#333138', 'color': '#fffffa'},
                       label_style={'borderColor': '#333138', 'backgroundColor': '#fffffa', 'color': '#333138'}
                       ),
    ])
])

@app.callback(
    Output('slider', 'max'),
    Output('slider', 'value'),
    Input('radioitem', 'value')
)
def update_slider(selected_max):
    return selected_max, selected_max

if __name__ == "__main__":
    app.run(debug=False, dev_tools_silence_routes_logging=False)

Although this is not a perfect solution to your problem, you can consider it as a temporary option.