Drill down function for graphs embedded in Dash app


#1

I am working on making a dashboard for an hr dataset and am trying to have one the bar charts be able to drill down on the column that the user clicks on. Is there any way to do this in Dash?
Here is what my current graph looks like.
48%20AM
I am thinking that I might have to embed a link through a click element on each column of the bar chart in order to make it “drill down” into each columns element but I am not sure whether there is an easier way to do this or not.

Here is my current code that I used to make the graph inside my dashboard: @app.callback(Output(‘tot_hours’,‘figure’),
[Input(‘month_slider’,‘value’)])
def tot_hors(month_slider):
data=[
go.Bar(
y=df.loc[df[‘ed_code’].isin([‘E02’,‘E04’,‘E03’,‘E01’,‘E05’]),‘hours’].groupby(df[‘month’]).sum(),
x=df[‘month2’].unique(),
name=‘Worked’,
text=df.loc[df[‘ed_code’].isin([‘E02’,‘E04’,‘E03’,‘E01’,‘E05’]),‘hours’].groupby(df[‘month’]).sum(),
marker=dict(color=’#42A5B3’),
showlegend=True
),
go.Bar(
y=df.loc[df[‘ed_code’].isin([‘E20’,‘E12’,‘E11’,‘E14’,‘E13’]),‘hours’].groupby(df[‘month’]).sum(),
x=df[‘month2’].unique(),
name=‘Sick’,
text=df.loc[df[‘ed_code’].isin([‘E20’,‘E12’,‘E11’,‘E14’,‘E13’]),‘hours’].groupby(df[‘month’]).sum(),
marker=dict(color=’#D15A86’),
showlegend=True
)

]
layout= go.Layout(
    title='Total Hours',
    legend=dict(x=-.1,y=1.1),
    hovermode='closest',
    barmode='stack'
)
figure = {'data':data,'layout':layout}
return figure

Thanks in advance!


#2

Yeah, I think that’s the easiest way to do this right now. I’ve seen a few examples that have succkessfully done this. Output('my-graph', 'figure'), [Input('my-graph', 'clickData')]. The trick is how you drill back out: One way I’ve seen someone do this is by embedding a second scatter trace with an annotation in the corner of the graph with text that says “Back”. Clicking on that item will refresh the figure to the original graph. Since it’s on the same figure, it will fire the same update on clickData


#3

Ok! Awesome! Thanks for your help!


#5

If I understood correctly that’s a good idea only for 1 step drill down. What do you recommend for many steps?

I tried to use html.Button with @app.callback as input and output with the same figure as in ‘clickData’, but get an error:

You have already assigned a callback to the output
with ID "****" and property "figure". An output can only have
a single callback function. Try combining your inputs and
callback functions together into one function.

#6

I implemented this kind of Drill Down. Here is an example:

"data": [
                {
                    'x': progress_demo2,
                    'y': cls_lev2_short,
                    'text': [str(i) + "%" for i in progress_demo2],
                    'textposition': 'inside',
                    'marker': {
                        'color': 'rgb(158,202,225)',
                        'line': dict(
                            color='rgb(8,48,107)',
                            width=1.5)
                    },
                    'opacity': 0.6,
                    'orientation': 'h',
                    'hoverinfo': 'y',
                    'type': 'bar',
                    'showlegend': False
                },
                {
                    'x': progress_demo,
                    'y': cls_heads_short,
                    'text': [str(i) + "%" for i in progress_demo],
                    'textposition': 'inside',
                    'marker': {
                        'color': 'rgb(158,202,225)',
                        'line': dict(
                            color='rgb(8,48,107)',
                            width=1.5)
                    },
                    'opacity': 0.6,
                    'orientation': 'h',
                    'hoverinfo': 'y',
                    'type': 'bar',
                    'visible': 'legendonly',
                    'name': 'Back',
                },
            ],
            "layout": {
                'height': 650,
                'margin': {
                    't': 50,
                    'l': 390
                },
                'yaxis': {
                    'type': "category",
                    'categoryorder': "category descending"
                },
                'bargap': 0.15,
                'legend': {
                        'x': -1.02,
                        'y': 1.02
                    }
            }

The problem is how to make other trace invisible after “Back” pressed. Can anyone suggest?

Thanks!


#7

I don’t fully understand what you mean but I really like the visual aspect you gave to your project. Would you share your View file with me ?


#8

Visual aspect you can find in post above in figure definition.


#9

Finally I’ve done it through html.Button functionality and using local variables in session environment to save number of previous button clicks and compare it with n_clicks.

Here is multilevel DrillDown with two buttons “Back to top” and “Back to previous level”:


#10

Hey, I’m glad you succeed to find a solution to your problem.

Sorry, my question was not clear, I was not talking about your graph but about the “side Menu” to navigate throw your views (I guess). The 2 “buttons” at the top of your view and the four at the top left.

I’m new to web development, and I don’t know how to build those navigations things. For the moment I’m dealing with with those ugly links to navigate through my web-app :stuck_out_tongue:

dash%20app%20navigation


#11

Oh, I’m new to web dev too.
For navigation I use Tabs in Dash Core Components


#12

Thanks man, I thought I knew the documentation by heart but obviously I missed this…

Here is a track from my favourite album of 2018 to correct my mistake :wink: