[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connecting Backend Paging with a Graph #571

Open
1 task done
BalaNagendraReddy opened this issue Jul 8, 2024 · 2 comments
Open
1 task done

Connecting Backend Paging with a Graph #571

BalaNagendraReddy opened this issue Jul 8, 2024 · 2 comments
Assignees
Labels
General Question ❓ Issue contains a general question

Comments

@BalaNagendraReddy
Copy link
BalaNagendraReddy commented Jul 8, 2024

Question

Hey team,

I have a question regarding the use of Connecting Backend Paging with a Graph.

Based on the filtering of the table graph needs to be change, How we can achieve the same by using vizro.

Thank you so much for the amazing work on this tool, and for the help in advance!

from dash import Dash, dash_table, dcc, html, Input, Output, callback
import pandas as pd

app = Dash(__name__)

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

PAGE_SIZE = 5

app.layout = html.Div(
    className="row",
    children=[
        html.Div(
            dash_table.DataTable(
                id='table-paging-with-graph',
                columns=[
                    {"name": i, "id": i} for i in sorted(df.columns)
                ],
                page_current=0,
                page_size=20,
                page_action='custom',

                filter_action='custom',
                filter_query='',

                sort_action='custom',
                sort_mode='multi',
                sort_by=[]
            ),
            style={'height': 750, 'overflowY': 'scroll'},
            className='six columns'
        ),
        html.Div(
            id='table-paging-with-graph-container',
            className="five columns"
        )
    ]
)

operators = [['ge ', '>='],
             ['le ', '<='],
             ['lt ', '<'],
             ['gt ', '>'],
             ['ne ', '!='],
             ['eq ', '='],
             ['contains '],
             ['datestartswith ']]


def split_filter_part(filter_part):
    for operator_type in operators:
        for operator in operator_type:
            if operator in filter_part:
                name_part, value_part = filter_part.split(operator, 1)
                name = name_part[name_part.find('{') + 1: name_part.rfind('}')]

                value_part = value_part.strip()
                v0 = value_part[0]
                if (v0 == value_part[-1] and v0 in ("'", '"', '`')):
                    value = value_part[1: -1].replace('\\' + v0, v0)
                else:
                    try:
                        value = float(value_part)
                    except ValueError:
                        value = value_part

                # word operators need spaces after them in the filter string,
                # but we don't want these later
                return name, operator_type[0].strip(), value

    return [None] * 3


@callback(
    Output('table-paging-with-graph', "data"),
    Input('table-paging-with-graph', "page_current"),
    Input('table-paging-with-graph', "page_size"),
    Input('table-paging-with-graph', "sort_by"),
    Input('table-paging-with-graph', "filter_query"))
def update_table(page_current, page_size, sort_by, filter):
    filtering_expressions = filter.split(' && ')
    dff = df
    for filter_part in filtering_expressions:
        col_name, operator, filter_value = split_filter_part(filter_part)

        if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
            # these operators match pandas series operator method names
            dff = dff.loc[getattr(dff[col_name], operator)(filter_value)]
        elif operator == 'contains':
            dff = dff.loc[dff[col_name].str.contains(filter_value)]
        elif operator == 'datestartswith':
            # this is a simplification of the front-end filtering logic,
            # only works with complete fields in standard format
            dff = dff.loc[dff[col_name].str.startswith(filter_value)]

    if len(sort_by):
        dff = dff.sort_values(
            [col['column_id'] for col in sort_by],
            ascending=[
                col['direction'] == 'asc'
                for col in sort_by
            ],
            inplace=False
        )

    return dff.iloc[
        page_current*page_size: (page_current + 1)*page_size
    ].to_dict('records')


@callback(
    Output('table-paging-with-graph-container', "children"),
    Input('table-paging-with-graph', "data"))
def update_graph(rows):
    dff = pd.DataFrame(rows)
    return html.Div(
        [
            dcc.Graph(
                id=column,
                figure={
                    "data": [
                        {
                            "x": dff["country"],
                            "y": dff[column] if column in dff else [],
                            "type": "bar",
                            "marker": {"color": "#0074D9"},
                        }
                    ],
                    "layout": {
                        "xaxis": {"automargin": True},
                        "yaxis": {"automargin": True},
                        "height": 250,
                        "margin": {"t": 10, "l": 10, "r": 10},
                    },
                },
            )
            for column in ["pop", "lifeExp", "gdpPercap"]
        ]
    )


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

https://dash.plotly.com/datatable/callbacks

Code/Examples

No response

Other information

No response

Which package?

None

Package version

No response

Python version

No response

OS

No response

Code of Conduct

@BalaNagendraReddy BalaNagendraReddy added General Question ❓ Issue contains a general question Needs triage 🔍 Issue needs triaging labels Jul 8, 2024
@Joseph-Perkins
Copy link
Contributor

hi @BalaNagendraReddy 👋 thanks for the question! we will double check and reply with guidance on how this might be achieved in Vizro 👍

in the meantime we wanted to check whether you're also aiming to retain the ability to sort and filter the data in the table, using the inbuilt controls at the top of the table?

@BalaNagendraReddy
Copy link
Author

Hi @Joseph-Perkins ,

Thanks for your reply.

Mainly, focusing on filter rather than sorting, based on the filter, graph needs to be change. That is my expectation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
General Question ❓ Issue contains a general question
Projects
None yet
Development

No branches or pull requests

3 participants