power-grid-model-ds 1.4.3__py3-none-any.whl → 1.4.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. power_grid_model_ds/_core/model/arrays/base/_string.py +1 -1
  2. power_grid_model_ds/_core/model/grids/base.py +1 -1
  3. power_grid_model_ds/_core/visualizer/app.py +4 -2
  4. power_grid_model_ds/_core/visualizer/callbacks/config.py +66 -0
  5. power_grid_model_ds/_core/visualizer/callbacks/element_selection.py +1 -1
  6. power_grid_model_ds/_core/visualizer/callbacks/header.py +30 -0
  7. power_grid_model_ds/_core/visualizer/callbacks/search_form.py +8 -6
  8. power_grid_model_ds/_core/visualizer/layout/cytoscape_html.py +0 -2
  9. power_grid_model_ds/_core/visualizer/layout/header.py +49 -18
  10. power_grid_model_ds/_core/visualizer/layout/header_config.py +71 -0
  11. power_grid_model_ds/_core/visualizer/layout/header_legenda.py +36 -0
  12. power_grid_model_ds/_core/visualizer/layout/{search_form.py → header_search.py} +12 -18
  13. power_grid_model_ds/_core/visualizer/typing.py +7 -0
  14. {power_grid_model_ds-1.4.3.dist-info → power_grid_model_ds-1.4.6.dist-info}/METADATA +4 -23
  15. {power_grid_model_ds-1.4.3.dist-info → power_grid_model_ds-1.4.6.dist-info}/RECORD +18 -17
  16. power_grid_model_ds/_core/visualizer/callbacks/element_scaling.py +0 -37
  17. power_grid_model_ds/_core/visualizer/callbacks/layout_dropdown.py +0 -11
  18. power_grid_model_ds/_core/visualizer/layout/cytoscape_config.py +0 -54
  19. power_grid_model_ds/_core/visualizer/layout/legenda.py +0 -41
  20. {power_grid_model_ds-1.4.3.dist-info → power_grid_model_ds-1.4.6.dist-info}/WHEEL +0 -0
  21. {power_grid_model_ds-1.4.3.dist-info → power_grid_model_ds-1.4.6.dist-info}/licenses/LICENSE +0 -0
  22. {power_grid_model_ds-1.4.3.dist-info → power_grid_model_ds-1.4.6.dist-info}/top_level.txt +0 -0
@@ -82,7 +82,7 @@ def _determine_column_widths(array: "FancyArray") -> list[tuple[str, int]]:
82
82
  def _center_and_truncate(string: str, width: int) -> str:
83
83
  if len(string) <= width:
84
84
  return string.center(width)
85
- return f"{string[:width - 2]}..".center(width)
85
+ return f"{string[: width - 2]}..".center(width)
86
86
 
87
87
 
88
88
  def _get_start_and_end_rows(array: "FancyArray", rows: int) -> tuple["FancyArray", Optional["FancyArray"]]:
@@ -451,7 +451,7 @@ class Grid(FancyArrayContainer):
451
451
  for field in dataclasses.fields(cls):
452
452
  if field.name == "node":
453
453
  continue # already added
454
- if issubclass(field.type, FancyArray):
454
+ if isinstance(field.type, type) and issubclass(field.type, FancyArray):
455
455
  extended_array = getattr(extended, field.name)
456
456
  new_array = field.type.from_extended(extended_array)
457
457
  new_grid.append(new_array, check_max_id=False)
@@ -8,12 +8,13 @@ from dash_bootstrap_components.icons import FONT_AWESOME
8
8
 
9
9
  from power_grid_model_ds._core.model.grids.base import Grid
10
10
  from power_grid_model_ds._core.visualizer.callbacks import ( # noqa: F401 # pylint: disable=unused-import
11
- element_scaling,
11
+ config,
12
12
  element_selection,
13
- layout_dropdown,
13
+ header,
14
14
  search_form,
15
15
  )
16
16
  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
17
18
  from power_grid_model_ds._core.visualizer.layout.header import HEADER_HTML
18
19
  from power_grid_model_ds._core.visualizer.layout.selection_output import SELECTION_OUTPUT_HTML
19
20
  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:
76
77
  return html.Div(
77
78
  [
78
79
  columns_store,
80
+ dcc.Store(id="stylesheet-store", data=DEFAULT_STYLESHEET),
79
81
  HEADER_HTML,
80
82
  html.Hr(style={"border-color": "white", "margin": "0"}),
81
83
  cytoscape_html,
@@ -0,0 +1,66 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
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
10
+ from power_grid_model_ds._core.visualizer.typing import STYLESHEET
11
+
12
+
13
+ @callback(
14
+ Output("stylesheet-store", "data", allow_duplicate=True),
15
+ Output("cytoscape-graph", "stylesheet", allow_duplicate=True),
16
+ Input("node-scale-input", "value"),
17
+ Input("edge-scale-input", "value"),
18
+ State("stylesheet-store", "data"),
19
+ prevent_initial_call=True,
20
+ )
21
+ def scale_elements(node_scale: float, edge_scale: float, stylesheet: STYLESHEET) -> tuple[STYLESHEET, STYLESHEET]:
22
+ """Callback to scale the elements of the graph."""
23
+ if stylesheet is None:
24
+ raise PreventUpdate
25
+ if node_scale == 1 and edge_scale == 1:
26
+ raise PreventUpdate
27
+ new_stylesheet = stylesheet.copy()
28
+ edge_style = {
29
+ "selector": "edge",
30
+ "style": {
31
+ "width": BRANCH_WIDTH * edge_scale,
32
+ },
33
+ }
34
+ new_stylesheet.append(edge_style)
35
+ node_style = {
36
+ "selector": "node",
37
+ "style": {
38
+ "height": NODE_SIZE * node_scale,
39
+ "width": NODE_SIZE * node_scale,
40
+ },
41
+ }
42
+ new_stylesheet.append(node_style)
43
+
44
+ return new_stylesheet, new_stylesheet
45
+
46
+
47
+ @callback(Output("cytoscape-graph", "layout"), Input("dropdown-update-layout", "value"), prevent_initial_call=True)
48
+ def update_layout(layout):
49
+ """Callback to update the layout of the graph."""
50
+ return {"name": layout, "animate": True}
51
+
52
+
53
+ @callback(
54
+ Output("cytoscape-graph", "stylesheet", allow_duplicate=True),
55
+ Input("show-arrows", "value"),
56
+ State("cytoscape-graph", "stylesheet"),
57
+ prevent_initial_call=True,
58
+ )
59
+ def update_arrows(show_arrows, current_stylesheet):
60
+ """Callback to update the arrow style of edges in the graph."""
61
+ selectors = [rule["selector"] for rule in current_stylesheet]
62
+ index = selectors.index("edge")
63
+ edge_style = current_stylesheet[index]["style"]
64
+
65
+ edge_style["target-arrow-shape"] = "triangle" if show_arrows else "none"
66
+ return current_stylesheet
@@ -27,7 +27,7 @@ def display_selected_element(node_data, edge_data):
27
27
 
28
28
  def _to_data_table(data: dict[str, Any]):
29
29
  columns = data.keys()
30
- data_table = dash_table.DataTable(
30
+ data_table = dash_table.DataTable( # type: ignore[attr-defined]
31
31
  data=[data], columns=[{"name": key, "id": key} for key in columns], editable=False
32
32
  )
33
33
  return data_table
@@ -0,0 +1,30 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
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, LEGENDA_DIV, SEARCH_DIV
9
+
10
+
11
+ @callback(
12
+ Output("header-right-col", "children"),
13
+ [
14
+ Input("btn-legend", "n_clicks"),
15
+ Input("btn-search", "n_clicks"),
16
+ Input("btn-config", "n_clicks"),
17
+ ],
18
+ )
19
+ def update_right_col(_btn1, _btn2, _btn3):
20
+ """Update the right column content based on the button clicked."""
21
+ ctx = dash.callback_context
22
+ if not ctx.triggered:
23
+ return LEGENDA_DIV
24
+ button_id = ctx.triggered[0]["prop_id"].split(".")[0]
25
+ button_map = {
26
+ "btn-legend": LEGENDA_DIV,
27
+ "btn-search": SEARCH_DIV,
28
+ "btn-config": CONFIG_DIV,
29
+ }
30
+ return button_map.get(button_id, "Right Column")
@@ -1,12 +1,12 @@
1
1
  # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
2
  #
3
3
  # SPDX-License-Identifier: MPL-2.0
4
- from typing import Any
5
4
 
6
- from dash import Input, Output, callback
5
+ from dash import Input, Output, State, callback
6
+ from dash.exceptions import PreventUpdate
7
7
 
8
8
  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.typing import STYLESHEET
10
10
 
11
11
 
12
12
  @callback(
@@ -15,11 +15,12 @@ from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import DEFAUL
15
15
  Input("search-form-column-input", "value"),
16
16
  Input("search-form-operator-input", "value"),
17
17
  Input("search-form-value-input", "value"),
18
+ State("stylesheet-store", "data"),
18
19
  )
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:
20
21
  """Color the specified element red based on the input values."""
21
22
  if not group or not column or not value:
22
- return DEFAULT_STYLESHEET
23
+ raise PreventUpdate
23
24
 
24
25
  # Determine if we're working with a node or an edge type
25
26
  if group == "node":
@@ -39,7 +40,8 @@ def search_element(group: str, column: str, operator: str, value: str) -> list[d
39
40
  "selector": selector,
40
41
  "style": style,
41
42
  }
42
- return DEFAULT_STYLESHEET + [new_style]
43
+ updated_stylesheet = stylesheet + [new_style]
44
+ return updated_stylesheet
43
45
 
44
46
 
45
47
  @callback(
@@ -10,8 +10,6 @@ from dash import html
10
10
  from power_grid_model_ds._core.visualizer.layout.colors import BACKGROUND_COLOR
11
11
  from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import DEFAULT_STYLESHEET
12
12
 
13
- LAYOUT_OPTIONS = ["random", "circle", "concentric", "grid", "cose", "breadthfirst"]
14
-
15
13
  _CYTO_INNER_STYLE = {"width": "100%", "height": "100%", "background-color": BACKGROUND_COLOR}
16
14
  _CYTO_OUTER_STYLE = {"height": "80vh"}
17
15
 
@@ -3,29 +3,60 @@
3
3
  # SPDX-License-Identifier: MPL-2.0
4
4
 
5
5
  import dash_bootstrap_components as dbc
6
+ from dash import html
6
7
 
7
- from power_grid_model_ds._core.visualizer.layout.colors import BACKGROUND_COLOR
8
- from power_grid_model_ds._core.visualizer.layout.cytoscape_config import LAYOUT_DROPDOWN_HTML, SCALE_INPUTS
9
- from power_grid_model_ds._core.visualizer.layout.legenda import LEGENDA_HTML
10
- from power_grid_model_ds._core.visualizer.layout.search_form import SEARCH_FORM_HTML
11
-
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,
8
+ from power_grid_model_ds._core.visualizer.layout.header_config import CONFIG_ELEMENTS
9
+ from power_grid_model_ds._core.visualizer.layout.header_legenda import LEGENDA_ELEMENTS, LEGENDA_STYLE
10
+ from power_grid_model_ds._core.visualizer.layout.header_search import SEARCH_ELEMENTS
11
+
12
+ _MENU_BUTTON_STYLE_CLASS = "me-2 btn-outline-primary"
13
+
14
+ _LEFT_COLUMN_HTML = dbc.Col(
15
+ [
16
+ dbc.Button("Legend", id="btn-legend", className=_MENU_BUTTON_STYLE_CLASS),
17
+ dbc.Button("Search", id="btn-search", className=_MENU_BUTTON_STYLE_CLASS),
18
+ dbc.Button("Config", id="btn-config", className=_MENU_BUTTON_STYLE_CLASS),
19
+ ],
20
+ id="header-left-col",
21
+ width=5,
22
+ style={
23
+ "display": "flex",
24
+ "align-items": "center",
25
+ "justify-content": "center",
26
+ "border-right": "1px solid white",
27
+ },
28
+ )
29
+
30
+
31
+ _RIGHT_COLUMN_STYLE = {
32
+ "display": "flex",
33
+ "align-items": "center",
34
+ "width": "100%",
18
35
  }
19
36
 
20
37
 
38
+ CONFIG_DIV = html.Div(CONFIG_ELEMENTS, style=_RIGHT_COLUMN_STYLE | {"justify-content": "space-between"})
39
+ SEARCH_DIV = html.Div(SEARCH_ELEMENTS, style=_RIGHT_COLUMN_STYLE | {"justify-content": "center"})
40
+ LEGENDA_DIV = html.Div(LEGENDA_ELEMENTS, style=_RIGHT_COLUMN_STYLE | LEGENDA_STYLE)
41
+
42
+ _RIGHT_COLUMN_HTML = dbc.Col(
43
+ [LEGENDA_DIV, SEARCH_DIV, CONFIG_DIV],
44
+ id="header-right-col",
45
+ width=7,
46
+ )
47
+
21
48
  HEADER_HTML = dbc.Row(
22
49
  [
23
- dbc.Col(LEGENDA_HTML, className="d-flex align-items-center"),
24
- dbc.Col(
25
- dbc.Card(SEARCH_FORM_HTML, style=_SEARCH_FORM_CARD_STYLE),
26
- className="d-flex justify-content-center align-items-center",
27
- ),
28
- dbc.Col(SCALE_INPUTS + LAYOUT_DROPDOWN_HTML, className="d-flex justify-content-end align-items-center"),
50
+ _LEFT_COLUMN_HTML,
51
+ _RIGHT_COLUMN_HTML,
29
52
  ],
30
- style={"background-color": BACKGROUND_COLOR},
53
+ style={
54
+ "background-color": "#343a40",
55
+ "color": "white",
56
+ "padding": "1rem 0",
57
+ "margin": 0,
58
+ "height": "90px",
59
+ "width": "100%",
60
+ },
61
+ align="center",
31
62
  )
@@ -0,0 +1,71 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+ from enum import Enum
5
+
6
+ import dash_bootstrap_components as dbc
7
+ from dash import dcc, html
8
+
9
+ from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
10
+
11
+ NODE_SCALE_HTML = [
12
+ html.I(className="fas fa-circle", style={"color": CYTO_COLORS["node"], "margin-right": "10px"}),
13
+ dcc.Input(
14
+ id="node-scale-input",
15
+ type="number",
16
+ value=1,
17
+ min=0.1,
18
+ step=0.1,
19
+ style={"width": "75px"},
20
+ ),
21
+ html.Span(style={"margin-right": "10px"}),
22
+ ]
23
+
24
+ EDGE_SCALE_HTML = [
25
+ html.I(className="fas fa-arrow-right-long", style={"color": CYTO_COLORS["line"], "margin-right": "10px"}),
26
+ dcc.Input(
27
+ id="edge-scale-input",
28
+ type="number",
29
+ value=1,
30
+ min=0.1,
31
+ step=0.1,
32
+ style={"width": "75px"},
33
+ ),
34
+ ]
35
+
36
+ _SCALING_DIV = html.Div(NODE_SCALE_HTML + EDGE_SCALE_HTML, style={"margin": "0 20px 0 10px"})
37
+
38
+
39
+ class LayoutOptions(Enum):
40
+ """Cytoscape layout options."""
41
+
42
+ RANDOM = "random"
43
+ CIRCLE = "circle"
44
+ CONCENTRIC = "concentric"
45
+ GRID = "grid"
46
+ COSE = "cose"
47
+ BREADTHFIRST = "breadthfirst"
48
+
49
+
50
+ _LAYOUT_DROPDOWN = html.Div(
51
+ dcc.Dropdown(
52
+ id="dropdown-update-layout",
53
+ placeholder="Select layout",
54
+ value=LayoutOptions.BREADTHFIRST.value,
55
+ clearable=False,
56
+ options=[{"label": option.value, "value": option.value} for option in LayoutOptions], # type: ignore[arg-type]
57
+ style={"width": "200px"},
58
+ ),
59
+ style={"margin": "0 20px 0 10px", "color": "black"},
60
+ )
61
+
62
+
63
+ _ARROWS_CHECKBOX = dbc.Checkbox(
64
+ id="show-arrows",
65
+ label="Show arrows",
66
+ value=True,
67
+ label_style={"color": "white"},
68
+ style={"margin-top": "10px"},
69
+ )
70
+
71
+ CONFIG_ELEMENTS = [_LAYOUT_DROPDOWN, _ARROWS_CHECKBOX, _SCALING_DIV]
@@ -0,0 +1,36 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+
5
+ import dash_bootstrap_components as dbc
6
+ from dash import html
7
+
8
+ from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
9
+
10
+ _BOOTSTRAP_ARROW_ICON_CLASS = "fas fa-arrow-right-long"
11
+ _MARGIN = "0 10px"
12
+
13
+ LEGENDA_STYLE = {"margin": _MARGIN, "text-shadow": "0 0 5px #000", "justify-content": "center"}
14
+
15
+ _FONT_SIZE = "2.5em"
16
+
17
+ NODE_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["node"]}
18
+ _SUBSTATION_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["substation_node"]}
19
+ _LINE_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["line"]}
20
+ _LINK_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["link"]}
21
+ _TRANSFORMER_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["transformer"]}
22
+ _OPEN_BRANCH_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["open_branch"]}
23
+ LEGENDA_ELEMENTS = [
24
+ html.I(className="fas fa-circle", id="node-icon", style=NODE_ICON_STYLE),
25
+ dbc.Tooltip("Node", target="node-icon", placement="bottom"),
26
+ html.I(className="fas fa-diamond", id="substation-icon", style=_SUBSTATION_ICON_STYLE),
27
+ dbc.Tooltip("Substation", target="substation-icon", placement="bottom"),
28
+ html.I(className=_BOOTSTRAP_ARROW_ICON_CLASS, id="line-icon", style=_LINE_ICON_STYLE),
29
+ dbc.Tooltip("Line", target="line-icon", placement="bottom"),
30
+ html.I(className=_BOOTSTRAP_ARROW_ICON_CLASS, id="transformer-icon", style=_TRANSFORMER_ICON_STYLE),
31
+ dbc.Tooltip("Transformer", target="transformer-icon", placement="bottom"),
32
+ html.I(className=_BOOTSTRAP_ARROW_ICON_CLASS, id="link-icon", style=_LINK_ICON_STYLE),
33
+ dbc.Tooltip("Link", target="link-icon", placement="bottom"),
34
+ html.I(className="fas fa-ellipsis", id="open-branch-icon", style=_OPEN_BRANCH_ICON_STYLE),
35
+ dbc.Tooltip("Open Branch", target="open-branch-icon", placement="bottom"),
36
+ ]
@@ -44,21 +44,15 @@ OPERATOR_INPUT = dbc.Select(
44
44
 
45
45
 
46
46
  # Arrange as a sentence
47
- SEARCH_FORM_HTML = html.Div(
48
- [
49
- html.Span("Search ", style=SPAN_TEXT_STYLE),
50
- GROUP_INPUT,
51
- html.Span(" with ", className="mx-2", style=SPAN_TEXT_STYLE),
52
- COLUMN_INPUT,
53
- OPERATOR_INPUT,
54
- VALUE_INPUT,
55
- ],
56
- style={
57
- "display": "flex",
58
- "align-items": "center",
59
- "justify-content": "center", # Centers items horizontally
60
- "padding": "10px",
61
- "margin": "0 auto", # Centers the container itself
62
- "width": "100%", # Ensures the container takes full width
63
- },
64
- )
47
+ SEARCH_ELEMENTS = [
48
+ html.Div(
49
+ [
50
+ html.Span("Search ", style=SPAN_TEXT_STYLE),
51
+ GROUP_INPUT,
52
+ html.Span(" with ", style=SPAN_TEXT_STYLE),
53
+ COLUMN_INPUT,
54
+ OPERATOR_INPUT,
55
+ VALUE_INPUT,
56
+ ]
57
+ )
58
+ ]
@@ -0,0 +1,7 @@
1
+ # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
+ #
3
+ # SPDX-License-Identifier: MPL-2.0
4
+
5
+ from typing import Any
6
+
7
+ STYLESHEET = list[dict[str, Any]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: power-grid-model-ds
3
- Version: 1.4.3
3
+ Version: 1.4.6
4
4
  Summary: Power Grid Model extension which provides a grid data structure for simulation and analysis
5
5
  Author-email: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
6
6
  License: MPL-2.0
@@ -23,32 +23,13 @@ Description-Content-Type: text/markdown
23
23
  License-File: LICENSE
24
24
  Requires-Dist: power-grid-model>=1.7
25
25
  Requires-Dist: rustworkx>=0.15.1
26
- Requires-Dist: numpy>=1.21
27
- Provides-Extra: pandas
28
- Requires-Dist: pandas>=2.2.1; extra == "pandas"
29
- Provides-Extra: dev
30
- Requires-Dist: pylint>=3.1.0; extra == "dev"
31
- Requires-Dist: pytest>=8.1.1; extra == "dev"
32
- Requires-Dist: coverage>=7.4.4; extra == "dev"
33
- Requires-Dist: black>=24.3.0; extra == "dev"
34
- Requires-Dist: ruff>=0.3.5; extra == "dev"
35
- Requires-Dist: isort>=5.13.2; extra == "dev"
36
- Requires-Dist: mypy>=1.9.0; extra == "dev"
37
- Requires-Dist: pre-commit>=4; extra == "dev"
38
- Requires-Dist: dash>=3.0.0; extra == "dev"
39
- Requires-Dist: dash-bootstrap-components>=2.0.0; extra == "dev"
40
- Requires-Dist: dash-cytoscape>=1.0.2; extra == "dev"
26
+ Requires-Dist: numpy>=2.0
41
27
  Provides-Extra: visualizer
42
28
  Requires-Dist: dash>=3.0.0; extra == "visualizer"
43
29
  Requires-Dist: dash-bootstrap-components>=2.0.0; extra == "visualizer"
44
30
  Requires-Dist: dash-cytoscape>=1.0.2; extra == "visualizer"
45
- Provides-Extra: doc
46
- Requires-Dist: sphinx; extra == "doc"
47
- Requires-Dist: myst-nb; extra == "doc"
48
- Requires-Dist: sphinx_rtd_theme; extra == "doc"
49
- Requires-Dist: readthedocs-sphinx-search; extra == "doc"
50
- Requires-Dist: sphinx-hoverxref; extra == "doc"
51
- Requires-Dist: numpydoc; extra == "doc"
31
+ Provides-Extra: pandas
32
+ Requires-Dist: pandas>=2.2.1; extra == "pandas"
52
33
  Dynamic: license-file
53
34
 
54
35
  <!--
@@ -28,7 +28,7 @@ power_grid_model_ds/_core/model/arrays/base/_build.py,sha256=NAdmzkjpC4lP-z1y0au
28
28
  power_grid_model_ds/_core/model/arrays/base/_filters.py,sha256=68DBuliTADfp2VNKpuTSq18fgPa5XC4MkxQIH6G9mV8,4241
29
29
  power_grid_model_ds/_core/model/arrays/base/_modify.py,sha256=TP8LojFMcZnyzhmshzNQnjlEVSZjE_xJ6BNQ4SpIBvA,2476
30
30
  power_grid_model_ds/_core/model/arrays/base/_optional.py,sha256=zEEaE5z7bjLiARb8WTYsgZhbtJYAT6BTd61IUdv_YTA,288
31
- power_grid_model_ds/_core/model/arrays/base/_string.py,sha256=H66DBYq8RHQHj6Gfn2tdEXKoL3ND64iVkZCt-Fwjdn0,3568
31
+ power_grid_model_ds/_core/model/arrays/base/_string.py,sha256=Y2oTbGvoAwKGN2e32LbGynRW_amoLrIhTCt8ItVlKwQ,3569
32
32
  power_grid_model_ds/_core/model/arrays/base/array.py,sha256=b6e8LBajvzYCfvTvADudG8lE9SnOdke769YFewOjnhs,13167
33
33
  power_grid_model_ds/_core/model/arrays/base/errors.py,sha256=M62aA2pv9AlSJSvniU1IJTtRC0jvBlMYRxv2SchTdDA,475
34
34
  power_grid_model_ds/_core/model/containers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -51,31 +51,32 @@ power_grid_model_ds/_core/model/graphs/models/base.py,sha256=B1My17h5VPf9jrs4Wbx
51
51
  power_grid_model_ds/_core/model/graphs/models/rustworkx.py,sha256=jccM7MUhNqH2215mk_X8ihQ-Q8IkjjRhUk4jSruaxy8,6158
52
52
  power_grid_model_ds/_core/model/grids/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  power_grid_model_ds/_core/model/grids/_text_sources.py,sha256=3CWn0zjaUkFhrnSEIqAas52xeW0EX3EWXIXyo8XSQgw,4229
54
- power_grid_model_ds/_core/model/grids/base.py,sha256=JzM4pbDr8NwvTIe-lAjGVRGZVYWmM_3BzgWVpIJazKk,17294
54
+ power_grid_model_ds/_core/model/grids/base.py,sha256=WRdvnOqgVgC4u2bWBWWiWixkgeO9fc7gnPCPNdcpf3k,17327
55
55
  power_grid_model_ds/_core/model/grids/helpers.py,sha256=lMUEER6l5MfdgLBIesSo_KnqK_K1CyRtu1dj33q924c,4244
56
56
  power_grid_model_ds/_core/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
57
  power_grid_model_ds/_core/utils/misc.py,sha256=fPjpczUr3IZ7EnAYI2darLzN2O8NJwhxgnOx7s-vU8w,2044
58
58
  power_grid_model_ds/_core/utils/pickle.py,sha256=LGeTc7nu9RY1noOzLJzYaSHSWIgqzHy2xhmueKGuipc,1445
59
59
  power_grid_model_ds/_core/utils/zip.py,sha256=9RtJYhjlgNZOtxr4iI-CpsjT1axw5kCCqprfTjaIsiI,2197
60
60
  power_grid_model_ds/_core/visualizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- power_grid_model_ds/_core/visualizer/app.py,sha256=dnigMtdGkYquBpFDznLDogTzXR-BHPaa_scdF4GxUlw,3421
61
+ power_grid_model_ds/_core/visualizer/app.py,sha256=Syu8niHt1jTGrBOCexn5bsX6sZq0sHTFcI1bFo2Bjyk,3567
62
62
  power_grid_model_ds/_core/visualizer/parsers.py,sha256=IYvnlunzZG-hqEjbVQGnDaZ37tLiYh5EEO39njyVjws,3168
63
+ power_grid_model_ds/_core/visualizer/typing.py,sha256=3q9AU7Uz0Cp06biIWLFw3zzmfsVSu8rPEFKkIQpHr-g,197
63
64
  power_grid_model_ds/_core/visualizer/callbacks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
- power_grid_model_ds/_core/visualizer/callbacks/element_scaling.py,sha256=l8PPSqglytqBQgZ4yyNVx3wMYLF8Fcx8ku4skbGNZLM,1136
65
- power_grid_model_ds/_core/visualizer/callbacks/element_selection.py,sha256=Teaeq0atd2rD_edaW0u_N-YCnaf6MQyC8WsgnEhQczk,963
66
- power_grid_model_ds/_core/visualizer/callbacks/layout_dropdown.py,sha256=ekO2imgbMrV_R8HpCicbOSjFO2m1tjsj-zF4RHih5RA,424
67
- power_grid_model_ds/_core/visualizer/callbacks/search_form.py,sha256=fi6azBaKIgV63vLCp0wrIB5mZ3zSWn2Jhc5VdR-Om44,2098
65
+ power_grid_model_ds/_core/visualizer/callbacks/config.py,sha256=c1j30Q-dKYEKNf1fZVLcZWZ9o384k_okwfTfegQ5x8I,2268
66
+ power_grid_model_ds/_core/visualizer/callbacks/element_selection.py,sha256=ZscGQscceQOUKtAeHHQGgvWS_I7DLQ0IgphPoJN3Jgs,993
67
+ power_grid_model_ds/_core/visualizer/callbacks/header.py,sha256=dQnUNzKonMPcSpSaikIGrsM9OdZV_C2RdFuPigTVZzg,925
68
+ power_grid_model_ds/_core/visualizer/callbacks/search_form.py,sha256=KceSRKYcSAxUdfyfQ3MFbkb0GHljiWEnSk60ufjFoXg,2181
68
69
  power_grid_model_ds/_core/visualizer/layout/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
70
  power_grid_model_ds/_core/visualizer/layout/colors.py,sha256=tt-2LvkClYvQ5ozL2UCX5q63AbXaXXo7kK2yLAzeCVw,455
70
- power_grid_model_ds/_core/visualizer/layout/cytoscape_config.py,sha256=_vnncYWIRERIgwqJY8aBXUYoXYh3l6Vd6G4voN3kTVQ,1471
71
- power_grid_model_ds/_core/visualizer/layout/cytoscape_html.py,sha256=apiU1oOSrT30c2bYADUNNOGcAkG4rkqV5UtSLVWFMfU,1009
71
+ power_grid_model_ds/_core/visualizer/layout/cytoscape_html.py,sha256=EL6Z2ewCZc86NvoDQoek7MmZH_trPtRWXBcH1kfnR2Y,924
72
72
  power_grid_model_ds/_core/visualizer/layout/cytoscape_styling.py,sha256=o5Rh8uNCyt9YxODkNH76sx_wKs8aCBrCMVGCFBTtegQ,3288
73
- power_grid_model_ds/_core/visualizer/layout/header.py,sha256=el-5SlWIPeEbZZLbi3vYz9CjanTlhuChVfqkktLCHjw,1165
74
- power_grid_model_ds/_core/visualizer/layout/legenda.py,sha256=8JTrMRgaYRaSIXAEoM0b3PgX7AYvW0_fHuYg8nY4y0g,2161
75
- power_grid_model_ds/_core/visualizer/layout/search_form.py,sha256=4LPU6MjD3QEIeBEOOWBvV5-GyLMqNYWyKcUa_oWScCs,2002
73
+ power_grid_model_ds/_core/visualizer/layout/header.py,sha256=PdIXUBZgdacTc7V99tR93SFcMjUHAzWdFGVGjq7PhMw,1829
74
+ power_grid_model_ds/_core/visualizer/layout/header_config.py,sha256=5Pn3mjHMLy5Xp2k0BkNosB-St6cy_vFp4Mdz0VdkpPc,1892
75
+ power_grid_model_ds/_core/visualizer/layout/header_legenda.py,sha256=tmSIxQFW0d4ey64J_w9QwcZji3EIg7BZ7Rf8w167xb8,2086
76
+ power_grid_model_ds/_core/visualizer/layout/header_search.py,sha256=RYTQosQaAeKyOiPNR9c0ofMiY2wKmmJCPENmlkv6BZw,1726
76
77
  power_grid_model_ds/_core/visualizer/layout/selection_output.py,sha256=fuPAdG5XmTj2E0oQ8w_tp9PGbB8bJ5fguteLtnM1EDg,534
77
- power_grid_model_ds-1.4.3.dist-info/licenses/LICENSE,sha256=GpbnG1pNl-ORtSP6dmHeiZvwy36UFli6MEZy1XlmBqo,14906
78
- power_grid_model_ds-1.4.3.dist-info/METADATA,sha256=Onl3lPwfEkgCPu8t1ELqGTxx2OA-s76U62CrGV8rGWM,8873
79
- power_grid_model_ds-1.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
- power_grid_model_ds-1.4.3.dist-info/top_level.txt,sha256=nJa103Eqvm5TESYEKPFVImfLg_ugGOBznikrM-rZQZg,20
81
- power_grid_model_ds-1.4.3.dist-info/RECORD,,
78
+ power_grid_model_ds-1.4.6.dist-info/licenses/LICENSE,sha256=GpbnG1pNl-ORtSP6dmHeiZvwy36UFli6MEZy1XlmBqo,14906
79
+ power_grid_model_ds-1.4.6.dist-info/METADATA,sha256=3T58Krn7LR69SZRthqQvie7eRSuVaOLBqaPQu1hqx4s,8044
80
+ power_grid_model_ds-1.4.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
81
+ power_grid_model_ds-1.4.6.dist-info/top_level.txt,sha256=nJa103Eqvm5TESYEKPFVImfLg_ugGOBznikrM-rZQZg,20
82
+ power_grid_model_ds-1.4.6.dist-info/RECORD,,
@@ -1,37 +0,0 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- from copy import deepcopy
6
- from typing import Any
7
-
8
- from dash import Input, Output, callback
9
-
10
- from power_grid_model_ds._core.visualizer.layout.cytoscape_styling import BRANCH_WIDTH, DEFAULT_STYLESHEET, NODE_SIZE
11
-
12
-
13
- @callback(
14
- Output("cytoscape-graph", "stylesheet", allow_duplicate=True),
15
- Input("node-scale-input", "value"),
16
- Input("edge-scale-input", "value"),
17
- prevent_initial_call=True,
18
- )
19
- def scale_elements(node_scale: float, edge_scale: float) -> list[dict[str, Any]]:
20
- """Callback to scale the elements of the graph."""
21
- new_stylesheet = deepcopy(DEFAULT_STYLESHEET)
22
- edge_style = {
23
- "selector": "edge",
24
- "style": {
25
- "width": BRANCH_WIDTH * edge_scale,
26
- },
27
- }
28
- new_stylesheet.append(edge_style)
29
- node_style = {
30
- "selector": "node",
31
- "style": {
32
- "height": NODE_SIZE * node_scale,
33
- "width": NODE_SIZE * node_scale,
34
- },
35
- }
36
- new_stylesheet.append(node_style)
37
- return new_stylesheet
@@ -1,11 +0,0 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- from dash import Input, Output, callback
6
-
7
-
8
- @callback(Output("cytoscape-graph", "layout"), Input("dropdown-update-layout", "value"), prevent_initial_call=True)
9
- def update_layout(layout):
10
- """Callback to update the layout of the graph."""
11
- return {"name": layout, "animate": True}
@@ -1,54 +0,0 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- from dash import dcc, html
6
-
7
- from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
8
- from power_grid_model_ds._core.visualizer.layout.cytoscape_html import LAYOUT_OPTIONS
9
-
10
- NODE_SCALE_HTML = [
11
- html.I(className="fas fa-circle", style={"color": CYTO_COLORS["node"], "margin-right": "10px"}),
12
- dcc.Input(
13
- id="node-scale-input",
14
- type="number",
15
- value=1,
16
- min=0.1,
17
- step=0.1,
18
- style={"width": "75px"},
19
- ),
20
- html.Span(style={"margin-right": "10px"}),
21
- ]
22
-
23
- EDGE_SCALE_HTML = [
24
- html.I(className="fas fa-arrow-right-long", style={"color": CYTO_COLORS["line"], "margin-right": "10px"}),
25
- dcc.Input(
26
- id="edge-scale-input",
27
- type="number",
28
- value=1,
29
- min=0.1,
30
- step=0.1,
31
- style={"width": "75px"},
32
- ),
33
- ]
34
-
35
- SCALE_INPUTS = [
36
- html.Div(
37
- NODE_SCALE_HTML + EDGE_SCALE_HTML,
38
- style={"margin": "0 20px 0 10px"},
39
- ),
40
- ]
41
-
42
- LAYOUT_DROPDOWN_HTML = [
43
- html.Div(
44
- dcc.Dropdown(
45
- id="dropdown-update-layout",
46
- placeholder="Select layout",
47
- value="",
48
- clearable=False,
49
- options=[{"label": name.capitalize(), "value": name} for name in LAYOUT_OPTIONS],
50
- style={"width": "200px"},
51
- ),
52
- style={"margin": "0 20px 0 10px"},
53
- )
54
- ]
@@ -1,41 +0,0 @@
1
- # SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
2
- #
3
- # SPDX-License-Identifier: MPL-2.0
4
-
5
- import dash_bootstrap_components as dbc
6
- from dash import html
7
-
8
- from power_grid_model_ds._core.visualizer.layout.colors import CYTO_COLORS
9
-
10
- _MARGIN = "0 10px"
11
- _FONT_SIZE = "2.5em"
12
-
13
- NODE_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["node"]}
14
- _SUBSTATION_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["substation_node"]}
15
- _LINE_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["line"]}
16
- _LINK_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["link"]}
17
- _TRANSFORMER_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["transformer"]}
18
- _OPEN_BRANCH_ICON_STYLE = {"font-size": _FONT_SIZE, "margin": _MARGIN, "color": CYTO_COLORS["open_branch"]}
19
- LEGENDA_HTML = html.Div(
20
- [
21
- html.I(className="fas fa-circle", id="node-icon", style=NODE_ICON_STYLE),
22
- dbc.Tooltip("Node", target="node-icon", placement="bottom"),
23
- html.I(className="fas fa-diamond", id="substation-icon", style=_SUBSTATION_ICON_STYLE),
24
- dbc.Tooltip("Substation", target="substation-icon", placement="bottom"),
25
- html.I(className="fas fa-arrow-right-long", id="line-icon", style=_LINE_ICON_STYLE),
26
- dbc.Tooltip("Line", target="line-icon", placement="bottom"),
27
- html.I(className="fas fa-arrow-right-long", id="transformer-icon", style=_TRANSFORMER_ICON_STYLE),
28
- dbc.Tooltip("Transformer", target="transformer-icon", placement="bottom"),
29
- html.I(className="fas fa-arrow-right-long", id="link-icon", style=_LINK_ICON_STYLE),
30
- dbc.Tooltip("Link", target="link-icon", placement="bottom"),
31
- html.I(className="fas fa-ellipsis", id="open-branch-icon", style=_OPEN_BRANCH_ICON_STYLE),
32
- dbc.Tooltip("Open Branch", target="open-branch-icon", placement="bottom"),
33
- ],
34
- style={
35
- "display": "flex",
36
- "align-items": "center",
37
- "margin": _MARGIN,
38
- "width": "100%",
39
- "text-shadow": "0 0 5px #000",
40
- },
41
- )