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

the selector option is from another selector #180

Open
1 task done
bvbvtw opened this issue Nov 24, 2023 · 5 comments
Open
1 task done

the selector option is from another selector #180

bvbvtw opened this issue Nov 24, 2023 · 5 comments
Assignees
Labels
Community Issue/PR opened by the open-source community Issue: General Question ❓ Issue contains a general question

Comments

@bvbvtw
Copy link

bvbvtw commented Nov 24, 2023

Question

I'd like to dynamic change the selector options according to the another selector.
for example:
I use titanic_data to set dropdown list:
first dropdown is pclass , it's including 1,2,3
second dropdown is deck it's including A,B,C,D,E,F,G
What I want is when select plass=2 on the first dropdown, the second dropdown only show D,E,F
because there are only deck D,E,F on pclass=2
This function can be done by callback in dash/plotly.
How can I achieve this function inVizro? Please advise, thank you!
image

Code/Examples

No response

Other information

No response

vizro version

No response

Python version

No response

OS

No response

Code of Conduct

@bvbvtw bvbvtw added Issue: General Question ❓ Issue contains a general question Status: Needs triage 🔍 Issue/PR needs triaging labels Nov 24, 2023
@Joseph-Perkins
Copy link
Contributor

Thank you for the clear explanation @bvbvtw ! That makes sense, and it seems that it would be similar to what might often be described as ‘cascading’ or ‘hierarchical’ filtering

This functionality is currently not available in Vizro 0.1.6 yet, however it may soon be possible to achieve through future functionality related to customising callbacks, which is currently in development

When the underlying functionality to apply custom callbacks is released shortly, we will reply here whether it is possible to use that to achieve the same outcome of cascading filters (or else will give an indication about when that functionality might be available as part of the core functionality instead)

@Joseph-Perkins Joseph-Perkins removed the Status: Needs triage 🔍 Issue/PR needs triaging label Nov 24, 2023
@bvbvtw
Copy link
Author

bvbvtw commented Nov 24, 2023

@Joseph-Perkins Thanks your prompt reply,

I've learn that it is possible to create custom components from documentation.
The following code demonstrates how I use Dash/Plotly to achieve cascading filters.
But I am not sure if I can use the callback method as following code to customize the controller in order to achieve cascading filters functionality. Please advice, thank you very much!

#######################################
from dash import Dash, dcc, html, Input, Output, State, dash_table, callback
import dash
app = dash.Dash()

category_lst = [category[0] for category in category_table]
tabs = html.Div(
[html.P(),
dcc.Dropdown(id='in_category',
options = category_lst,
placeholder="Select a category"
),

 dcc.Dropdown(id='in_item', 
              #options = ppid_lst, 
              placeholder="Select a item"
              ), 

])

@app.callback(Output("in_item", component_property='options'),
Input(component_id='in_category', component_property='value'),
prevent_initial_call=True
)
def platform_ppid_selected(the_category):
sql = f"""
SELECT distinct item
FROM table
where item = '{the_category}'
"""
item_lst = [item[0] for item in pd.read_sql(sql, engine)]
return item_lst
#########################

@petar-qb
Copy link
Contributor

Hi @bvbvtw. It's possible to use Vizro in combination with the Dash which makes a requested feature possible.

Here's an example with the plotly.express.data.gapminder() data where the "country filter" options are filtered by "continent filter" selected value:

import dash
import pandas as pd
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_data_table


def create_country_analysis():
    df_gapminder = px.data.gapminder()

    @dash.callback(
        dash.Output("country_selector_id", "options"),
        dash.Output("country_selector_id", "value"),
        dash.Input("continent_selector_id", "value"),
    )
    def custom_cascading_filter(continent_selector_id_value):
        if not continent_selector_id_value:
            return [], None
        continent_df = df_gapminder[df_gapminder['continent'] == continent_selector_id_value]
        countries_list = list(set(continent_df['country'].tolist()))
        countries_list.sort()
        return countries_list, countries_list[0]

    page_country = vm.Page(
        title="Country Analysis",
        components=[
            vm.Table(
                id="table_country",
                title="Table Country",
                figure=dash_data_table(
                    data_frame=px.data.gapminder(),
                ),
            ),
        ],
        controls=[
            vm.Filter(
                id="continent_filter_id",
                column="continent",
                selector=vm.Dropdown(
                    id="continent_selector_id",
                    # value="Europe",
                    multi=False,
                    title="Select continent",
                ),
            ),
            vm.Filter(
                id="country_filter_id",
                column="country",
                selector=vm.Dropdown(
                    id="country_selector_id",
                    multi=True,
                    title="Select country",
                )
            ),
        ],
    )
    return page_country


dashboard = vm.Dashboard(
    pages=[
        create_country_analysis(),
    ],
)

if __name__ == "__main__":
    Vizro(assets_folder="../assets").build(dashboard).run()

I really hope this example can help you achieve the desired behaviour. Tell us if the solution works for you and if we can still help you somehow.

P.S. As @Joseph-Perkins already said, similar behaviour will soon be possible to implement just using the Vizro syntax (without needing to import dash library).

@maxschulz-COL maxschulz-COL added the Community Issue/PR opened by the open-source community label Dec 19, 2023
@Et9797
Copy link

Et9797 commented Jan 3, 2024

Hi @bvbvtw. It's possible to use Vizro in combination with the Dash which makes a requested feature possible.

Here's an example with the plotly.express.data.gapminder() data where the "country filter" options are filtered by "continent filter" selected value:

import dash
import pandas as pd
import vizro.models as vm
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_data_table


def create_country_analysis():
    df_gapminder = px.data.gapminder()

    @dash.callback(
        dash.Output("country_selector_id", "options"),
        dash.Output("country_selector_id", "value"),
        dash.Input("continent_selector_id", "value"),
    )
    def custom_cascading_filter(continent_selector_id_value):
        if not continent_selector_id_value:
            return [], None
        continent_df = df_gapminder[df_gapminder['continent'] == continent_selector_id_value]
        countries_list = list(set(continent_df['country'].tolist()))
        countries_list.sort()
        return countries_list, countries_list[0]

    page_country = vm.Page(
        title="Country Analysis",
        components=[
            vm.Table(
                id="table_country",
                title="Table Country",
                figure=dash_data_table(
                    data_frame=px.data.gapminder(),
                ),
            ),
        ],
        controls=[
            vm.Filter(
                id="continent_filter_id",
                column="continent",
                selector=vm.Dropdown(
                    id="continent_selector_id",
                    # value="Europe",
                    multi=False,
                    title="Select continent",
                ),
            ),
            vm.Filter(
                id="country_filter_id",
                column="country",
                selector=vm.Dropdown(
                    id="country_selector_id",
                    multi=True,
                    title="Select country",
                )
            ),
        ],
    )
    return page_country


dashboard = vm.Dashboard(
    pages=[
        create_country_analysis(),
    ],
)

if __name__ == "__main__":
    Vizro(assets_folder="../assets").build(dashboard).run()

I really hope this example can help you achieve the desired behaviour. Tell us if the solution works for you and if we can still help you somehow.

P.S. As @Joseph-Perkins already said, similar behaviour will soon be possible to implement just using the Vizro syntax (without needing to import dash library).

Is this there a solution to this problem now without importing dash and using newly added Vizro custom actions?

@petar-qb
Copy link
Contributor

petar-qb commented Jan 4, 2024

Hi @Et9797! We don't yet support this feature natively in Vizro, but will let you know when we do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community Issue/PR opened by the open-source community Issue: General Question ❓ Issue contains a general question
Projects
None yet
Development

No branches or pull requests

5 participants