πŸ“£ Dash v1.8.0 release

Dash 1.8.0 is a minor release improving dcc.Graph responsiveness on page and parent element resize and adds markdown support to the DataTable.

Changelog
Dash v1.8.0

Highlights

Previous Releases

Delving Deeper

Graph Responsiveness
The Plotly.js library allows the container to be resize on window resize but does not react to parent element resize, which can lead to some undesired behavior. To help usability, in addition to using the figure.layout.autosize and config.responsive flags in Plotly, it is now possible to override thedcc.Graph behavior by passing responsive=False|True|'auto'(default).

  • If responsive=True: will be responsive to both window and parent resize and will override any default behavior from config/figure
  • If `responsive=False: will be not be responsive even if it could have been.
  • If responsive='auto' (default): will be responsive on both window and parent resize if it would otherwise have been responsive on page resize, will not be responsive otherwise.

Table Markdowns
The table now has a new presentation='markdown' option on columns that can be used with type='text'. The table will parse the text as markdown and display the result.

import dash
from dash_html_components import Div
from dash_table import DataTable

app = dash.Dash(__name__)

data=[
    dict(a=''' ```javascript
return 20;
    ```
'''), # need to dedent the ``` for actual usage
    dict(a='''An image\n
![Plotly](https://aws1.discourse-cdn.com/business7/uploads/plot/original/2X/7/7957b51729ad7fd9472879cd620b9b068d7105bb.png)'''),
    dict(a='''
_italics_\n
**bold**\n
~~strikethrough~~
'''),
    dict(a='''Nested table
Statement | Is it true?
--- | ---
This page has two tables | yes
This table has two rows | no
This is an example of tableception | yes
'''),
    dict(a='[Dash documentation](https://dash.plot.ly)')
]

app.layout = Div([
    DataTable(
        columns=[
            dict(name='a', id='a', type='text', presentation='markdown'),
        ],
        css=[
            dict(selector='img[alt=Plotly]', rule='height: 50px;')
        ],
        data=data
    ),
])

app.run_server(debug=True)

2 Likes

Hi,

I am trying to get links embedded in the dash datatable. I was informed that this new version (1.8.0) now includes markdowns (links, images etc).
I was hoping for an example script that shows how to have links embedded in a datatable when reading columns from a pandas dataframe.
I then hope to have the table filterable - will the links still be supported with filtering?
I would really appreciate some help with the syntax on this issue.

Thanks
Georgia

1 Like

One question about the responsive attribute, does this also work with transitions on the parent element?

@Gbw-lucite Links are supported through the Markdown syntax. In markdowns, links take the form [display_name](url) with both parts mandatory. If you have no meaningful name to display, just use the url like so: [url](url).

You can optionally add a hover title/description for the link like so: [display_name](url "title").

There are many good resources online for the Markdown syntax, here’s a demo from the 3rd party used by the DataTable to render markdowns: https://jonschlinkert.github.io/remarkable/demo/. That said, many sources of information exist and not all markdown implementations are created equal and some disparities are to be expected if looking at other sources.

For filtering, the table filters on the raw value of the field. The link in the example above (dict(a='[Dash documentation](https://dash.plot.ly)')) will match both Dash and plot.ly.

Sorting is also done on the raw value of the field, not the displayed value. If for a certain column all rows contain similarly formatted links, this will behave the same as if sorting on the display value.

import dash
from dash_html_components import Div
from dash_table import DataTable

from pandas import DataFrame

def f(row):
    return "[{0}]({0})".format(row["url"])

d = {
    'id': [1,2,3,4,5,6],
    'url': [
        'www.google.com',
        'dash.plot.ly',
        'plot.ly',
        'community.plot.ly',
        'altavista.com',
        'yahoo.com'
    ]
}
df = DataFrame(data=d)
df["link"] = df.apply(f, axis=1)
print(df)

app = dash.Dash(__name__)

app.layout = Div([
    DataTable(
        columns=[
            dict(name='id', id='id', type='text'),
            dict(name='link', id='link', type='text', presentation='markdown'),
        ],
        data=df.to_dict('records')
    ),
])

app.run_server(debug=True)

2 Likes

@seferoezcan As the resize operation is expensive, the underlying Plotly.js library debounces the graph resize until no further resize request has been made for a short period of time. As such, a smooth transition will not resize the graph every step of the way but instead will wait for the transition to be completed before triggering the resize.

index.py

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

from dash.dependencies import Input, Output, State, ClientsideFunction
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)
server = app.server

app.layout = html.Div(children=[
    html.Button(['Click to resize'], id='btn'),
    html.Div(id="transition-div",
        children=[
            dcc.Graph(
                responsive=True,
                style=dict(height='100%', width='100%'),
                figure={
                    'data': [{
                        'x': [1, 2, 3, 4],
                        'y': [5, 4, 3, 6],
                        'line': {'shape': 'spline'}
                    }],
                },
            )
        ]
    ),
])

@app.callback(
    Output('transition-div', 'className'),
    [Input('btn', 'n_clicks')]
)
def resize(n_clicks):
    if n_clicks is None:
        raise PreventUpdate

    return 'div-resize'


if __name__ == '__main__':
    app.run_server(debug=True)

/assets/custom.css

#transition-div {
    height: 600px;
    padding: 10px;
    background-color: red;
}

#transition-div.div-resize {
    height: 1000px !important;
    transition: height 2s;
}

Hey,

yeah thats what my tests showed as well. Furthermore is there any update on the dcc.Loading compoent which seems to be broken since 1.7.0 and has seen multiple bug reports.

Hi,

Thank you for your reply. I’ve managed to get it working.
I’m quite new to dash and html and I was wondering if you could show me how to get a different name displayed instead of the url by reading from a different column of the same dataframe?
i,e, how would you edit the f(row) function to display more easily readable names for example:
google, dash, plotly, community, altavista, yahoo?

Hi,

I have managed to do it.

import dash

from dash_html_components import Div

from dash_table import DataTable

from pandas import DataFrame

def f(row): #Turns the dictionary d into the correct format for

return"[%s]({0})".format(row["url"]) %row["id"] #Where the "id" is the names of the links that will be seen

d = {

'id': ['Sky Tv', 'BBC', 'Amazon Video', 'Channel 4', 'ITV', 'Netflix'],

'url': [

    'https://tvplayer.com/',

    'https://www.bbc.co.uk/iplayer',

    'https://www.amazon.co.uk/Prime-Video/b?ie=UTF8&node=3280626031',

    'https://www.channel4.com/',

    'https://www.itv.com/hub/itv',

    'https://www.netflix.com/'

]

}

df = DataFrame(data=d)

df[β€œlink”] = df.apply(f, axis=1)

app = dash.Dash(name)

app.layout = Div([

DataTable(

    columns=[

        dict(name='id', id='id', type='text'),

        dict(name='link', id='link', type='text', presentation='markdown'),

    ],

    data=df.to_dict('records')

),

])

app.run_server(debug=True)

is it possible to display an image (icon) using presentation=markdown and when image is clicked trigger a callback?