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
7 changes: 6 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
# Release notes

## Unversioned (2026-05-19)
## Version 0.7.2 (2026-05-20)

### Adjustments

* If coordinates have not been saved to a design file for the nodes under an `Area`, they are now placed *symmetrically* around the circle (that is, accounting for one node being the `GeoAvailability` node to be placed at the center).
* The default value for the radius of the circle for placing nodes without coordinates is now a third of the minimal distance between area coordinates defined in the `top_level` design file.
* Show investments into individual `TransmissionMode`s in the investment overview and in the information box appearing when hovering over an object.

### Enhancements

* Enabled the user to adjust the alpha value of EMGUI-objects not invested in.

## Version 0.7.1 (2026-04-24)

Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "EnergyModelsGUI"
uuid = "737a7361-d3b7-40e9-b1ac-59bee4c5ea2d"
version = "0.7.1"
version = "0.7.2"
authors = ["Jon Vegard Venås <JonVegard.Venas@sintef.no>", "Dimitri Pinel <Dimitri.Pinel@sintef.no>", "Magnus Askeland <Magnus.Askeland@sintef.no>", "Shweta Tiwari <Shweta.Tiwari@sintef.no>"]

[deps]
Expand Down
1 change: 1 addition & 0 deletions docs/generate_images.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ function create_EMI_geography_images()
coarse_coast_lines = false,
scale_tot_opex = true,
scale_tot_capex = false,
alpha = 0.5,
)

# Create examples.png image
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: 2 additions & 0 deletions docs/src/manual/simple-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ You should then get the following GUI:
The location of these files can be assigned through the `design_path` input parameter to the `GUI` function (this feature has the shortcut `ctrl+s`).
6. `reset view`: Reset the view to the optimal view based on the current system if the view has been altered (this feature has the shortcut `ctrl+r`).
7. `Expand all`: Toggle this to show/hide all components of all `Area`s.
8. `Simplified`: Toggle this to use simplified connection plotting for the current level by default; it also applies to expanded sub-levels when `Expand all` is enabled, or when `simplify_all_levels` was enabled when constructing the GUI.
9. `Alpha`: Adjust the transparency of the components not being invested in.

!!! note "Top right text areas"
The first text area (to the left) shows some tips of using the GUI by defult, but is temporarily changed upon a selection of an EMX object in which information of this object is shown.
Expand Down
28 changes: 26 additions & 2 deletions ext/EMGExt/EMGExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ using EnergyModelsBase
using EnergyModelsInvestments
using EnergyModelsGeography
using EnergyModelsGUI
using GLMakie

const TS = TimeStruct
const EMG = EnergyModelsGeography
Expand Down Expand Up @@ -83,6 +84,30 @@ function EMGUI.get_plotables(system::EMGUI.SystemGeo)
)
end

"""
EMGUI.ProcInvData(element::TransmissionMode)

Constructor for an `ProcInvData` object on a `TransmissionMode` `element`.
"""
function EMGUI.ProcInvData(element::TransmissionMode)
return EMGUI.ProcInvData(
EMGUI.get_element_label(element),
String[],
Float64[],
Observable(false),
)
end

"""
instantiate_inv_data(element::Transmission)

Instantiate the `inv_data` field for a `Transmission` by creating a vector
of `ProcInvData` for each mode.
"""
function EMGUI.instantiate_inv_data(element::Transmission)
return [EMGUI.ProcInvData(mode) for mode ∈ modes(element)]
end

############################################################################################
## From structure_utils.jl
"""
Expand Down Expand Up @@ -193,9 +218,8 @@ EMGUI._type_to_header(::Type{<:TransmissionMode}) = :element
EMGUI.get_inv_objs(obj::Transmission)

Get the objects for which investment information should be stored for a given `Transmission`.
This includes obj itself but also its modes.
"""
EMGUI.get_inv_objs(obj::Transmission) = [obj, modes(obj)...]
EMGUI.get_inv_objs(obj::Transmission) = modes(obj)

############################################################################################
## From info_axis_utils.jl
Expand Down
80 changes: 58 additions & 22 deletions src/datastructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,31 @@ Type for storing processed investment data.

# Fields

- **`id::String`** is the identifier for structures that have `TransmissionModes`
(default is thus an empty string).
- **`inv_times::Vector{String}`** is a vector of formatted strings for added investments.
- **`capex::Vector{Number}`** contains the capex of all times with added investments.
- **`invested::Bool`** indicates if the element has been invested in.
- **`capex::Vector{Float64}`** contains the capex of all times with added investments.
- **`invested::Observable{Bool}`** indicates if the element has been invested in.
"""
struct ProcInvData{T<:Number}
mutable struct ProcInvData
id::String
inv_times::Vector{String}
capex::Vector{T}
invested::Bool
capex::Vector{Float64}
invested::Observable{Bool}
end
function ProcInvData()
return ProcInvData(String[], Vector{Number}(), false)
function ProcInvData(::Any)
return ProcInvData("", String[], Float64[], Observable(false))
end

"""
instantiate_inv_data(element::AbstractElement)

Instantiate the `inv_data` field for an `AbstractElement` by creating a vector of `ProcInvData`.
This function can be specialized for different types of `AbstractElement` to handle specific cases,
such as `Transmission` where multiple modes may require separate `ProcInvData` instances.
"""
function instantiate_inv_data(element::AbstractElement)
return [ProcInvData(element)]
end

"""
Expand All @@ -136,11 +150,13 @@ energy system designs in Julia.
for changes and represented as a Symbol.
- **`file::String`** is the filename or path associated with the `EnergySystemDesign`.
- **`visible::Observable{Bool}`** indicates whether the system is visible, observed for changes.
- **`inv_data::ProcInvData`** stores processed investment data.
- **`inv_data::Vector{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.
- **`alpha::Observable{Float32}`** is the alpha value for the system's connections, observed for changes.
The alpha value is used to toggle the visibility of the nodes when investments have occurred.
"""
mutable struct EnergySystemDesign <: AbstractGUIObj
system::AbstractSystem
Expand All @@ -155,9 +171,10 @@ mutable struct EnergySystemDesign <: AbstractGUIObj
wall::Observable{Symbol}
file::String
visible::Observable{Bool}
inv_data::ProcInvData
inv_data::Vector{ProcInvData}
plots::Vector{Makie.AbstractPlot}
simplified::Observable{Bool}
alpha::Observable{Float32}
end
function EnergySystemDesign(
system::AbstractSystem,
Expand Down Expand Up @@ -186,9 +203,10 @@ function EnergySystemDesign(
wall,
file,
visible,
ProcInvData(),
instantiate_inv_data(get_element(system)),
Makie.AbstractPlot[],
Observable(false),
Observable(1.0f0),
)
end

Expand All @@ -207,21 +225,25 @@ Mutable type for providing a flexible data structure for connections between
- **`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.
- **`inv_data::ProcInvData`** stores processed investment data.
- **`inv_data::Vector{ProcInvData}`** stores processed investment data.
- **`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.
- **`alpha::Vector{Observable{Float32}}`** is the alpha value of the connection, observed for changes.
For each line it controls the alpha value, which is used to toggle the visibility of the line when
the connection has not been invested in.
"""
mutable struct Connection <: AbstractGUIObj
from::EnergySystemDesign
to::EnergySystemDesign
connection::AbstractElement
parent::EnergySystemDesign
colors::Vector{RGBA{Float32}}
inv_data::ProcInvData
inv_data::Vector{ProcInvData}
regular_plots::Vector{Makie.AbstractPlot}
simplified_plots::Vector{Makie.AbstractPlot}
alpha::Vector{Observable{Float32}}
end
function Connection(
from::EnergySystemDesign,
Expand All @@ -237,9 +259,10 @@ function Connection(
connection,
parent,
colors,
ProcInvData(),
instantiate_inv_data(connection),
Makie.AbstractPlot[],
Makie.AbstractPlot[],
[Observable(1.0f0) for _ ∈ 1:length(colors)],
)
end

Expand Down Expand Up @@ -280,6 +303,8 @@ The main type for the realization of the GUI.
gui.axes[:results] object.
- **`toggles::Dict{Symbol,Makie.Toggle}`** is a dictionary of the GLMakie toggles linked
to the gui.axes[:results] object.
- **`sliders::Dict{Symbol,Makie.Slider}`** is a dictionary of the GLMakie sliders linked
to the gui.axes[:results] object.
- **`root_design::EnergySystemDesign`** is the data structure used for the root topology.
- **`design::EnergySystemDesign`** is the data structure used for visualizing the topology.
- **`model::Union{Model, Dict}`** contains the optimization results.
Expand All @@ -293,6 +318,7 @@ mutable struct GUI
buttons::Dict{Symbol,Makie.Button}
menus::Dict{Symbol,Makie.Menu}
toggles::Dict{Symbol,Makie.Toggle}
sliders::Dict{Symbol,Makie.Slider}
root_design::EnergySystemDesign
design::EnergySystemDesign
model::Union{Model,Dict}
Expand Down Expand Up @@ -629,30 +655,26 @@ get_plots(conn::Connection, simplified::Bool) =

"""
get_inv_times(data::ProcInvData)
get_inv_times(design::AbstractGUIObj)

Returns the `inv_times` field of a `ProcInvData`/`AbstractGUIObj` object `data`.
Returns the `inv_times` field of a `ProcInvData` object `data`.
"""
get_inv_times(data::ProcInvData) = data.inv_times
get_inv_times(design::AbstractGUIObj) = get_inv_times(get_inv_data(design))

"""
get_capex(data::ProcInvData)
get_capex(design::AbstractGUIObj)

Returns the `capex` of the investments of a `ProcInvData`/`AbstractGUIObj` object `data`.
Returns the `capex` of the investments of a `ProcInvData` object `data`.
"""
get_capex(data::ProcInvData) = data.capex
get_capex(design::AbstractGUIObj) = get_capex(get_inv_data(design))

"""
has_invested(data::ProcInvData)
has_invested(data::AbstractGUIObj)
has_invested(data::EnergySystemDesign)

Returns a boolean indicator if investment has occured.
Returns an observable of the boolean indicator for if investment has occured.
"""
has_invested(data::ProcInvData) = data.invested
has_invested(design::AbstractGUIObj) = has_invested(get_inv_data(design))
has_invested(design::EnergySystemDesign) = has_invested(get_inv_data(design)[1])
Comment thread
Zetison marked this conversation as resolved.

Comment thread
Zetison marked this conversation as resolved.
"""
get_inv_data(obj::AbstractGUIObj)
Expand All @@ -675,6 +697,13 @@ Returns the `parent` field of a `AbstractGUIObj` `obj`.
"""
get_parent(obj::AbstractGUIObj) = obj.parent

"""
get_alpha(obj::AbstractGUIObj)

Returns the `alpha` field of a `AbstractGUIObj` `obj`.
"""
get_alpha(obj::AbstractGUIObj) = obj.alpha

"""
get_fig(gui::GUI)

Expand Down Expand Up @@ -745,6 +774,13 @@ Returns the `toggle` with name `toggle_name` of a `GUI` `gui`.
"""
get_toggle(gui::GUI, toggle_name::Symbol) = gui.toggles[toggle_name]

"""
get_slider(gui::GUI, slider_name::Symbol)

Returns the `slider` with name `slider_name` of a `GUI` `gui`.
"""
get_slider(gui::GUI, slider_name::Symbol) = gui.sliders[slider_name]

"""
get_root_design(gui::GUI)

Expand Down
32 changes: 27 additions & 5 deletions src/setup_GUI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ to the old EnergyModelsX `case` dictionary.
plotting for all hierarchical levels.
- **`map_boundary_file::String=""`** is the path to a .geojson file containing
geographical boundary data for plotting to be used instead of the default coastlines.
- **`alpha::Number=1.0`** is the alpha value for non-invested connections
and nodes in the topology design.

!!! 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 @@ -87,6 +89,7 @@ function GUI(
simplified_connection_plotting::Bool = false,
simplify_all_levels::Bool = false,
map_boundary_file::String = "",
alpha::Number = 1.0,
)
# Generate the system topology:
@info raw"Setting up the topology design structure"
Expand Down Expand Up @@ -134,6 +137,7 @@ function GUI(
:simplify_all_levels => simplify_all_levels,
:marker_to_box_ratio => 0.4, # Ratio between marker size and `Node` box size
:map_boundary_file => map_boundary_file,
:alpha => Observable(Float32(alpha)),
:autolimits => Dict(
:results_op => true,
:results_sc => true,
Expand All @@ -148,7 +152,7 @@ function GUI(
),
)

# gobal variables for legends
# global variables for legends
vars[:color_box_padding_px] = 25 # Padding around the legends
vars[:color_boxes_width_px] = 20 # Width of the rectangles for the colors in legends
vars[:color_boxes_height_px] = vars[:fontsize] # Height of the rectangles for the colors in legends
Expand Down Expand Up @@ -213,7 +217,8 @@ function GUI(
vars[:ctrl_is_pressed] = Ref(false)

# Construct the makie figure and its objects
fig, buttons, menus, toggles, axes, legends = create_makie_objects(vars, root_design)
fig, buttons, menus, toggles, sliders, axes, legends =
create_makie_objects(vars, root_design)

# Construct screen object
manifest = Pkg.Operations.Context().env.manifest
Expand All @@ -228,7 +233,8 @@ function GUI(

## Create the main structure for the EnergyModelsGUI
gui::GUI = GUI(
fig, screen, axes, legends, buttons, menus, toggles, root_design, design,
fig, screen, axes, legends, buttons, menus, toggles, sliders, root_design,
design,
transfer_model(model, get_system(root_design)), vars,
)

Expand Down Expand Up @@ -529,9 +535,22 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
gridlayout_taskbar[1, 10];
active = vars[:simplified_connection_plotting],
)
Makie.Label(
gridlayout_taskbar[1, 11],
"Alpha:";
halign = :right,
fontsize = vars[:fontsize],
justification = :right,
)
alpha_slider = Makie.Slider(
gridlayout_taskbar[1, 12];
range = 0:0.01:1,
startvalue = vars[:alpha][],
width = 100 * vars[:fontsize] / 12,
)

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

# Add buttons related to the ax_results object (where the optimization results are plotted)
Makie.Label(
Expand Down Expand Up @@ -695,6 +714,9 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
toggles::Dict{Symbol,Makie.Toggle} =
Dict(:expand_all => expand_all_toggle, :simplified => simplified_toggle)

# Collect all sliders into a dictionary
sliders::Dict{Symbol,Makie.Slider} = Dict(:alpha => alpha_slider)

# Collect all axes into a dictionary
axes::Dict{Symbol,Makie.Block} = Dict(
:topo => ax, :results => ax_results, :info => ax_info, :summary => ax_summary,
Expand All @@ -710,5 +732,5 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
depth_shift = -1.0f0,
)

return fig, buttons, menus, toggles, axes, legends
return fig, buttons, menus, toggles, sliders, axes, legends
end
Loading
Loading