Skip to content

Commit 633e3ea

Browse files
committed
Reorganize visualizer menu and add show-arrows option
Signed-off-by: Thijs Baaijen <[email protected]>
1 parent 38d9969 commit 633e3ea

File tree

11 files changed

+175
-76
lines changed

11 files changed

+175
-76
lines changed

src/power_grid_model_ds/_core/visualizer/app.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
from power_grid_model_ds._core.model.grids.base import Grid
1010
from power_grid_model_ds._core.visualizer.callbacks import ( # noqa: F401 # pylint: disable=unused-import
11-
element_scaling,
11+
config,
1212
element_selection,
13-
layout_dropdown,
13+
header,
1414
search_form,
1515
)
1616
from power_grid_model_ds._core.visualizer.layout.cytoscape_html import get_cytoscape_html
17+
from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import DEFAULT_STYLESHEET
1718
from power_grid_model_ds._core.visualizer.layout.header import HEADER_HTML
1819
from power_grid_model_ds._core.visualizer.layout.selection_output import SELECTION_OUTPUT_HTML
1920
from power_grid_model_ds._core.visualizer.parsers import parse_branches, parse_node_array
@@ -76,6 +77,7 @@ def get_app_layout(grid: Grid) -> html.Div:
7677
return html.Div(
7778
[
7879
columns_store,
80+
dcc.Store(id="stylesheet-store", data=DEFAULT_STYLESHEET),
7981
HEADER_HTML,
8082
html.Hr(style={"border-color": "white", "margin": "0"}),
8183
cytoscape_html,
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
6+
from dash import Input, Output, State, callback
7+
from dash.exceptions import PreventUpdate
8+
9+
from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import BRANCH_WIDTH, NODE_SIZE, STYLESHEET
10+
11+
12+
@callback(
13+
Output("stylesheet-store", "data", allow_duplicate=True),
14+
Output("cytoscape-graph", "stylesheet", allow_duplicate=True),
15+
Input("node-scale-input", "value"),
16+
Input("edge-scale-input", "value"),
17+
State("stylesheet-store", "data"),
18+
prevent_initial_call=True,
19+
)
20+
def scale_elements(node_scale: float, edge_scale: float, stylesheet: STYLESHEET) -> tuple[STYLESHEET, STYLESHEET]:
21+
"""Callback to scale the elements of the graph."""
22+
if stylesheet is None:
23+
raise PreventUpdate
24+
if node_scale == 1 and edge_scale == 1:
25+
raise PreventUpdate
26+
new_stylesheet = stylesheet.copy()
27+
edge_style = {
28+
"selector": "edge",
29+
"style": {
30+
"width": BRANCH_WIDTH * edge_scale,
31+
},
32+
}
33+
new_stylesheet.append(edge_style)
34+
node_style = {
35+
"selector": "node",
36+
"style": {
37+
"height": NODE_SIZE * node_scale,
38+
"width": NODE_SIZE * node_scale,
39+
},
40+
}
41+
new_stylesheet.append(node_style)
42+
43+
return new_stylesheet, new_stylesheet
44+
45+
46+
@callback(Output("cytoscape-graph", "layout"), Input("dropdown-update-layout", "value"), prevent_initial_call=True)
47+
def update_layout(layout):
48+
"""Callback to update the layout of the graph."""
49+
return {"name": layout, "animate": True}
50+
51+
52+
@callback(
53+
Output("cytoscape-graph", "stylesheet", allow_duplicate=True),
54+
Input("show-arrows", "value"),
55+
State("cytoscape-graph", "stylesheet"),
56+
prevent_initial_call=True,
57+
)
58+
def update_arrows(show_arrows, current_stylesheet):
59+
"""Callback to update the arrow style of edges in the graph."""
60+
selectors = [rule["selector"] for rule in current_stylesheet]
61+
index = selectors.index("edge")
62+
edge_style = current_stylesheet[index]["style"]
63+
64+
if show_arrows:
65+
edge_style["target-arrow-shape"] = "triangle"
66+
else:
67+
edge_style["target-arrow-shape"] = "none"
68+
return current_stylesheet

src/power_grid_model_ds/_core/visualizer/callbacks/element_scaling.py

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
2+
#
3+
# SPDX-License-Identifier: MPL-2.0
4+
5+
import dash
6+
from dash import Input, Output, callback
7+
8+
from power_grid_model_ds._core.visualizer.layout.header import CONFIG_DIV, SEARCH_DIV
9+
from power_grid_model_ds._core.visualizer.layout.legenda import LEGENDA_HTML
10+
11+
12+
@callback(
13+
Output("right-col-content", "children"),
14+
[
15+
Input("btn-legend", "n_clicks"),
16+
Input("btn-search", "n_clicks"),
17+
Input("btn-config", "n_clicks"),
18+
],
19+
)
20+
def update_right_col(_btn1, _btn2, _btn3):
21+
"""Update the right column content based on the button clicked."""
22+
ctx = dash.callback_context
23+
if not ctx.triggered:
24+
return LEGENDA_HTML
25+
button_id = ctx.triggered[0]["prop_id"].split(".")[0]
26+
button_map = {
27+
"btn-legend": LEGENDA_HTML,
28+
"btn-search": SEARCH_DIV,
29+
"btn-config": CONFIG_DIV,
30+
}
31+
return button_map.get(button_id, "Right Column")

src/power_grid_model_ds/_core/visualizer/callbacks/layout_dropdown.py

Lines changed: 0 additions & 11 deletions
This file was deleted.

src/power_grid_model_ds/_core/visualizer/callbacks/search_form.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
22
#
33
# SPDX-License-Identifier: MPL-2.0
4-
from typing import Any
54

6-
from dash import Input, Output, callback
5+
from dash import Input, Output, State, callback
6+
from dash.exceptions import PreventUpdate
77

88
from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
9-
from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import DEFAULT_STYLESHEET
9+
from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import STYLESHEET
1010

1111

1212
@callback(
@@ -15,11 +15,12 @@
1515
Input("search-form-column-input", "value"),
1616
Input("search-form-operator-input", "value"),
1717
Input("search-form-value-input", "value"),
18+
State("stylesheet-store", "data"),
1819
)
19-
def search_element(group: str, column: str, operator: str, value: str) -> list[dict[str, Any]]:
20+
def search_element(group: str, column: str, operator: str, value: str, stylesheet: STYLESHEET) -> STYLESHEET:
2021
"""Color the specified element red based on the input values."""
2122
if not group or not column or not value:
22-
return DEFAULT_STYLESHEET
23+
raise PreventUpdate
2324

2425
# Determine if we're working with a node or an edge type
2526
if group == "node":
@@ -39,7 +40,8 @@ def search_element(group: str, column: str, operator: str, value: str) -> list[d
3940
"selector": selector,
4041
"style": style,
4142
}
42-
return DEFAULT_STYLESHEET + [new_style]
43+
updated_stylesheet = stylesheet + [new_style]
44+
return updated_stylesheet
4345

4446

4547
@callback(

src/power_grid_model_ds/_core/visualizer/layout/cytoscape_config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@
4444
dcc.Dropdown(
4545
id="dropdown-update-layout",
4646
placeholder="Select layout",
47-
value="",
47+
value="breadthfirst",
4848
clearable=False,
4949
options=[{"label": name.capitalize(), "value": name} for name in LAYOUT_OPTIONS],
5050
style={"width": "200px"},
5151
),
52-
style={"margin": "0 20px 0 10px"},
52+
style={"margin": "0 20px 0 10px", "color": "black"},
5353
)
5454
]

src/power_grid_model_ds/_core/visualizer/layout/cytoscape_styling.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44

55
"""Contains selectors for the Cytoscape stylesheet."""
66

7+
from typing import Any
8+
79
from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
810

11+
STYLESHEET = list[dict[str, Any]]
12+
13+
914
NODE_SIZE = 100
1015
BRANCH_WIDTH = 10
1116

src/power_grid_model_ds/_core/visualizer/layout/header.py

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,59 @@
33
# SPDX-License-Identifier: MPL-2.0
44

55
import dash_bootstrap_components as dbc
6+
from dash import html
67

7-
from power_grid_model_ds._core.visualizer.layout.colors import BACKGROUND_COLOR
88
from power_grid_model_ds._core.visualizer.layout.cytoscape_config import LAYOUT_DROPDOWN_HTML, SCALE_INPUTS
99
from power_grid_model_ds._core.visualizer.layout.legenda import LEGENDA_HTML
1010
from power_grid_model_ds._core.visualizer.layout.search_form import SEARCH_FORM_HTML
1111

12-
_SEARCH_FORM_CARD_STYLE = {
13-
"background-color": "#555555",
14-
"color": "white",
15-
"border-left": "1px solid white",
16-
"border-right": "1px solid white",
17-
"border-radius": 0,
18-
}
19-
12+
SHOW_ARROWS_CHECKBOX = dbc.Checkbox(
13+
id="show-arrows",
14+
label="Show arrows",
15+
value=True,
16+
className="me-2",
17+
label_style={"color": "white"},
18+
style={"margin-top": "10px"},
19+
)
20+
CONFIG_DIV = html.Div(
21+
SCALE_INPUTS + LAYOUT_DROPDOWN_HTML + [SHOW_ARROWS_CHECKBOX],
22+
className="d-flex justify-content-end align-items-center",
23+
)
24+
SEARCH_DIV = html.Div(SEARCH_FORM_HTML)
2025

2126
HEADER_HTML = dbc.Row(
2227
[
23-
dbc.Col(LEGENDA_HTML, className="d-flex align-items-center"),
2428
dbc.Col(
25-
dbc.Card(SEARCH_FORM_HTML, style=_SEARCH_FORM_CARD_STYLE),
26-
className="d-flex justify-content-center align-items-center",
29+
[
30+
dbc.Button("Legend", id="btn-legend", color="primary", className="me-2"),
31+
dbc.Button("Search", id="btn-search", color="secondary", className="me-2"),
32+
dbc.Button("Config", id="btn-config", color="success", className="me-2"),
33+
],
34+
width=5,
35+
style={
36+
"display": "flex",
37+
"align-items": "center",
38+
"justify-content": "center",
39+
"border-right": "1px solid white",
40+
},
41+
),
42+
dbc.Col(
43+
html.Div([LEGENDA_HTML, SEARCH_DIV, CONFIG_DIV], id="right-col-content", className="text-end"),
44+
width=7,
45+
style={
46+
"display": "flex",
47+
"align-items": "center",
48+
"justify-content": "center",
49+
},
2750
),
28-
dbc.Col(SCALE_INPUTS + LAYOUT_DROPDOWN_HTML, className="d-flex justify-content-end align-items-center"),
2951
],
30-
style={"background-color": BACKGROUND_COLOR},
52+
style={
53+
"background-color": "#343a40",
54+
"color": "white",
55+
"padding": "1rem 0",
56+
"margin": 0,
57+
"height": "90px",
58+
},
59+
className="g-0",
60+
align="center",
3161
)

src/power_grid_model_ds/_core/visualizer/layout/legenda.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,6 @@
3737
"margin": _MARGIN,
3838
"width": "100%",
3939
"text-shadow": "0 0 5px #000",
40+
# "display": "none",
4041
},
4142
)

0 commit comments

Comments
 (0)