我最近问了一个关于如何使用clientside_callback
的问题(请参阅this),并且正在我自己的 Jmeter 板应用程序上进行实践。在我的 Jmeter 板中,我有一个Map,一个下拉菜单和一个按钮。用户通过点击在Map上选择州,并且还可以从下拉菜单中选择它们。但是,下拉菜单中也有ALL选项。至于按钮,它清除用户的选择。
我的应用程序可以使用常规的Dash回调,但我的目标是使用clientside_callback
来加速这个过程。然而,我收到了多个错误与我的代码,由于Java脚本部分,我没有经验。
所以我希望有人能帮我。
import random, json
import dash
from dash import dcc, html, Dash, callback, Output, Input, State
import dash_leaflet as dl
import geopandas as gpd
from dash import dash_table
#https://gist.github.com/incubated-geek-cc/5da3adbb2a1602abd8cf18d91016d451?short_path=2de7e44
us_states_gdf = gpd.read_file("us_states.geojson")
us_states_geojson = json.loads(us_states_gdf.to_json())
options = [{'label': 'Select all', 'value': 'ALL'}, {'label': 'AK', 'value': 'AK'}, {'label': 'AL', 'value': 'AL'},
{'label': 'AR', 'value': 'AR'}, {'label': 'AZ', 'value': 'AZ'}, {'label': 'CA', 'value': 'CA'},
{'label': 'CO', 'value': 'CO'}, {'label': 'CT', 'value': 'CT'}, {'label': 'DE', 'value': 'DE'},
{'label': 'FL', 'value': 'FL'}, {'label': 'GA', 'value': 'GA'}, {'label': 'HI', 'value': 'HI'},
{'label': 'IA', 'value': 'IA'}, {'label': 'ID', 'value': 'ID'}, {'label': 'IL', 'value': 'IL'},
{'label': 'IN', 'value': 'IN'}, {'label': 'KS', 'value': 'KS'}, {'label': 'KY', 'value': 'KY'},
{'label': 'LA', 'value': 'LA'}, {'label': 'MA', 'value': 'MA'}, {'label': 'MD', 'value': 'MD'},
{'label': 'ME', 'value': 'ME'}, {'label': 'MI', 'value': 'MI'}, {'label': 'MN', 'value': 'MN'},
{'label': 'MO', 'value': 'MO'}, {'label': 'MS', 'value': 'MS'}, {'label': 'MT', 'value': 'MT'},
{'label': 'NC', 'value': 'NC'}, {'label': 'ND', 'value': 'ND'}, {'label': 'NE', 'value': 'NE'},
{'label': 'NH', 'value': 'NH'}, {'label': 'NJ', 'value': 'NJ'}, {'label': 'NM', 'value': 'NM'},
{'label': 'NV', 'value': 'NV'}, {'label': 'NY', 'value': 'NY'}, {'label': 'OH', 'value': 'OH'},
{'label': 'OK', 'value': 'OK'}, {'label': 'OR', 'value': 'OR'}, {'label': 'PA', 'value': 'PA'},
{'label': 'RI', 'value': 'RI'}, {'label': 'SC', 'value': 'SC'}, {'label': 'SD', 'value': 'SD'},
{'label': 'TN', 'value': 'TN'}, {'label': 'TX', 'value': 'TX'}, {'label': 'UT', 'value': 'UT'},
{'label': 'VA', 'value': 'VA'}, {'label': 'VT', 'value': 'VT'}, {'label': 'WA', 'value': 'WA'},
{'label': 'WI', 'value': 'WI'}, {'label': 'WV', 'value': 'WV'}, {'label': 'WY', 'value': 'WY'}]
state_abbreviations = {'Alabama': 'AL', 'Alaska': 'AK', 'Arizona': 'AZ', 'Arkansas': 'AR', 'California': 'CA', 'Colorado': 'CO',
'Connecticut': 'CT', 'Delaware': 'DE', 'Florida': 'FL', 'Georgia': 'GA', 'Hawaii': 'HI', 'Idaho': 'ID',
'Illinois': 'IL', 'Indiana': 'IN', 'Iowa': 'IA', 'Kansas': 'KS', 'Kentucky': 'KY', 'Louisiana': 'LA',
'Maine': 'ME', 'Maryland': 'MD', 'Massachusetts': 'MA', 'Michigan': 'MI', 'Minnesota': 'MN',
'Mississippi': 'MS', 'Missouri': 'MO', 'Montana': 'MT', 'Nebraska': 'NE', 'Nevada': 'NV',
'New Hampshire': 'NH', 'New Jersey': 'NJ', 'New Mexico': 'NM', 'New York': 'NY', 'North Carolina': 'NC',
'North Dakota': 'ND', 'Ohio': 'OH', 'Oklahoma': 'OK', 'Oregon': 'OR', 'Pennsylvania': 'PA',
'Rhode Island': 'RI', 'South Carolina': 'SC', 'South Dakota': 'SD', 'Tennessee': 'TN', 'Texas': 'TX',
'Utah': 'UT', 'Vermont': 'VT', 'Virginia': 'VA', 'Washington': 'WA', 'West Virginia': 'WV', 'Wisconsin':
'WI', 'Wyoming': 'WY'}
states = list(state_abbreviations.values())
app = Dash(__name__)
app.layout = html.Div([
#Store lists to use in the callback
dcc.Store(id='options-store', data=json.dumps(options)),
dcc.Store(id='states-store', data=json.dumps(states)),
dcc.Store(id='states-abbrevations', data=json.dumps(state_abbreviations)),
#US Map here
dl.Map([
dl.TileLayer(url="http://tile.stamen.com/toner-lite/{z}/{x}/{y}.png"),
dl.GeoJSON(data=us_states_geojson, id="state-layer")],
style={'width': '100%', 'height': '250px'},
id="map",
center=[39.8283, -98.5795],
),
#Drop down menu here
html.Div(className='row', children=[
dcc.Dropdown(
id='state-dropdown',
options=[{'label': 'Select all', 'value': 'ALL'}] +
[{'label': state, 'value': state} for state in states],
value=[],
multi=True,
placeholder='States'
)]),
html.Div(className='one columns', children=[
html.Button(
'Clear',
id='clear-button',
n_clicks=0,
className='my-button'
),
]),
])
@app.callback(
Output('state-dropdown', 'value', allow_duplicate=True),
[Input('clear-button', 'n_clicks')],
prevent_initial_call=True
)
def clear_tab(user_click):
if user_click:
return []
else:
raise dash.exceptions.PreventUpdate
app.clientside_callback(
"""
function(click_feature, selected_states, defaults_options, states, states_abbreviations) {
let options = defaults_options
let select_all_selected = selected_states.includes('ALL');
let list_states;
if (select_all_selected) {
options = [{'label': 'Select All', 'value': 'ALL'}];
selected_states = states;
list_states = 'ALL';
} else {
list_states = selected_states;
if (click_feature && dash.callback_context.triggered[0]['prop_id'].split('.')[0] == 'state-layer') {
let state_name = state_abbreviations[click_feature["properties"]["NAME"]];
if (!selected_states.includes(state_name)) {
selected_states.push(state_name);
list_states = selected_states;
}
}
}
return [options, list_states];
}
""",
Output('state-dropdown', 'options'),
Output('state-dropdown', 'value'),
Input('state-layer', 'click_feature'),
Input('state-dropdown', 'value'),
State('options-store', 'data'),
State('states-store', 'data'),
State('states-abbrevations', 'data'),
prevent_initial_call=True
)
if __name__ == '__main__':
app.run_server(debug=True)
1条答案
按热度按时间y3bcpkx11#
你不需要将存储数据序列化为JSON字符串(或者这样做,你必须使用
JSON.parse()
客户端将它们反序列化回来,但Dash已经在内部完成了),所以第一件事是在应用程序布局中解决这个问题,以便在客户端回调中接收正确的JS对象:第二件事是在客户端回调中使用
dash_clientside
而不是dash
,这样你就可以获得回调上下文等,并且还修复了states_abbreviations
的拼写错误: