-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathplotlyDash_patternMatching_subIndex.py
142 lines (116 loc) · 3.7 KB
/
plotlyDash_patternMatching_subIndex.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# this is an answer to a question on the plotly forums:
# https://community.plotly.com/t/sub-indexing-pattern-matching-callbacks/80573
import time
import dash
from dash import html, dcc, Input, Output, ALL, MATCH, ctx, State
# define amount of components
BUTTONS = 5
ROWS = 2
def create_lookup(major: int, minor: int) -> dict:
"""
function creates a dictionary where the keys are a combination
of major and minor indices and values are integers (sequential)
Parameters:
major: range of major indices
minor: range of minor indices
Returns:
dictionary
"""
look_up = {}
count = 0
for mjr in range(major):
for mir in range(minor):
key = f'{mjr}-{mir}'
look_up[key] = count
count += 1
return look_up
def search(search_in: dict, search_for: str, search_what='major') -> list:
"""
function searches in the keys of a dictionary for a string
Parameters:
search_in: dictionary in which to search
search_for: search string
search_what: first or second part of the key.spit('-')
Returns:
list of dict.values() where the search string has been found in dict.keys()
"""
found = []
for combined_index in search_in.keys():
# split into major and minor index
mjr, mnr = combined_index.split('-')
# what is searched for?
if search_what == 'major':
if search_for == mjr:
found.append(search_in[combined_index])
else:
if search_for == mnr:
found.append(search_in[combined_index])
return found
app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Div(
[
html.Div(
[
html.Button(
id={'type': 'btn', 'index': f'{major}-{minor}'},
children=f'{major}-{minor}'
)
for minor in range(BUTTONS)
]
)
for major in range(ROWS)
]
),
html.Div(
[
html.Div(
[
html.Div(
id={'type': 'out', 'index': f'{major}-{minor}'},
children=f'{major}-{minor}'
)
for minor in range(BUTTONS)
]
)
for major in range(ROWS)
]
),
dcc.Store(id='lookup', data=create_lookup(ROWS, BUTTONS))
]
)
@app.callback(
Output({'type': 'out', 'index': MATCH}, 'children'),
Input({'type': 'btn', 'index': MATCH}, 'n_clicks'),
prevent_initial_call=True
)
def show(click):
idx = ctx.triggered_id.index
return f'index {idx} clicked {click} times'
@app.callback(
Output({'type': 'out', 'index': ALL}, 'children', allow_duplicate=True),
Input({'type': 'btn', 'index': ALL}, 'n_clicks'),
State({'type': 'out', 'index': ALL}, 'children'),
State('lookup', 'data'),
prevent_initial_call=True
)
def show(_, state, lookup):
# create some delay between the two callbacks
time.sleep(1)
# extract trigger
idx = ctx.triggered_id.index
# spit into major and minor indices
row_idx, btn_index = idx.split('-')
# find the positions of the corresponding indices
indices = search(
search_in=lookup,
search_for=row_idx,
search_what='major'
)
# change values where needed
for i in indices:
state[i] = f'all has been used. button in row {row_idx} triggered callback'
return state
if __name__ == '__main__':
app.run_server(debug=True)