Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
# Release notes

## Unversioned updates
## Version 0.5.18 (2025-11-24)

### Enhancements

* Added the option `pre_plot_sub_components` to the `GUI`-constructor to skip preplotting hidden sub components of an area (the option is by default `true`). The components of an `Area` are then plotted on demand (on the `open` functionality). This greatly enhances performance for large cases.
* Improved general performance.
* Added two new options to the `GUI` constructor: `simplified_connection_plotting` (default `false`) for controlling connection visualization detail, and `simplify_all_levels` (default `false`) for applying simplification across hierarchical levels.

### Adjustments

* Adjusted the calculation of `Connection` plots.
* Added the field `visible` to `EnergySystemDesign` and `Connection` on which plots can directly rely on for visibility
* Adjust behaviour of `Base.show` on the types `EnergySystemDesign`, `Connection` and `AbstractSystem` to correspond to `Base.show` of their corresponding `AbstractElement`.
* Change tests of toggling of colors to be based on a new case having more transmission modes (the case in the new `test/EMI_geography_2.jl` file).
* Make the distance between two way connection linearly dependent on `Δh` instead of a fixed width based on `gui.vars[:two_way_sep_px]`.
* Make the markersize (arrow heads for connections) linearly dependent on `Δh` instead of a fixed size based on `gui.vars[:markersize]`

## Version 0.5.17 (2025-11-19)

Expand Down
14 changes: 6 additions & 8 deletions docs/generate_images.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import EnergyModelsGUI:
get_component,
get_selected_systems,
get_name,
get_toggle,
pick_component!,
update!,
toggle_selection_color!,
select_data!
Expand Down Expand Up @@ -77,7 +79,7 @@ function create_EMI_geography_images()
solution_summary(m)

# Set folder where visualization info is saved and retrieved
design_path = joinpath(@__DIR__, "design", "EMI", "geography")
design_path = joinpath(docsdir, "design", "EMI", "geography")

# Run the GUI
gui = GUI(
Expand All @@ -90,7 +92,7 @@ function create_EMI_geography_images()
)

# Create examples.png image
path_to_results = joinpath(@__DIR__, "src", "figures")
path_to_results = joinpath(docsdir, "src", "figures")
get_vars(gui)[:path_to_results] = path_to_results
get_menu(gui, :axes).selection[] = "All"
get_menu(gui, :export_type).selection[] = "png"
Expand All @@ -105,9 +107,8 @@ function create_EMI_geography_images()

# Create EMI_geography.png image
oslo_area = get_component(get_root_design(gui), 1)
push!(get_selected_systems(gui), oslo_area) # Manually add to :selected_systems
pick_component!(gui, oslo_area, :topo)
update!(gui)
toggle_selection_color!(gui, oslo_area, true)
select_data!(gui, "area_exchange")
notify(export_button.clicks)
mv(
Expand All @@ -119,11 +120,8 @@ function create_EMI_geography_images()
# Create EMI_geography_Oslo.png image
notify(open_button.clicks)
sub_component = get_component(oslo_area, 5) # fetch node id 5 in Oslo area
selected_systems = get_selected_systems(gui)
empty!(selected_systems)
push!(selected_systems, sub_component) # Manually add to :selected_systems
pick_component!(gui, sub_component, :topo)
update!(gui)
toggle_selection_color!(gui, sub_component, true)
select_data!(gui, "cap_add")
notify(export_button.clicks)
mv(
Expand Down
8 changes: 5 additions & 3 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@ const EMB = EnergyModelsBase
const EMGUI = EnergyModelsGUI

# Copy the NEWS.md file
news = "docs/src/manual/NEWS.md"
pkg_dir = pkgdir(EnergyModelsGUI)
docsdir = joinpath(pkg_dir, "docs")
news = joinpath(docsdir, "src", "manual", "NEWS.md")
if isfile(news)
rm(news)
end
cp("NEWS.md", news)
cp(joinpath(pkg_dir, "NEWS.md"), news)

ENV["EMX_TEST"] = true # Set flag for example scripts to check if they are run as part CI
include("generate_images.jl")
include(joinpath(docsdir, "generate_images.jl"))

DocMeta.setdocmeta!(
EnergyModelsGUI, :DocTestSetup, :(using EnergyModelsGUI); recursive = true,
Expand Down
Binary file modified docs/src/figures/EMI_geography.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/src/figures/EMI_geography_Oslo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion ext/EMGExt/EMGExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ Get the line style for an Transmission `transmission` based on its properties.
"""
function EMGUI.get_linestyle(gui::GUI, transmission::Transmission)
return [
EMI.has_investment(m) ? EMGUI.get_var(gui, :investment_lineStyle) : :solid for
EMI.has_investment(m) ? EMGUI.get_var(gui, :investment_linestyle) : :solid for
m ∈ modes(transmission)
]
end
Expand Down
110 changes: 85 additions & 25 deletions src/datastructures.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
AbstractGUIObj

Supertype for EnergyModelsGUI objects representing `Node`s/`Link`s/`Area`s/`Transmission`s.
Supertype for `EnergyModelsGUI` objects representing `Node`s/`Link`s/`Area`s/`Transmission`s.
"""
abstract type AbstractGUIObj end

Expand All @@ -15,14 +15,14 @@ struct NothingDesign <: AbstractGUIObj end
"""
AbstractSystem

Supertype for EnergyModelsGUI objects representing a sub system of a Case.
Supertype for `EnergyModelsGUI` objects representing a sub system of a `Case`.
"""
abstract type AbstractSystem <: AbstractCase end

"""
NothingElement <: AbstractElement

Type for representing an empty Element (the "nothing" element).
Type for representing an empty `AbstractElement` (the "nothing" element).
"""
struct NothingElement <: AbstractElement end

Expand Down Expand Up @@ -139,6 +139,8 @@ energy system designs in Julia.
- **`inv_data::ProcInvData`** stores processed investment data.
- **`plots::Vector{Makie.AbstractPlot}`** is a vector with all Makie object associated with
this object.
- **`simplified::Observable{Bool}`** indicates whether the system uses a simplified
representation of its plotted connections, observed for changes.
"""
mutable struct EnergySystemDesign <: AbstractGUIObj
system::AbstractSystem
Expand All @@ -155,6 +157,7 @@ mutable struct EnergySystemDesign <: AbstractGUIObj
visible::Observable{Bool}
inv_data::ProcInvData
plots::Vector{Makie.AbstractPlot}
simplified::Observable{Bool}
end
function EnergySystemDesign(
system::AbstractSystem,
Expand Down Expand Up @@ -184,7 +187,8 @@ function EnergySystemDesign(
file,
visible,
ProcInvData(),
Any[],
Makie.AbstractPlot[],
Observable(false),
)
end

Expand All @@ -201,30 +205,42 @@ Mutable type for providing a flexible data structure for connections between
- **`to::EnergySystemDesign`** is the `EnergySystemDesign` to which the connection is
linked to.
- **`connection::AbstractElement`** is the EMX connection structure.
- **`parent::EnergySystemDesign`** is the parent EnergySystemDesign of the connection.
- **`colors::Vector{RGBA{Float32}}`** is the associated colors of the connection.
- **`visible::Observable{Bool}`** indicates whether the system is visible, observed for changes.
- **`inv_data::ProcInvData`** stores processed investment data.
- **`plots::Vector{Makie.AbstractPlot}`** is a vector with all Makie object associated with
this object.
- **`regular_plots::Vector{Makie.AbstractPlot}`** is a vector with
all regular plots associated with the connection.
- **`simplified_plots::Vector{Makie.AbstractPlot}`** is a vector with
all simplified plots associated with the connection.
"""
mutable struct Connection <: AbstractGUIObj
from::EnergySystemDesign
to::EnergySystemDesign
connection::AbstractElement
parent::EnergySystemDesign
colors::Vector{RGBA{Float32}}
visible::Observable{Bool}
inv_data::ProcInvData
plots::Vector{Makie.AbstractPlot}
regular_plots::Vector{Makie.AbstractPlot}
simplified_plots::Vector{Makie.AbstractPlot}
end
function Connection(
from::EnergySystemDesign,
to::EnergySystemDesign,
connection::AbstractElement,
parent::EnergySystemDesign,
id_to_color_map::Dict{Any,Any},
visible::Observable{Bool},
)
colors::Vector{RGBA{Float32}} = get_resource_colors(connection, id_to_color_map)
return Connection(from, to, connection, colors, visible, ProcInvData(), Any[])
return Connection(
from,
to,
connection,
parent,
colors,
ProcInvData(),
Makie.AbstractPlot[],
Makie.AbstractPlot[],
)
end

"""
Expand Down Expand Up @@ -446,13 +462,6 @@ Returns the `system` field of a `EnergySystemDesign` `design`.
"""
get_system(design::EnergySystemDesign) = design.system

"""
get_parent(design::EnergySystemDesign)

Returns the `parent` field of a `EnergySystemDesign` `design`.
"""
get_parent(design::EnergySystemDesign) = design.parent

"""
get_element(design::EnergySystemDesign)

Expand Down Expand Up @@ -535,10 +544,24 @@ EMB.get_time_struct(design::EnergySystemDesign) = EMB.get_time_struct(get_system
"""
get_ref_element(design::EnergySystemDesign)

Returns the `ref_element` field of a `EnergySystemDesign` `design`.
Returns the `ref_element` field in the `system` field of a `EnergySystemDesign` `design`.
"""
get_ref_element(design::EnergySystemDesign) = get_ref_element(get_system(design))

"""
get_plots(design::EnergySystemDesign)

Returns the `plots` field of a `EnergySystemDesign` `design`.
"""
get_plots(design::EnergySystemDesign) = design.plots

"""
get_simplified(design::EnergySystemDesign)

Returns the `simplified` field of a `EnergySystemDesign` `design`.
"""
get_simplified(design::EnergySystemDesign) = design.simplified

"""
get_from(conn::Connection)

Expand Down Expand Up @@ -567,6 +590,43 @@ Returns the `colors` field of a `Connection` `conn`.
"""
get_colors(conn::Connection) = conn.colors

"""
get_regular_plots(conn::Connection)

Returns the `regular_plots` field of a `Connection` `conn`.
"""
get_regular_plots(conn::Connection) = conn.regular_plots

"""
get_simplified_plots(conn::Connection)

Returns the `simplified_plots` field of a `Connection` `conn`.
"""
get_simplified_plots(conn::Connection) = conn.simplified_plots

"""
get_simplified(conn::Connection)

Returns the `simplified` field of the parent `EnergySystemDesign` of a `Connection` `conn`.
"""
get_simplified(conn::Connection) = get_simplified(get_parent(conn))

"""
get_plots(conn::Connection)

Returns the active `plots` field of a `Connection` `conn`.
"""
get_plots(conn::Connection) =
get_simplified(conn)[] ? get_simplified_plots(conn) : get_regular_plots(conn)

"""
get_plots(conn::Connection, simplified::Bool)

Returns the `plots` field of a `Connection` `conn` based on the `simplified` flag.
"""
get_plots(conn::Connection, simplified::Bool) =
simplified ? get_simplified_plots(conn) : get_regular_plots(conn)

"""
get_inv_times(data::ProcInvData)
get_inv_times(design::AbstractGUIObj)
Expand Down Expand Up @@ -602,18 +662,18 @@ Returns the `inv_data` field of a `AbstractGUIObj` `obj`.
get_inv_data(obj::AbstractGUIObj) = obj.inv_data

"""
get_plots(obj::AbstractGUIObj)
get_visible(obj::AbstractGUIObj)

Returns the `plots` field of a `AbstractGUIObj` `obj`.
Returns the `visible` field of a `AbstractGUIObj` `obj`.
"""
get_plots(obj::AbstractGUIObj) = obj.plots
get_visible(obj::AbstractGUIObj) = obj.visible

"""
get_visible(obj::AbstractGUIObj)
get_parent(obj::AbstractGUIObj)

Returns the `visible` field of a `AbstractGUIObj` `obj`.
Returns the `parent` field of a `AbstractGUIObj` `obj`.
"""
get_visible(obj::AbstractGUIObj) = obj.visible
get_parent(obj::AbstractGUIObj) = obj.parent

"""
get_fig(gui::GUI)
Expand Down
30 changes: 25 additions & 5 deletions src/setup_GUI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ to the old EnergyModelsX `case` dictionary.
sub-components of areas in the topology design. Setting this to `false` greatly
enhances performance for large cases, as the components of an `Area` are then
plotted on demand (on the `open` functionality).
- **`simplified_connection_plotting::Bool=false`** toggles whether or not to use a
simplified representation of the connections with a single line for each connection
(instead of multiple lines for multiple transmission modes) in the topology design.
- **`simplify_all_levels::Bool=false`** toggles whether or not to use simplified connection
plotting for all hierarchical levels.

!!! warning "Reading model results from CSV-files"
Reading model results from a directory (*i.e.*, `model::String` implying that the results
Expand Down Expand Up @@ -77,6 +82,8 @@ function GUI(
enable_data_inspector::Bool = true,
use_geomakie::Bool = true,
pre_plot_sub_components::Bool = true,
simplified_connection_plotting::Bool = false,
simplify_all_levels::Bool = false,
)
# Generate the system topology:
@info raw"Setting up the topology design structure"
Expand All @@ -98,7 +105,6 @@ function GUI(
:Δh => Observable(0.05f0), # Sidelength of main box
:coarse_coast_lines => coarse_coast_lines,
:Δh_px => 50, # Pixel size of a box for nodes
:markersize => 15, # Marker size for arrows in connections
:boundary_add => 0.2f0, # Relative to the xlim/ylim-dimensions, expand the axis
:line_sep_px => 2, # Separation (in px) between lines for connections
:connection_linewidth => 2, # line width of connection lines
Expand All @@ -107,9 +113,8 @@ function GUI(
:linewidth => 1.2, # Width of the line around boxes
:parent_scaling => 1.1, # Scale for enlargement of boxes around main boxes for nodes for parent systems
:icon_scale => 0.9f0, # scale icons w.r.t. the surrounding box in fraction of Δh
:two_way_sep_px => 10, # No pixels between set of lines for nodes having connections both ways
:selection_color => GREEN2, # Colors for box boundaries when selection objects
:investment_lineStyle => Linestyle([1.0, 1.5, 2.0, 2.5] .* 5), # linestyle for investment connections and box boundaries for nodes
:investment_linestyle => Linestyle([1.0, 1.5, 2.0, 2.5] .* 5), # linestyle for investment connections and box boundaries for nodes
:path_to_results => path_to_results, # Path to the location where axes[:results] can be exported
:plotted_data => [],
:periods_labels => periods_labels,
Expand All @@ -122,6 +127,9 @@ function GUI(
:tol => tol,
:use_geomakie => use_geomakie,
:pre_plot_sub_components => pre_plot_sub_components,
:simplified_connection_plotting => simplified_connection_plotting,
:simplify_all_levels => simplify_all_levels,
:marker_to_box_ratio => 0.4, # Ratio between marker size and `Node` box size
:autolimits => Dict(
:results_op => true,
:results_sc => true,
Expand Down Expand Up @@ -501,9 +509,20 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
justification = :right,
)
expand_all_toggle = Makie.Toggle(gridlayout_taskbar[1, 8]; active = vars[:expand_all])
Makie.Label(
gridlayout_taskbar[1, 9],
"Simplified:";
halign = :right,
fontsize = vars[:fontsize],
justification = :right,
)
simplified_toggle = Makie.Toggle(
gridlayout_taskbar[1, 10];
active = vars[:simplified_connection_plotting],
)

# Add the following to add flexibility
Makie.Label(gridlayout_taskbar[1, 9], " "; tellwidth = false)
Makie.Label(gridlayout_taskbar[1, 11], " "; tellwidth = false)

# Add buttons related to the ax_results object (where the optimization results are plotted)
Makie.Label(
Expand Down Expand Up @@ -664,7 +683,8 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
)

# Collect all toggles into a dictionary
toggles::Dict{Symbol,Makie.Toggle} = Dict(:expand_all => expand_all_toggle)
toggles::Dict{Symbol,Makie.Toggle} =
Dict(:expand_all => expand_all_toggle, :simplified => simplified_toggle)

# Collect all axes into a dictionary
axes::Dict{Symbol,Makie.Block} = Dict(
Expand Down
Loading
Loading