flixopt 2.1.7__py3-none-any.whl → 2.1.9__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.
Potentially problematic release.
This version of flixopt might be problematic. Click here for more details.
- docs/user-guide/Mathematical Notation/Effects, Penalty & Objective.md +8 -8
- docs/user-guide/Mathematical Notation/Flow.md +3 -3
- docs/user-guide/Mathematical Notation/InvestParameters.md +3 -0
- docs/user-guide/Mathematical Notation/LinearConverter.md +3 -3
- docs/user-guide/Mathematical Notation/OnOffParameters.md +3 -0
- docs/user-guide/Mathematical Notation/Storage.md +1 -1
- flixopt/aggregation.py +33 -32
- flixopt/calculation.py +158 -58
- flixopt/components.py +673 -150
- flixopt/config.py +17 -8
- flixopt/core.py +59 -54
- flixopt/effects.py +144 -63
- flixopt/elements.py +292 -107
- flixopt/features.py +61 -58
- flixopt/flow_system.py +69 -48
- flixopt/interface.py +952 -113
- flixopt/io.py +15 -10
- flixopt/linear_converters.py +373 -81
- flixopt/network_app.py +73 -39
- flixopt/plotting.py +215 -87
- flixopt/results.py +382 -209
- flixopt/solvers.py +25 -21
- flixopt/structure.py +41 -37
- flixopt/utils.py +10 -7
- {flixopt-2.1.7.dist-info → flixopt-2.1.9.dist-info}/METADATA +46 -42
- {flixopt-2.1.7.dist-info → flixopt-2.1.9.dist-info}/RECORD +30 -28
- scripts/gen_ref_pages.py +1 -1
- {flixopt-2.1.7.dist-info → flixopt-2.1.9.dist-info}/WHEEL +0 -0
- {flixopt-2.1.7.dist-info → flixopt-2.1.9.dist-info}/licenses/LICENSE +0 -0
- {flixopt-2.1.7.dist-info → flixopt-2.1.9.dist-info}/top_level.txt +0 -0
flixopt/network_app.py
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
2
3
|
import logging
|
|
3
4
|
import socket
|
|
4
5
|
import threading
|
|
5
|
-
from typing import
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
6
7
|
|
|
7
8
|
try:
|
|
8
9
|
import dash_cytoscape as cyto
|
|
9
10
|
import dash_daq as daq
|
|
10
|
-
import networkx
|
|
11
|
+
import networkx as nx
|
|
11
12
|
from dash import Dash, Input, Output, State, callback_context, dcc, html, no_update
|
|
12
13
|
from werkzeug.serving import make_server
|
|
13
14
|
|
|
@@ -18,8 +19,10 @@ except ImportError as e:
|
|
|
18
19
|
VISUALIZATION_ERROR = str(e)
|
|
19
20
|
|
|
20
21
|
from .components import LinearConverter, Sink, Source, SourceAndSink, Storage
|
|
21
|
-
from .elements import Bus
|
|
22
|
-
|
|
22
|
+
from .elements import Bus
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
from .flow_system import FlowSystem
|
|
23
26
|
|
|
24
27
|
logger = logging.getLogger('flixopt')
|
|
25
28
|
|
|
@@ -110,8 +113,16 @@ class VisualizationConfig:
|
|
|
110
113
|
]
|
|
111
114
|
|
|
112
115
|
|
|
113
|
-
def flow_graph(flow_system: FlowSystem) ->
|
|
116
|
+
def flow_graph(flow_system: FlowSystem) -> nx.DiGraph:
|
|
114
117
|
"""Convert FlowSystem to NetworkX graph - simplified and more robust"""
|
|
118
|
+
if not DASH_CYTOSCAPE_AVAILABLE:
|
|
119
|
+
raise ImportError(
|
|
120
|
+
'Network visualization requires optional dependencies. '
|
|
121
|
+
'Install with: pip install flixopt[viz] or '
|
|
122
|
+
'pip install dash dash-cytoscape networkx werkzeug. '
|
|
123
|
+
f'Original error: {VISUALIZATION_ERROR}'
|
|
124
|
+
)
|
|
125
|
+
|
|
115
126
|
nodes = list(flow_system.components.values()) + list(flow_system.buses.values())
|
|
116
127
|
edges = list(flow_system.flows.values())
|
|
117
128
|
|
|
@@ -141,7 +152,7 @@ def flow_graph(flow_system: FlowSystem) -> networkx.DiGraph:
|
|
|
141
152
|
else:
|
|
142
153
|
return 'rectangle'
|
|
143
154
|
|
|
144
|
-
graph =
|
|
155
|
+
graph = nx.DiGraph()
|
|
145
156
|
|
|
146
157
|
# Add nodes with attributes
|
|
147
158
|
for node in nodes:
|
|
@@ -168,7 +179,7 @@ def flow_graph(flow_system: FlowSystem) -> networkx.DiGraph:
|
|
|
168
179
|
return graph
|
|
169
180
|
|
|
170
181
|
|
|
171
|
-
def make_cytoscape_elements(graph:
|
|
182
|
+
def make_cytoscape_elements(graph: nx.DiGraph) -> list[dict[str, Any]]:
|
|
172
183
|
"""Convert NetworkX graph to Cytoscape elements"""
|
|
173
184
|
elements = []
|
|
174
185
|
|
|
@@ -225,7 +236,7 @@ def create_color_picker_input(label: str, input_id: str, default_color: str):
|
|
|
225
236
|
)
|
|
226
237
|
|
|
227
238
|
|
|
228
|
-
def create_style_section(title: str, children:
|
|
239
|
+
def create_style_section(title: str, children: list):
|
|
229
240
|
"""Create a collapsible section for organizing controls"""
|
|
230
241
|
return html.Div(
|
|
231
242
|
[
|
|
@@ -378,7 +389,7 @@ def create_sidebar():
|
|
|
378
389
|
)
|
|
379
390
|
|
|
380
391
|
|
|
381
|
-
def shownetwork(graph:
|
|
392
|
+
def shownetwork(graph: nx.DiGraph):
|
|
382
393
|
"""Main function to create and run the network visualization"""
|
|
383
394
|
if not DASH_CYTOSCAPE_AVAILABLE:
|
|
384
395
|
raise ImportError(f'Required packages not available: {VISUALIZATION_ERROR}')
|
|
@@ -535,10 +546,46 @@ def shownetwork(graph: networkx.DiGraph):
|
|
|
535
546
|
|
|
536
547
|
return sidebar_style, main_style
|
|
537
548
|
|
|
549
|
+
# Combined callback to handle both color scheme changes and reset
|
|
550
|
+
@app.callback(
|
|
551
|
+
[
|
|
552
|
+
Output('bus-color-picker', 'value'),
|
|
553
|
+
Output('source-color-picker', 'value'),
|
|
554
|
+
Output('sink-color-picker', 'value'),
|
|
555
|
+
Output('storage-color-picker', 'value'),
|
|
556
|
+
Output('converter-color-picker', 'value'),
|
|
557
|
+
],
|
|
558
|
+
[Input('color-scheme-dropdown', 'value'), Input('reset-btn', 'n_clicks')],
|
|
559
|
+
)
|
|
560
|
+
def update_color_pickers(color_scheme, reset_clicks):
|
|
561
|
+
"""Update color pickers when color scheme changes or reset is clicked"""
|
|
562
|
+
ctx = callback_context
|
|
563
|
+
|
|
564
|
+
# Determine which input triggered the callback
|
|
565
|
+
if ctx.triggered:
|
|
566
|
+
trigger_id = ctx.triggered[0]['prop_id'].split('.')[0]
|
|
567
|
+
if trigger_id == 'reset-btn' and reset_clicks and reset_clicks > 0:
|
|
568
|
+
# Reset was clicked, use default colors
|
|
569
|
+
colors = VisualizationConfig.DEFAULT_COLORS
|
|
570
|
+
else:
|
|
571
|
+
# Color scheme changed
|
|
572
|
+
colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
|
|
573
|
+
else:
|
|
574
|
+
# Initial load
|
|
575
|
+
colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
|
|
576
|
+
|
|
577
|
+
return (
|
|
578
|
+
{'hex': colors['Bus']},
|
|
579
|
+
{'hex': colors['Source']},
|
|
580
|
+
{'hex': colors['Sink']},
|
|
581
|
+
{'hex': colors['Storage']},
|
|
582
|
+
{'hex': colors['Converter']},
|
|
583
|
+
)
|
|
584
|
+
|
|
585
|
+
# Updated main visualization callback - simplified logic
|
|
538
586
|
@app.callback(
|
|
539
587
|
[Output('cytoscape', 'elements'), Output('cytoscape', 'stylesheet')],
|
|
540
588
|
[
|
|
541
|
-
Input('color-scheme-dropdown', 'value'),
|
|
542
589
|
Input('bus-color-picker', 'value'),
|
|
543
590
|
Input('source-color-picker', 'value'),
|
|
544
591
|
Input('sink-color-picker', 'value'),
|
|
@@ -551,7 +598,6 @@ def shownetwork(graph: networkx.DiGraph):
|
|
|
551
598
|
[State('elements-store', 'data')],
|
|
552
599
|
)
|
|
553
600
|
def update_visualization(
|
|
554
|
-
color_scheme,
|
|
555
601
|
bus_color,
|
|
556
602
|
source_color,
|
|
557
603
|
sink_color,
|
|
@@ -562,23 +608,20 @@ def shownetwork(graph: networkx.DiGraph):
|
|
|
562
608
|
font_size,
|
|
563
609
|
stored_elements,
|
|
564
610
|
):
|
|
611
|
+
"""Update visualization based on current color picker values"""
|
|
565
612
|
if not stored_elements:
|
|
566
613
|
return no_update, no_update
|
|
567
614
|
|
|
568
|
-
#
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
}
|
|
579
|
-
else:
|
|
580
|
-
# Use preset scheme
|
|
581
|
-
colors = VisualizationConfig.COLOR_PRESETS.get(color_scheme, VisualizationConfig.DEFAULT_COLORS)
|
|
615
|
+
# Use colors from pickers (which are now synced with scheme selection)
|
|
616
|
+
default_colors = VisualizationConfig.DEFAULT_COLORS
|
|
617
|
+
colors = {
|
|
618
|
+
'Bus': bus_color.get('hex') if bus_color else default_colors['Bus'],
|
|
619
|
+
'Source': source_color.get('hex') if source_color else default_colors['Source'],
|
|
620
|
+
'Sink': sink_color.get('hex') if sink_color else default_colors['Sink'],
|
|
621
|
+
'Storage': storage_color.get('hex') if storage_color else default_colors['Storage'],
|
|
622
|
+
'Converter': converter_color.get('hex') if converter_color else default_colors['Converter'],
|
|
623
|
+
'Other': default_colors['Other'],
|
|
624
|
+
}
|
|
582
625
|
|
|
583
626
|
# Update element colors
|
|
584
627
|
updated_elements = []
|
|
@@ -681,15 +724,10 @@ def shownetwork(graph: networkx.DiGraph):
|
|
|
681
724
|
def update_layout(selected_layout):
|
|
682
725
|
return {'name': selected_layout}
|
|
683
726
|
|
|
684
|
-
# Reset callback
|
|
727
|
+
# Reset callback for non-color-picker controls
|
|
685
728
|
@app.callback(
|
|
686
729
|
[
|
|
687
730
|
Output('color-scheme-dropdown', 'value'),
|
|
688
|
-
Output('bus-color-picker', 'value'),
|
|
689
|
-
Output('source-color-picker', 'value'),
|
|
690
|
-
Output('sink-color-picker', 'value'),
|
|
691
|
-
Output('storage-color-picker', 'value'),
|
|
692
|
-
Output('converter-color-picker', 'value'),
|
|
693
731
|
Output('edge-color-picker', 'value'),
|
|
694
732
|
Output('node-size-slider', 'value'),
|
|
695
733
|
Output('font-size-slider', 'value'),
|
|
@@ -698,15 +736,11 @@ def shownetwork(graph: networkx.DiGraph):
|
|
|
698
736
|
[Input('reset-btn', 'n_clicks')],
|
|
699
737
|
)
|
|
700
738
|
def reset_controls(n_clicks):
|
|
739
|
+
"""Reset all controls to defaults (color pickers handled separately)"""
|
|
701
740
|
if n_clicks and n_clicks > 0:
|
|
702
741
|
return (
|
|
703
|
-
'Default', # color scheme
|
|
704
|
-
{'hex': '#
|
|
705
|
-
{'hex': '#F1C40F'}, # source
|
|
706
|
-
{'hex': '#F1C40F'}, # sink
|
|
707
|
-
{'hex': '#2980B9'}, # storage
|
|
708
|
-
{'hex': '#D35400'}, # converter
|
|
709
|
-
{'hex': '#808080'}, # edge
|
|
742
|
+
'Default', # color scheme (will trigger color picker updates)
|
|
743
|
+
{'hex': '#808080'}, # edge color
|
|
710
744
|
90, # node size
|
|
711
745
|
10, # font size
|
|
712
746
|
'klay', # layout
|