-
-
Notifications
You must be signed in to change notification settings - Fork 143
Dash Tabs component #74
Conversation
Fixes plotly/dash#36 |
Try it out on the pre-release channel with
That example above: import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from loremipsum import get_sentences
app = dash.Dash()
app.scripts.config.serve_locally = True
app.layout = html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} for i in range(1, 5)
],
value=3,
id='tabs'
),
html.Div(id='tab-output')
], style={
'width': '80%',
'fontFamily': 'Sans-Serif',
'margin-left': 'auto',
'margin-right': 'auto'
})
@app.callback(Output('tab-output', 'children'), [Input('tabs', 'value')])
def display_content(value):
data = [
{
'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
'y': [219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
350, 430, 474, 526, 488, 537, 500, 439],
'name': 'Rest of world',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter', 'box'][int(value) % 3]
},
{
'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
'y': [16, 13, 10, 11, 28, 37, 43, 55, 56, 88, 105, 156, 270,
299, 340, 403, 549, 499],
'name': 'China',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter', 'box'][int(value) % 3]
}
]
return html.Div([
dcc.Graph(
id='graph',
figure={
'data': data,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div(' '.join(get_sentences(10)))
])
if __name__ == '__main__':
app.run_server(debug=True) |
Awesome ! Thank you very much |
Hey Chris, looking great! Tabs & Upload have taken Dash to the next level! How did you get the tabs on the left-hand side? Had a look through the source, but struggling to figure it out. |
@richard-muir Sorry about that! I forgot to publish my latest commits.
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from loremipsum import get_sentences
app = dash.Dash()
app.scripts.config.serve_locally = True
vertical = True
if not vertical:
app.layout = html.Div([
dcc.Tabs(
tabs=[
{'label': 'Market Value', 'value': 1},
{'label': 'Usage Over Time', 'value': 2},
{'label': 'Predictions', 'value': 3},
{'label': 'Target Pricing', 'value': 4},
],
value=3,
id='tabs',
vertical=vertical
),
html.Div(id='tab-output')
], style={
'width': '80%',
'fontFamily': 'Sans-Serif',
'margin-left': 'auto',
'margin-right': 'auto'
})
else:
app.layout = html.Div([
html.Div(
dcc.Tabs(
tabs=[
{'label': 'Market Value', 'value': 1},
{'label': 'Usage Over Time', 'value': 2},
{'label': 'Predictions', 'value': 3},
{'label': 'Target Pricing', 'value': 4},
],
value=3,
id='tabs',
vertical=vertical,
style={
'height': '100vh',
'borderRight': 'thin lightgrey solid',
'textAlign': 'left'
}
),
style={'width': '20%', 'float': 'left'}
),
html.Div(
html.Div(id='tab-output'),
style={'width': '80%', 'float': 'right'}
)
], style={
'fontFamily': 'Sans-Serif',
'margin-left': 'auto',
'margin-right': 'auto',
})
@app.callback(Output('tab-output', 'children'), [Input('tabs', 'value')])
def display_content(value):
data = [
{
'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
'y': [219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
350, 430, 474, 526, 488, 537, 500, 439],
'name': 'Rest of world',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter', 'box'][int(value) % 3]
},
{
'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
'y': [16, 13, 10, 11, 28, 37, 43, 55, 56, 88, 105, 156, 270,
299, 340, 403, 549, 499],
'name': 'China',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter', 'box'][int(value) % 3]
}
]
return html.Div([
dcc.Graph(
id='graph',
figure={
'data': data,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div(' '.join(get_sentences(10)))
])
if __name__ == '__main__':
app.run_server(debug=True) |
Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort. |
I have pushed |
* upload component 🎉 * integration test * update circle python requirements * lint * ✨ sort imports
I have rebased this branch off of the latest version. Try this out with |
"number" to number
This looks awesome! However, is there a way to change the color of a tab? |
Hey, @chriddyp thank you very much. I am trying to actually get different data on each tab. I am quite new in Python, but so far I have tried the following.
I would love if you could point where my error is. I have also tried to create another label, without success as it is apparent . |
@jbrav - Would you mind asking this implementation question in the dash community forum? https://community.plot.ly/c/dash. That'll keep things a little bit more organized for me and you're likely to get more people to help you out there. Thanks! |
- Add newlines at end of file. - Add a .editorconfig for newlines at end of file.
I've made a new prerelease off of master. Get the latest with:
And check your version with:
|
@chriddyp Do you think there's a way for Here's a toy example of what I'm thinking:
Ideally I'd like a user to be able to make selections in each tab, and have the main output draw from both tabs. Something like this doesn't work now because the tabs change the layout, and it's impossible for both |
@charleyferrari - All of the inputs of a callback need to be visible in the layout at the same time in order for them to fire the callback. You could keep them layout by just toggling the visibility, like: app.layout = html.Div([
dcc.Tabs(...),
dcc.Dropdown(id='dropdown1', style={'display': 'none'}, ...)
dcc.Dropdown(id='dropdown2', style={'display': 'none'}, ...)
])
@app.callback(Output('dropdown1', 'style'), [Input('tabs', 'value')])
def update_dropdown(value):
return {'display': 'block' if value == 1 else 'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])
def update_dropdown(value):
return {'display': 'block' if value == 2 else 'none'} |
Is there was a way to use Tabs offline? I would like to create an HTML dashboard with plots arranged in tabs which I can email to people who don't have Python installed (due to security requirements I also cannot use Dash server). This can be done using Bokeh but I would prefer using Plotly as it's much more user friendly. Any help would really be appreciated. Thanks |
This is a separate issue than what is presented in this PR. In any case, this isn't possible now with Dash but it will be in the future. There is a WIP PR here: plotly/dash-renderer#7 |
Thanks for the quick response Chris. What would you suggest if I'm looking to create something like this? Is it possible to arrange something myself by saving Plotly plots as divs? |
Can you ask this in the community forum? https://community.plot.ly/c/dash. The discussion in this thread should be related to this PR. |
This is an extremely useful PR, congrats @chriddyp ! Can we maybe have a (rough) estimation of when this could be merged? I am interested in using it for a client facing application so I would feel a lot better using master! |
Thanks for the great work. @chriddyp I encountered one problem when I tried to place an upload component (https://dash.plot.ly/dash-core-components/upload) inside a tab, it can not properly display the upload block. If I don't put the upload component (the same codes) in the tab, the upload block can properly display... Is this normal? |
Hi Chris, |
@chriddyp for Tabs, it's not included in the latest release (0.22). I had to revert back to an older version 0.21.rc01 which means I can't use some other new cool features people added to dash-core-component. Can you please see if you can merge to the latest branch? Thanks. |
If it can be merged that would be great since scattermapbox doesn't work with this branch and I love the tabs way too much. |
+1 on having this re-integrated into the train. Thanks for all of your hard work! |
Major firepower with this tab pre release, the programming gods are happy :). |
I too am interested in seeing this PR updated for the latest release. |
Thank you everyone so much for the reviews and feedback ❤️ We have incorporated this feedback into a new revision of the Tabs component here: #213. |
Hi Chris, ... can you help with a situation wherein i have to update real time using dcc.Interval as component-Interval is not part of 0.21.0rcxx . |
No description provided.