This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component - #74

Closed
chriddyp wants to merge 86 commits into
uploadfrom
tabs
Closed

Dash Tabs component#74
chriddyp wants to merge 86 commits into
uploadfrom
tabs

Conversation

@chriddyp

Copy link
Copy Markdown
Member

No description provided.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

tabs

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Fixes plotly/dash#36

@chriddyp

Copy link
Copy Markdown
MemberAuthor

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Trueapp.layout=html.Div([
dcc.Tabs(
tabs=[
{'label': 'Tab {}'.format(i), 'value': i} foriinrange(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')])defdisplay_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]
}
]
returnhtml.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)

@chriddypchriddyp changed the title first pass at a Tabs componentDash Tabs componentSep 14, 2017
@chriddyp

Copy link
Copy Markdown
MemberAuthor

Vertical view
tabs-vertical

@TheoLvs

Copy link
Copy Markdown

Awesome ! Thank you very much

@richard-muir

Copy link
Copy Markdown

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.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
importdashfromdash.dependenciesimportInput, Outputimportdash_core_componentsasdccimportdash_html_componentsashtmlfromloremipsumimportget_sentencesapp=dash.Dash()
app.scripts.config.serve_locally=Truevertical=Trueifnotvertical:
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')])defdisplay_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]
}
]
returnhtml.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)

@dotsdl

Copy link
Copy Markdown

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

@mtreu

mtreu commented Nov 13, 2017

Copy link
Copy Markdown

This looks awesome! However, is there a way to change the color of a tab?

@jbrav

jbrav commented Nov 15, 2017

Copy link
Copy Markdown

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.

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, 4)
],
value=4,
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': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
'name': 'Schroders',
'marker': {
'color': 'rgb(54, 82, 110)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
'name': 'MSF ',
'marker': {
'color': 'rgb(26, 118, 255)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
{
'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
'name': 'OMS',
'marker': {
'color': 'rgb(55, 83, 109)'
},
'type': ['bar', 'scatter'][int(value) % 2]
},
],
def muestra_contenido(value):
data1 = [
{
'x': [1940, 1950, 1960, 1970],
'y': [1, 2, 3, 4],
'name': 'test1',
'marker': {
'color': 'rgb(60, 41, 200)'
},
'type': ['bar', 'scatter'][int(value)%2]
},
{
'x': [1940, 1950, 1960, 1970],
'y': [5, 6, 7, 8],
'name': 'test2',
'marker': {
'color': 'rgb(61, 42, 201)'
},
'type': ['bar', 'scatter'][int(value)%2]
}
],
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('Estoy haciendo una prueba para ver como funcionaria esto')
)],
return html.Div([
dcc.Graph(
id='graph1',
figure={
'data': data1,
'layout': {
'margin': {
'l': 30,
'r': 0,
'b': 30,
't': 0
},
'legend': {'x': 0, 'y': 1}
}
}
),
html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
])
if __name__ == '__main__':
app.run_server(debug=True)

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 .

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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!

@chriddyp

Copy link
Copy Markdown
MemberAuthor

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1

@charleyferrari

Copy link
Copy Markdown

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
dcc.Tabs(tabs = [
{'label': 'Tab 1', 'value': 1},
{'label': 'Tab 2', 'value': 2}
], id='tabs', value = 1),
html.Div([], id='tab_output'),
html.Div([], id='output')
])
@app.callback(
Output('tab_output', 'children'),
[Input('tabs', 'value')]
)
def show_dropdowns(value):
if value == 1:
return dcc.Dropdown(options = [
{'label': 'A', 'value': 'A'},
{'label': 'B', 'value': 'B'}
], id='dropdown1', value = 'A')
if value == 2:
return dcc.Dropdown(options = [
{'label': 'C', 'value': 'C'},
{'label': 'D', 'value': 'D'}
], id='dropdown2', value = 'C')
@app.callback(
Output('output', 'children'),
[Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
app.run_server(debug=True)

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 dccs to exist at the same time.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

@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')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==1else'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])defupdate_dropdown(value):
return {'display': 'block'ifvalue==2else'none'}

@Forander

Copy link
Copy Markdown

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

@chriddyp

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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 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

@Forander

Copy link
Copy Markdown

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?

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@steremma

Copy link
Copy Markdown

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!

@QCTW

QCTW commented Apr 19, 2018

Copy link
Copy Markdown

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?

@ghost

Copy link
Copy Markdown

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

@jen0liu

jen0liu commented May 2, 2018

Copy link
Copy Markdown

@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.

@thomasmarshbintel

Copy link
Copy Markdown

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.

@slash31

Copy link
Copy Markdown

+1 on having this re-integrated into the train. Thanks for all of your hard work!

@randiaz95

Copy link
Copy Markdown

Major firepower with this tab pre release, the programming gods are happy :).

@kyleabeauchamp

Copy link
Copy Markdown

I too am interested in seeing this PR updated for the latest release.

@chriddyp

Copy link
Copy Markdown
MemberAuthor

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.

@jogendraKhalsa

Copy link
Copy Markdown

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 .
Thanks in Advance.

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

20 participants

@chriddyp@TheoLvs@richard-muir@dotsdl@mtreu@jbrav@salvatoregiannuzzi@radumas@Akronix@pthakur4@alastairbegley@ploncker@ColasDroin@yellowbean@charleyferrari@Forander@steremma@QCTW@jen0liu@thomasmarshbintel