简体   繁体   English

在 Plotly Dash 应用程序中双击图形中的数据点后如何触发模式

[英]How to fire a modal after a double click on data points in a graph in Plotly Dash application

I have included a modal component into my dash application poping up after clicking on a data point inside a graph.我在单击图形中的数据点后弹出的破折号应用程序中包含了一个模态组件。 I would like however to show the modal only after a second click on the data point confirming that the user really wants the modal to appear and not only clicked by accident.但是,我想仅在第二次单击数据点后显示模态,确认用户确实希望模态出现,而不仅仅是意外点击。 For the moment, I use the 'Clickdata' property of the graph component to trigger the callback responsible for the modal.目前,我使用图形组件的“Clickdata”属性来触发负责模态的回调。 Is there some other property that records how many time a data point was clicked for example, that way I could set the condition to number_of_clicks = 2 (or something alike … ).例如,是否有其他一些属性记录了点击数据点的次数,这样我就可以将条件设置为 number_of_clicks = 2(或类似的东西......)。

Thank you all for any helpful insight.感谢大家提供任何有用的见解。

I don't believe there are any properties of a graph component that allow you to store clicks, but you can extract click information through clickData and store that information in dcc.Store .我不相信图形组件有任何属性允许您存储点击,但您可以通过clickData提取点击信息并将该信息存储在dcc.Store中。

Since you didn't provide any specific code in your question, these are some of the assumptions built into my working example:由于您没有在问题中提供任何特定代码,因此这些是我的工作示例中内置的一些假设:

  • that we are using a DataFrame for the data (which allows us to more conveniently store the number of clicks using a dictionary with the data point's index in the dataframe as the key and the number of clicks as the value).我们正在使用 DataFrame 作为数据(这使我们可以更方便地使用字典存储点击次数,其中数据点在 dataframe 中的index作为键,点击次数作为值)。 for example, dcc.Store might contain {'0': 1} meaning that the data point at index 0 has been clicked 1 time.例如, dcc.Store可能包含{'0': 1}表示索引 0 处的数据点已被单击 1 次。
  • that you want the modal component to appear permanently once any point is clicked twice.您希望模态组件在任何点被单击两次后永久显示。
  • that the modal component you are using has the style property, which we will set to {'display': 'none'} so it is not visible when the app first renders, but will become visible once any point is clicked twice (based on this answer ).您正在使用的模态组件具有style属性,我们将其设置为 {'display': 'none'} 因此当应用程序首次呈现时它是不可见的,但是一旦任何点被点击两次就会变得可见(基于这个答案)。 i picked dcc.TextArea but it could be any modal component that you like (this also works for double clicking on an individual point, thanks to @Hamzah's helpful answer )我选择了dcc.TextArea但它可以是您喜欢的任何模态组件(这也适用于双击单个点,感谢@Hamzah 的有用回答

import pandas as pd
import plotly.express as px
import dash
from dash import Input, Output, dcc, html, ctx
from typing import List

app = dash.Dash(__name__)

df = pd.DataFrame({
    'x': list(range(5,10)),
    'y': list(range(5,10))
})

fig = px.scatter(df, x='x', y='y')
fig.update_traces(marker_size=20)

app.layout = html.Div([
    html.Div([
        dcc.Graph(figure=fig, id='graph-interaction'),
        dcc.Store(id='store-clicks')
    ]),
    html.Div([
        # Create element to hide/show, in this case an 'Input Component'
        dcc.Textarea(
            id='modal',
            value='This shows up when you click a point twice',
            style={'width': 100, 'height': 100},
        ),
    ], style= {'display': 'none', 'padding-left': '80px'} # <-- This is the line that will be changed by the dropdown callback
    )
])

@app.callback(
    Output('modal','style'),
    Output('store-clicks','data'),
    Output('graph-interaction', 'clickData'),
    [Input('graph-interaction', 'clickData'),
    Input('store-clicks','data'),
    ])
def show_selection(click_data, stored_clicks):
    # print(f"incoming click data: {click_data}")
    if stored_clicks is None:
        stored_clicks = {}
    else:
        point_index = str(click_data['points'][0]['pointIndex'])
        if point_index in stored_clicks:
            stored_clicks[point_index] += 1
        else:
            stored_clicks[point_index] = 1
    
    ## this means that the model componant will appear permanently 
    ## after any point is clicked twice 
    if 2 in stored_clicks.values():
        return {'display': 'block'}, stored_clicks, None
    else:
        return {'display': 'none'}, stored_clicks, None

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

In the example below, I click on the points (6,6) and (7,7) one time each, and once I click on (8,8) twice, the textbox appears.在下面的示例中,我分别单击点(6,6)(7,7)一次,然后单击(8,8)两次,出现文本框。

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM