Rajat
Rajat

Reputation: 121

Insert shape in Dash DataTable

I have the below datatable in dash.Datatable Code for generating this table is below:

import dash
import dash_table
import pandas as pd

data = {'value':['very low','low','medium','high','very high'],'data':[1,3,5,7,10]}
df = pd.DataFrame(data)


app = dash.Dash(__name__)

app.layout = dash_table.DataTable(
    id='table',
    columns=[{"name": i, "id": i} for i in df.columns],
    data=df.to_dict('records'),
)

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

But I want to generate the below table. How can i do this using dash? The indicator column is a shape that is color coded based on a scale (For eg. 5 is medium and hence yellow/amber, above 5 the value go from green to dark green. Similarly, values below 5 go from amber to red

Datatable with Indicator

Upvotes: 3

Views: 1366

Answers (1)

bas
bas

Reputation: 15462

Thanks to Eduardo on the plotly community forum I learned that we can now use html content for Markdown cells of a DataTable (plotly forum thread, github pull request).

This allows us to do something like this:

import dash
import dash_html_components as html
import dash_table
import pandas as pd


def get_svg_arrow(val):
    if val > 7:
        fill = "green"
    elif val > 5:
        fill = "blue"
    elif val == 5:
        fill = "yellow"
    elif val >= 3:
        fill = "orange"
    else:
        fill = "red"

    if val >= 5:
        path = f'<path d="M19.5 11L26 11L13 -1.1365e-06L7.97623e-09 11L6.5 11L6.5 22L19.5 22L19.5 11Z" fill="{fill}"/>'
    else:
        path = (
            f'<path d="M6.5 11H0L13 22L26 11L19.5 11V0L6.5 0L6.5 11Z" fill="{fill}"/>'
        )

    return f'<svg width="26" height="22" viewBox="0 0 26 22" fill="none" xmlns="http://www.w3.org/2000/svg">{path}</svg>'


values = [1, 3, 5, 7, 10]
data = {
    "value": ["very low", "low", "medium", "high", "very high"],
    "indicator": [get_svg_arrow(val) for val in values],
    "data": values,
}

df = pd.DataFrame(data)

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        dash_table.DataTable(
            css=[dict(selector="p", rule="margin: 0px; text-align: center")],
            data=df.to_dict("records"),
            style_cell={"textAlign": "center"},
            columns=[
                {"name": col, "id": col, "presentation": "markdown"}
                if col == "indicator"
                else {"name": col, "id": col}
                for col in df.columns
            ],
            markdown_options={"html": True},
        )
    ]
)

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

So the idea of the code above is to dynamically create an arrow svg with a fill color based on the data.

For creating the svg arrows I've used a vector drawing program and exported to svg, but you could construct the path manually if you wanted to.

Result

showcase

Upvotes: 3

Related Questions