Обратный вызов сопоставления шаблона для построения тире – Python

У меня есть раскрывающийся список, который позволяет мне фильтровать категориальный график. Отдельный обратный вызов позволяет пользователю изменить этот график из гистограммы в круговую диаграмму. Эта часть работает так, как ожидалось.

У меня есть отдельные компоненты ползунка, которые регулируют настройки как для гистограммы, так и для круговой диаграммы. Проблема в том, что ползунки зафиксированы на месте. Можно ли добавлять/удалять соответствующие ползунки на основе выбора, выбранного в радиопунктах?

Если выбрана гистограмма (см. ниже), должны быть видны только два ползунка. Остальные два следует отбросить или удалить. И наоборот, если выбран пирог, должно произойти обратное. Ползунки полос удаляются вместо ползунков круговой диаграммы.

Макет фильтрующего элемента должен остаться прежним.

import dash
from dash import dcc
from dash import html
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd

df = pd.DataFrame({
   'Fruit': ['Apple','Banana','Orange','Kiwi','Lemon'],
   'Value': [1,2,4,8,6],
   })

external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]

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

filter_box = html.Div(children=[

    html.Div(children=[

        html.Label('Fruit', style = {}),
        dcc.Dropdown(
            id = 'value_type',
            options = [
                {'label': x, 'value': x} for x in df['Fruit'].unique()
            ],
            value = df['Fruit'].unique(),
            multi = True,
            clearable = True
        ),

        html.Label('Cat Chart', style = {'display': 'inline','paddingTop': '0rem', "justifyContent": "center"}),
        dcc.RadioItems(['Bar','Pie'],'Bar', 
                       id = 'catmap', 
                       ),

       html.Label('Bar Transp', style = {'display': 'inline-block', 'paddingTop': '0.1rem',}),
        dcc.Slider(0, 1, 0.2,
               value = 0.6,
               id = 'bar_transp'),

        html.Label('Bar Width', style = {'display': 'inline-block'}),
        dcc.Slider(200, 1000, 200,
               value = 600,
               id = 'bar_width'),

        html.Label('Pie Transp', style = {'display': 'inline-block', 'paddingTop': '0.1rem',}),
        dcc.Slider(0, 1, 0.2,
               value = 0.6,
               id = 'pie_transp'),

        html.Label('Pie Hole', style = {'display': 'inline-block'}),
        dcc.Slider(0, 1, 0.2,
               value = 0.4,
               id = 'pie_hole'),

    ], className = "vstack",            
    )
])

app.layout = dbc.Container([
    dbc.Row([
        dbc.Col([
            dbc.Row([
                dbc.Col(html.Div(filter_box), 
                        ),
            ]),
        ]),
        dbc.Col([
            dbc.Row([
                dcc.Graph(id = 'type-chart'),
            ]),
        ])
    ])
], fluid = True)

@app.callback(
    Output('type-chart', 'figure'),
    [Input('value_type', 'value'), 
     Input('catmap', 'value'), 
     Input('bar_transp', 'value'), 
     Input('bar_width', 'value'), 
     Input('pie_transp', 'value'), 
     Input('pie_hole', 'value'), 
    ])     

def chart(value_type, catmap, bar_transp, bar_width, pie_transp, pie_hole):

    dff = df[df['Fruit'].isin(value_type)]

    if catmap == 'Bar':

        df_count = dff.groupby(['Fruit'])['Value'].count().reset_index(name = 'counts')

        if df_count.empty == True:
            type_fig = go.Figure()

        else:
            df_count = df_count

            type_fig = px.bar(x = df_count['Fruit'], 
                      y = df_count['counts'],
                      color = df_count['Fruit'],
                      opacity = bar_transp,
                      width = bar_width
                      )

    elif catmap == 'Pie':

        df_count = dff.groupby(['Fruit'])['Value'].count().reset_index(name = 'counts')

        if df_count.empty == True:
            type_fig = go.Figure()

        else:
            df_count = df_count

            type_fig = px.pie(df_count,
                              values = df_count['counts'],
                              opacity = pie_transp,
                              hole = pie_hole
                             )

    return type_fig

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Обратные вызовы, соответствующие шаблону, в этой ситуации не нужны, хотя это могло бы быть, если бы фильтры создавались динамически. Вместо этого, чтобы добавить/удалить соответствующие ползунки на основе выбранного типа графика, вы должны обернуть их в компонент (как children) и использовать обратный вызов для обновления свойства children этого компонента.

Однако я предлагаю вам просто показать/скрыть ползунки, а не добавлять/удалять их, чтобы их состояние сохранялось при обновлении типа графика:

  • Используйте один компонент-оболочку для каждого типа (здесь «filter_bar» и «filter_pie»):

    filter_box = html.Div(children=[
    
        html.Div(children=[
    
            html.Label('Fruit', style = {}),
            dcc.Dropdown(
                id = 'value_type',
                options = [
                    {'label': x, 'value': x} for x in df['Fruit'].unique()
                ],
                value = df['Fruit'].unique(),
                multi = True,
                clearable = True
            ),
    
            html.Label('Cat Chart', style = {'display': 'inline','paddingTop': '0rem', "justifyContent": "center"}),
            dcc.RadioItems(['Bar','Pie'],'Bar',
                        id = 'catmap',
                        ),
    
            html.Div(id='filter_bar', children=[
                html.Label('Bar Transp', style = {'display': 'inline-block', 'paddingTop': '0.1rem',}),
                dcc.Slider(0, 1, 0.2,
                    value = 0.6,
                    id = 'bar_transp'),
    
                html.Label('Bar Width', style = {'display': 'inline-block'}),
                dcc.Slider(200, 1000, 200,
                    value = 600,
                    id = 'bar_width'),
            ]),
    
    
            html.Div(id='filter_pie', children=[
                html.Label('Pie Transp', style = {'display': 'inline-block', 'paddingTop': '0.1rem',}),
                dcc.Slider(0, 1, 0.2,
                    value = 0.6,
                    id = 'pie_transp'),
    
                html.Label('Pie Hole', style = {'display': 'inline-block'}),
                dcc.Slider(0, 1, 0.2,
                    value = 0.4,
                    id = 'pie_hole'),
            ])
    
        ], className = "vstack",
        )
    ])
    
  • И обновите его свойство style в обратном вызове:

     @app.callback(
        Output('filter_bar', 'style'),
        Output('filter_pie', 'style'),
        Input('catmap', 'value')
    )
    def display_sliders(catmap):
        if catmap == 'Bar':
            return {}, {'display': 'none'}
    
        if catmap == 'Pie':
            return {'display': 'none'}, {}
    
        return {'display': 'none'}, {'display': 'none'}
    

Спасибо. Очень полезно. Есть ли у вас ссылки, которые более подробно объясняют разницу между добавлением/удалением и отображением/скрытием?

jonboy 29.04.2024 02:03

Не совсем, но давайте возьмем этот пример, где обратный вызов set_display_children отображает выбранную страну и город, добавляя/удаляя некоторый текст в макете, как дочернее свойство определенного контейнера. В вашем случае этот конкретный контейнер будет, например, html.Div(id='sliders') размещен сразу после компонента «catmap», и в обратном вызове вы обновите его children в соответствии с catmap, вернув соответствующую пару компонентов (метка+ползунки).

EricLavault 29.04.2024 14:43

Однако теперь, когда я переосмыслил это, это предотвратит запуск первого обратного вызова: поскольку ползунки используются в качестве входных данных этого обратного вызова, добавление/удаление этих входных данных из макета потребует повторной регистрации обратного вызова с новыми входными данными после каждого обновить, чтобы его все еще можно было запустить.

EricLavault 29.04.2024 14:48

Да, я просмотрел эти примеры, которые дали мне подход к сопоставлению с образцом, но он не соответствовал точным требованиям. Спасибо за информацию.

jonboy 30.04.2024 05:06

Другие вопросы по теме

Похожие вопросы

Как добавить функцию перетаскивания в HTML-тег ввода файла, который я настроил как изображение?
Как сохранить значения каждого массива в цепочке обещаний, используя javascript forEach?
Почему я нарушаю лимит времени!? Цикл связанных списков LeetCode (решено, но необходимо объяснение!)
Как контейнер может изменить отображение дочернего элемента в слотах по умолчанию?
Что вызывает невозможность навигации между элементами, представленными одним и тем же компонентом в Angular 16?
(объект JavaScript), если следующие значения больше первого значения на 1, добавьте значения в новый объект, если нет, игнорируйте значения
Как обрезать прозрачность изображения, но при необходимости сохранить минимальный размер и положение
Сбой подключения NodeJS к CosmosDB при создании клиента из строки подключения
Внедрить значение параметра AWS SSM в процесс сборки Webpack
Как мне отредактировать обратный отсчет FlipDown.js?