📣 Dash v1.21.0 - Plotly.js 2.0, Icicle Charts, Bar Chart Patterns, Clipboard Component, Bug Fixes

Here are a few more examples of new features in this release :confetti_ball:

Disable days in DatePickerRange and DatePickerSingle components .

Thanks to @tcbegley for doing this pull request This was a frequently requested feature on the forum and it’s a nice addition to Dash.

This example makes weekends in April disabled:

image

# Example for making  weekends in April disabled:

from datetime import datetime, timedelta

import dash
import dash_core_components as dcc
import dash_html_components as html

APRIL = [datetime(2021, 4, 1) + timedelta(days=i) for i in range(30)]

app = dash.Dash()

app.layout = html.Div(
    [
        dcc.DatePickerSingle(
            disabled_days=[date for date in APRIL if date.weekday() >= 5],
            min_date_allowed=APRIL[0],
            max_date_allowed=APRIL[-1],
        )
    ],
    style={"padding": "30px"},
)

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



Case insensitive filtering to DataTable

I’ve been looking forward to this functionality, and it works great! There is a new icon in the filter to select whether or not the filter is case sensitive. Here is what it looks like:

case_insensitive

# Case insensitive filter demo

import dash
import dash_html_components as html
import dash_table
import plotly.express as px

df = px.data.gapminder()

app = dash.Dash(__name__)

app.layout = html.Div(
    dash_table.DataTable(
        columns=[{"name": i, "id": i, "deletable": True} for i in df.columns],
        data=df.to_dict("records"),
        filter_action="native",
        filter_options={"case": "insensitive"},
        sort_action="native",
    ),
)

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

Allow html in markdown in the DataTable.

There is now an option to “opt-in” and allow html tags to be used in markdown in the DataTable. Previously this was not allowed due to security issues. See this discussion to learn more: Writing Secure Dash Apps - Community Thread

Here are some examples using html tags in markdown. (See this pull request for the code for these examples)

image

image

Adding images using <img>. This can make it easier to control image size and add other style
image



dcc.Clipboard

Here are a few more examples of the new dcc.Clipboard component, including several options for formatting:
copy_paste

# basic copy to clipboard demo - no callback required!

import dash
import dash_html_components as html
import dash_core_components as dcc

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dcc.Textarea(
            id="textarea_id",
            value="Copy and paste here",
            style={ "height": 100},
        ),
        dcc.Clipboard(
            target_id="textarea_id",
            title="copy",
            style={
                "display": "inline-block",
                "fontSize": 20,
                "verticalAlign": "top",
            },
        ),
    ],
)

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

Style the copy icon as a Bootstrap button:

image

# style the copy icon as a bootstrap button

import dash
import dash_core_components as dcc
import dash_bootstrap_components as dbc

app = dash.Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = dbc.Container(
    [
        dcc.Textarea(
            id="textarea_id",
            value="Copy and paste here",
            style={"height": 100},
        ),
        dbc.Button(
            dcc.Clipboard(target_id="textarea_id"),
            style={"verticalAlign": "top"},
        ),
    ],
)

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

Copy Icon placed inside of a scrolling Div

copy_scrollable_div

html.Div("Copy icon in top right corner of a scrollable div"),
        html.Div(
            [
                dcc.Markdown(
                    code,
                    id="code",
                    style={"width": 800, "height": 200, "overflow": "auto"},
                ),
                dcc.Clipboard(
                    target_id="code",
                    style={
                        "position": "absolute",
                        "top": 0,
                        "right": 20,
                        "fontSize": 20,
                    },
                ),
            ],
            style={
                "width": 800,
                "height": 200,
                "position": "relative",
                "marginBottom": 100,
            },
        ),

Copy to clipboard in a callback.

The previous examples, no callback was required to copy text to the clipboard. This works well for html tables as well. For the Dash DataTable, it’s necessary to use a callback. The data can be copied to the clipboard in different formats using Pandas functions. See the Pandas documentation for more information on the following: .to_text() .to_csv() or .to_excel().

#  example for copying from a DataTable to the clipboard

import dash
import dash_html_components as html
import dash_core_components as dcc
import dash_table
from dash.dependencies import Input, Output, State
import pandas as pd

external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]

app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/solar.csv")

app.layout = html.Div(
    [
        dcc.Clipboard(
            id="DataTable_copy",
            style={"fontSize": 30, "color": "white", "backgroundColor": "grey", "height":38},
            className="button",
        ),
        dcc.RadioItems(
            id="copy_selected",
            options=[
                {"label": "Copy All", "value": "all"},
                {"label": "Copy Selected", "value": "some"},
            ],
            value="all",
            style={"display": "inline-block"},
        ),
        dash_table.DataTable(
            id="DataTable",
            columns=[{"name": i, "id": i} for i in df.columns],
            data=df.to_dict("records"),
            page_size=10,
        ),
    ]
)


@app.callback(
    Output("DataTable_copy", "content"),
    Input("DataTable_copy", "n_clicks"),
    State("DataTable", "start_cell"),
    State("DataTable", "end_cell"),
    State("DataTable", "derived_virtual_data"),
    State("copy_selected", "value")
)
def custom_copy(_, start, end, data, copy_selected):
    dff = pd.DataFrame(data)
    if start and (copy_selected == 'some'):
        copy_cells = dff.loc[
            start["row"]: end["row"], start["column_id"]: end["column_id"]
        ]
        # see more options for .to_text() in pandas documentation
        return copy_cells.to_text(header=False, index=False, )
    else:
        # see more options for .to_csv() or .to_excel() in pandas documentation
        return dff.to_csv(index=False)  # includes headers

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

8 Likes