Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
FoodInformatics
msx-tool
Commits
904796c1
Commit
904796c1
authored
Mar 31, 2021
by
Jim Hoekstra
👋🏻
Browse files
restructuring of app layout and callbacks
parent
9b2ef564
Changes
5
Hide whitespace changes
Inline
Side-by-side
dash_app/app.py
View file @
904796c1
import
os
import
json
import
dash
import
dash_core_components
as
dcc
import
dash_html_components
as
html
from
dash.exceptions
import
PreventUpdate
from
dash.dependencies
import
Input
,
Output
,
State
from
dash_app.graph
import
Graph
from
dash_app.words
import
AssociatedWords
external_stylesheets
=
[
{
'href'
:
'https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css'
,
'rel'
:
'stylesheet'
,
'integrity'
:
'sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl'
,
'crossorigin'
:
'anonymous'
}
]
from
dash_app.layout
import
external_stylesheets
app
=
dash
.
Dash
(
name
=
__name__
,
external_stylesheets
=
external_stylesheets
,
url_base_pathname
=
'/msx/'
,
suppress_callback_exceptions
=
True
)
server
=
app
.
server
server
.
config
[
'SECRET_KEY'
]
=
os
.
environ
[
'MSX_SECRET_KEY'
]
word2vec_model
=
AssociatedWords
()
app
.
layout
=
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'container'
,
children
=
[
html
.
Br
(),
html
.
Br
(),
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'row'
,
children
=
[
html
.
Div
(
className
=
'col-1'
,
children
=
[
html
.
H2
(
children
=
'Term:'
),
]),
html
.
Div
(
className
=
'col-9'
,
children
=
[
dcc
.
Input
(
id
=
'base-word-input'
,
value
=
'fruit'
,
type
=
'text'
,
className
=
'form-control form-control-lg'
),
]),
html
.
Div
(
className
=
'col-2'
,
children
=
[
html
.
Button
(
id
=
'submit-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Submit Term'
,
className
=
'btn btn-success btn-lg'
)]),
])
]),
html
.
Br
(),
html
.
Div
(
id
=
'base-word-div'
,
style
=
{
'display'
:
'none'
},
),
html
.
Div
(
id
=
'graph-elements-div'
,
style
=
{
'display'
:
'none'
},
),
html
.
Div
(
id
=
'msx-graph-div'
,
children
=
[]),
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'row'
,
children
=
[
html
.
Div
(
className
=
'col-3'
,
children
=
[
dcc
.
Input
(
id
=
'add-word-input'
,
value
=
''
,
type
=
'text'
,
className
=
'form-control form-control-lg'
),
]),
html
.
Div
(
className
=
'col-2'
,
children
=
[
html
.
Button
(
id
=
'add-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Add Association'
,
className
=
'btn btn-success btn-lg'
),
]),
html
.
Div
(
className
=
'col-4'
,
children
=
[
]),
html
.
Div
(
className
=
'col-3'
,
children
=
[
html
.
Button
(
id
=
'remove-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Remove Selected Association'
,
className
=
'btn btn-danger btn-lg'
)]),
]),
]),
]),
])
@
app
.
callback
(
Output
(
component_id
=
'msx-graph-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
)
def
update_graph_div
(
submit_word_button
):
graph
=
Graph
()
graph
.
set_nodes_and_edges
({
'nodes'
:
[],
'edges'
:
[]})
return
graph
.
get_cytoscape_graph
(
'msx-graph'
)
@
app
.
callback
(
Output
(
component_id
=
'base-word-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
State
(
component_id
=
'base-word-input'
,
component_property
=
'value'
),
)
def
update_base_word
(
submit_word_button
,
base_word_input
):
return
base_word_input
@
app
.
callback
(
Output
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'add-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'remove-word-button'
,
component_property
=
'n_clicks'
),
State
(
component_id
=
'base-word-input'
,
component_property
=
'value'
),
State
(
component_id
=
'add-word-input'
,
component_property
=
'value'
),
State
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
State
(
component_id
=
'msx-graph'
,
component_property
=
'tapNodeData'
),
State
(
component_id
=
'base-word-div'
,
component_property
=
'children'
),
prevent_initial_call
=
True
)
def
update_graph_elements
(
submit_word_button
,
add_word_button
,
remove_word_button
,
base_word_input
,
add_word_input
,
nodes_and_edges
,
selected_nodes
,
base_word_state
):
callback_context
=
dash
.
callback_context
button_id
=
callback_context
.
triggered
[
0
][
'prop_id'
].
split
(
'.'
)[
0
]
graph
=
Graph
()
if
button_id
==
'submit-word-button'
:
graph
.
fill_with_associations
(
word2vec_model
,
base_word_input
)
new_nodes_and_edges
=
graph
.
get_nodes_and_edges
()
return
json
.
dumps
(
new_nodes_and_edges
)
if
button_id
==
'add-word-button'
:
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
if
add_word_input
is
not
None
and
add_word_input
!=
''
and
add_word_input
not
in
graph
.
get_all_words
():
graph
.
add_node
(
add_word_input
)
graph
.
add_edge
(
base_word_state
,
add_word_input
)
new_nodes_and_edges
=
json
.
dumps
(
graph
.
get_nodes_and_edges
())
return
new_nodes_and_edges
else
:
raise
PreventUpdate
if
button_id
==
'remove-word-button'
:
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
if
selected_nodes
is
not
None
:
selected_word
=
selected_nodes
[
'label'
]
if
selected_word
in
graph
.
get_all_words
()
and
selected_word
!=
base_word_state
:
graph
.
remove_node
(
selected_nodes
[
'label'
])
new_nodes_and_edges
=
json
.
dumps
(
graph
.
get_nodes_and_edges
())
return
new_nodes_and_edges
else
:
raise
PreventUpdate
else
:
raise
PreventUpdate
@
app
.
callback
(
Output
(
component_id
=
'msx-graph'
,
component_property
=
'elements'
),
Input
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
prevent_initial_call
=
True
)
def
update_graph
(
nodes_and_edges
):
graph
=
Graph
()
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
return
graph
.
get_elements
()
@
app
.
callback
(
Output
(
component_id
=
'msx-graph'
,
component_property
=
'autoRefreshLayout'
),
Input
(
component_id
=
'add-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'remove-word-button'
,
component_property
=
'n_clicks'
),
prevent_initial_call
=
True
)
def
set_auto_refresh_layout
(
add_word_button
,
remove_word_button
):
return
False
dash_app/callbacks.py
0 → 100644
View file @
904796c1
import
dash
from
dash.exceptions
import
PreventUpdate
from
dash.dependencies
import
Input
,
Output
,
State
import
json
from
dash_app.app
import
app
from
dash_app.graph
import
Graph
from
dash_app.words
import
AssociatedWords
word2vec_model
=
AssociatedWords
()
@
app
.
callback
(
Output
(
component_id
=
'msx-graph-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
)
def
update_graph_div
(
submit_word_button
):
graph
=
Graph
()
graph
.
set_nodes_and_edges
({
'nodes'
:
[],
'edges'
:
[]})
return
graph
.
get_cytoscape_graph
(
'msx-graph'
)
@
app
.
callback
(
Output
(
component_id
=
'base-word-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
State
(
component_id
=
'base-word-input'
,
component_property
=
'value'
),
)
def
update_base_word
(
submit_word_button
,
base_word_input
):
return
base_word_input
@
app
.
callback
(
Output
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
Input
(
component_id
=
'submit-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'add-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'remove-word-button'
,
component_property
=
'n_clicks'
),
State
(
component_id
=
'base-word-input'
,
component_property
=
'value'
),
State
(
component_id
=
'add-word-input'
,
component_property
=
'value'
),
State
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
State
(
component_id
=
'msx-graph'
,
component_property
=
'tapNodeData'
),
State
(
component_id
=
'base-word-div'
,
component_property
=
'children'
),
prevent_initial_call
=
True
)
def
update_graph_elements
(
submit_word_button
,
add_word_button
,
remove_word_button
,
base_word_input
,
add_word_input
,
nodes_and_edges
,
selected_nodes
,
base_word_state
):
callback_context
=
dash
.
callback_context
button_id
=
callback_context
.
triggered
[
0
][
'prop_id'
].
split
(
'.'
)[
0
]
graph
=
Graph
()
if
button_id
==
'submit-word-button'
:
graph
.
fill_with_associations
(
word2vec_model
,
base_word_input
)
new_nodes_and_edges
=
graph
.
get_nodes_and_edges
()
return
json
.
dumps
(
new_nodes_and_edges
)
if
button_id
==
'add-word-button'
:
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
if
add_word_input
is
not
None
and
add_word_input
!=
''
and
add_word_input
not
in
graph
.
get_all_words
():
graph
.
add_node
(
add_word_input
)
graph
.
add_edge
(
base_word_state
,
add_word_input
)
new_nodes_and_edges
=
json
.
dumps
(
graph
.
get_nodes_and_edges
())
return
new_nodes_and_edges
else
:
raise
PreventUpdate
if
button_id
==
'remove-word-button'
:
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
if
selected_nodes
is
not
None
:
selected_word
=
selected_nodes
[
'label'
]
if
selected_word
in
graph
.
get_all_words
()
and
selected_word
!=
base_word_state
:
graph
.
remove_node
(
selected_nodes
[
'label'
])
new_nodes_and_edges
=
json
.
dumps
(
graph
.
get_nodes_and_edges
())
return
new_nodes_and_edges
else
:
raise
PreventUpdate
else
:
raise
PreventUpdate
@
app
.
callback
(
Output
(
component_id
=
'msx-graph'
,
component_property
=
'elements'
),
Input
(
component_id
=
'graph-elements-div'
,
component_property
=
'children'
),
prevent_initial_call
=
True
)
def
update_graph
(
nodes_and_edges
):
graph
=
Graph
()
graph
.
set_nodes_and_edges
(
json
.
loads
(
nodes_and_edges
))
return
graph
.
get_elements
()
@
app
.
callback
(
Output
(
component_id
=
'msx-graph'
,
component_property
=
'autoRefreshLayout'
),
Input
(
component_id
=
'add-word-button'
,
component_property
=
'n_clicks'
),
Input
(
component_id
=
'remove-word-button'
,
component_property
=
'n_clicks'
),
prevent_initial_call
=
True
)
def
set_auto_refresh_layout
(
add_word_button
,
remove_word_button
):
return
False
dash_app/index.py
0 → 100644
View file @
904796c1
import
os
from
dash_app.app
import
app
from
dash_app.layout
import
layout
import
dash_app.callbacks
app
.
layout
=
layout
server
=
app
.
server
server
.
config
[
'SECRET_KEY'
]
=
os
.
environ
[
'MSX_SECRET_KEY'
]
dash_app/layout.py
0 → 100644
View file @
904796c1
import
dash_core_components
as
dcc
import
dash_html_components
as
html
external_stylesheets
=
[
{
'href'
:
'https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css'
,
'rel'
:
'stylesheet'
,
'integrity'
:
'sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl'
,
'crossorigin'
:
'anonymous'
}
]
layout
=
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'container'
,
children
=
[
html
.
Br
(),
html
.
Br
(),
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'row'
,
children
=
[
html
.
Div
(
className
=
'col-1'
,
children
=
[
html
.
H2
(
children
=
'Term:'
),
]),
html
.
Div
(
className
=
'col-9'
,
children
=
[
dcc
.
Input
(
id
=
'base-word-input'
,
value
=
'fruit'
,
type
=
'text'
,
className
=
'form-control form-control-lg'
),
]),
html
.
Div
(
className
=
'col-2'
,
children
=
[
html
.
Button
(
id
=
'submit-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Submit Term'
,
className
=
'btn btn-success btn-lg'
)]),
])
]),
html
.
Br
(),
html
.
Div
(
id
=
'base-word-div'
,
style
=
{
'display'
:
'none'
},
),
html
.
Div
(
id
=
'graph-elements-div'
,
style
=
{
'display'
:
'none'
},
),
html
.
Div
(
id
=
'msx-graph-div'
,
children
=
[]),
html
.
Div
(
children
=
[
html
.
Div
(
className
=
'row'
,
children
=
[
html
.
Div
(
className
=
'col-3'
,
children
=
[
dcc
.
Input
(
id
=
'add-word-input'
,
value
=
''
,
type
=
'text'
,
className
=
'form-control form-control-lg'
),
]),
html
.
Div
(
className
=
'col-2'
,
children
=
[
html
.
Button
(
id
=
'add-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Add Association'
,
className
=
'btn btn-success btn-lg'
),
]),
html
.
Div
(
className
=
'col-4'
,
children
=
[
]),
html
.
Div
(
className
=
'col-3'
,
children
=
[
html
.
Button
(
id
=
'remove-word-button'
,
n_clicks_timestamp
=
0
,
children
=
'Remove Selected Association'
,
className
=
'btn btn-danger btn-lg'
)]),
]),
]),
]),
])
scripts/run_debug_server.py
View file @
904796c1
from
dash_app.
app
import
app
from
dash_app.
index
import
app
if
__name__
==
'__main__'
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment