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
14 changes: 14 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Release notes

## Unversioned updates

### 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.

### 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).

## Version 0.5.17 (2025-11-19)

### Bugfix
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.5.17"
version = "0.5.18"
authors = ["Jon Vegard Venås <JonVegard.Venas@sintef.no>", "Magnus Askeland <Magnus.Askeland@sintef.no>", "Shweta Tiwari <Shweta.Tiwari@sintef.no>"]

[deps]
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.
1 change: 1 addition & 0 deletions examples/EMI_geography.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,5 @@ gui = GUI(
coarse_coast_lines = false,
scale_tot_opex = true,
scale_tot_capex = false,
pre_plot_sub_components = false,
)
2 changes: 0 additions & 2 deletions examples/generate_examples.jl
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,7 @@ technologies.
The example is partly based on the provided example `network.jl` in `EnergyModelsGeography`.
It will be repalced in the near future with a simplified example.
"""

function generate_example_data_geo()
@debug "Generate case data"
@info "Generate data coded dummy model for now (Investment Model)"

# Retrieve the products
Expand Down
11 changes: 2 additions & 9 deletions ext/EMGExt/EMGExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@ using TimeStruct
using EnergyModelsBase
using EnergyModelsInvestments
using EnergyModelsGeography

# Use GLMakie to get the GridLayout type
using GLMakie

using EnergyModelsGUI

using DataFrames

const TS = TimeStruct
const EMG = EnergyModelsGeography
const EMB = EnergyModelsBase
Expand All @@ -38,7 +32,7 @@ EMG.get_transmissions(system::EMGUI.SystemGeo) = EMGUI.get_connections(system)
Get all transmission modes of a `SystemGeo` `system`.
"""
function get_modes(system::EMGUI.SystemGeo)
transmission_modes = Vector{TransmissionMode}()
transmission_modes = TransmissionMode[]
for t ∈ get_transmissions(system)
append!(transmission_modes, modes(t))
end
Expand Down Expand Up @@ -70,15 +64,14 @@ Initialize a `SystemGeo` from a `Case`.
"""
function EMGUI.SystemGeo(case::Case)
areas = get_areas(case)
ref_element = areas[1]
return EMGUI.SystemGeo(
get_time_struct(case),
get_products(case),
get_elements_vec(case),
areas,
get_transmissions(case),
EMGUI.NothingElement(),
ref_element,
areas[1],
)
end

Expand Down
41 changes: 28 additions & 13 deletions src/datastructures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,10 @@ energy system designs in Julia.
- **`wall::Observable{Symbol}`** represents an aspect of the system's state, observed
for changes and represented as a Symbol.
- **`file::String`** is the filename or path associated with the `EnergySystemDesign`.
- **`plots::Vector{Any}`** is a vector with all Makie object associated with this object.
The value does not have to be provided.
- **`invest_data::ProcInvData`** stores processed investment data.
- **`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.
"""
mutable struct EnergySystemDesign <: AbstractGUIObj
system::AbstractSystem
Expand All @@ -151,8 +152,9 @@ mutable struct EnergySystemDesign <: AbstractGUIObj
color::Observable{RGBA{Float32}}
wall::Observable{Symbol}
file::String
visible::Observable{Bool}
inv_data::ProcInvData
plots::Vector{Any}
plots::Vector{Makie.AbstractPlot}
end
function EnergySystemDesign(
system::AbstractSystem,
Expand All @@ -166,6 +168,7 @@ function EnergySystemDesign(
color::Observable{RGBA{Float32}},
wall::Observable{Symbol},
file::String,
visible::Observable{Bool},
)
return EnergySystemDesign(
system,
Expand All @@ -179,6 +182,7 @@ function EnergySystemDesign(
color,
wall,
file,
visible,
ProcInvData(),
Any[],
)
Expand All @@ -198,25 +202,29 @@ Mutable type for providing a flexible data structure for connections between
linked to.
- **`connection::AbstractElement`** is the EMX connection structure.
- **`colors::Vector{RGBA{Float32}}`** is the associated colors of the connection.
- **`plots::Vector{Any}`** is a vector with all Makie object associated with this object.
- **`invest_data::ProcInvData`** stores processed investment data.
- **`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.
"""
mutable struct Connection <: AbstractGUIObj
from::EnergySystemDesign
to::EnergySystemDesign
connection::AbstractElement
colors::Vector{RGBA{Float32}}
visible::Observable{Bool}
inv_data::ProcInvData
plots::Vector{Any}
plots::Vector{Makie.AbstractPlot}
end
function Connection(
from::EnergySystemDesign,
to::EnergySystemDesign,
connection::AbstractElement,
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, ProcInvData(), Any[])
return Connection(from, to, connection, colors, visible, ProcInvData(), Any[])
end

"""
Expand Down Expand Up @@ -308,10 +316,10 @@ const YELLOW = RGBA{Float32}(1.0, 1.0, 0.0, 1.0)
const MAGENTA = RGBA{Float32}(1.0, 0.0, 1.0, 1.0)
const CYAN = RGBA{Float32}(0.0, 1.0, 1.0, 1.0)

Base.show(io::IO, obj::AbstractGUIObj) = dump(io, obj; maxdepth = 1)
Base.show(io::IO, obj::AbstractGUIObj) = Base.show(io, get_element(obj))
Base.show(io::IO, ::NothingDesign) = print(io, "NothingDesign()")
Base.show(io::IO, obj::ProcInvData) = dump(io, obj; maxdepth = 1)
Base.show(io::IO, system::AbstractSystem) = dump(io, system; maxdepth = 1)
Base.show(io::IO, system::AbstractSystem) = Base.show(io, get_element(system))
Base.show(io::IO, gui::GUI) = dump(io, gui; maxdepth = 1)
Base.show(io::IO, ::NothingElement) = print(io, "top_level")

Expand Down Expand Up @@ -418,11 +426,11 @@ Returns the nodes of a `AbstractSystem` `system`.
EMB.get_nodes(system::AbstractSystem) = get_children(system)

"""
get_element(system::System)
get_element(system::AbstractSystem)

Returns the `element` assosiated of a `System` `system`.
Returns the `element` assosiated of a `AbstractSystem` `system`.
"""
get_element(system::System) = get_parent(system)
get_element(system::AbstractSystem) = get_parent(system)

"""
get_plotables(system::System)
Expand Down Expand Up @@ -600,6 +608,13 @@ Returns the `plots` field of a `AbstractGUIObj` `obj`.
"""
get_plots(obj::AbstractGUIObj) = obj.plots

"""
get_visible(obj::AbstractGUIObj)

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

"""
get_fig(gui::GUI)

Expand Down
91 changes: 53 additions & 38 deletions src/setup_GUI.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ to the old EnergyModelsX `case` dictionary.
hovering objects to show information.
- **`use_geomakie::Bool=true`** toggles the use of GeoMakie for plotting geographical
designs when the `case` contains geographical information.
- **`pre_plot_sub_components::Bool=true`** toggles whether or not to pre-plot all
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).

!!! 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 @@ -72,6 +76,7 @@ function GUI(
tol::Float64 = 1e-8,
enable_data_inspector::Bool = true,
use_geomakie::Bool = true,
pre_plot_sub_components::Bool = true,
)
# Generate the system topology:
@info raw"Setting up the topology design structure"
Expand All @@ -82,6 +87,11 @@ function GUI(
@info raw"Setting up the GUI"
design::EnergySystemDesign = root_design # variable to store current system (inkluding sub systems)

if expand_all && !pre_plot_sub_components
expand_all = false
@warn "Incompatible EMGUI settings: `expand_all` is set to true but " *
"`pre_plot_sub_components` is set to false. Setting `expand_all` to false."
end
# Set variables
vars::Dict{Symbol,Any} = Dict(
:title => Observable("top_level"),
Expand Down Expand Up @@ -111,6 +121,7 @@ function GUI(
:colormap => colormap,
:tol => tol,
:use_geomakie => use_geomakie,
:pre_plot_sub_components => pre_plot_sub_components,
:autolimits => Dict(
:results_op => true,
:results_sc => true,
Expand All @@ -137,7 +148,7 @@ function GUI(
vars[:path_to_descriptive_names] = path_to_descriptive_names
vars[:descriptive_names_dict] = descriptive_names_dict

vars[:plot_widths] = plot_widths
vars[:plot_widths] = Vec{2,Int64}(plot_widths)
vars[:hide_topo_ax_decorations] = hide_topo_ax_decorations
vars[:expand_all] = expand_all

Expand All @@ -149,30 +160,42 @@ function GUI(

# Create iterables for plotting objects in layers (z-direction) such that nodes are
# neatly placed on top of each other and lines are beneath nodes
vars[:z_translate_lines] = 10.0f0
vars[:z_translate_components] = 50.0f0
vars[:depth_shift_lines] = 0.006f0
vars[:depth_shift_components] = 0.002f0

vars[:selected_systems] = []

# Default text for the text area
vars[:default_text] = string(
"Tips:\n",
"Keyboard shortcuts:\n",
"\tctrl+left-click: Select multiple nodes.\n",
"\tright-click and drag: to pan\n",
"\tscroll wheel: zoom in or out\n",
"\tspace: Enter the selected system\n",
"\tctrl+s: Save\n",
"\tctrl+r: Reset view\n",
"\tctrl+w: Close window\n",
"\tEsc (or MouseButton4): Exit the current system and into the parent system\n",
"\tholding x while scrolling over plots will zoom in/out in the x-direction.\n",
"\tholding y while scrolling over plots will zoom in/out in the y-direction.\n\n",
"Left-clicking a component will put information about this component here.\n\n",
"Clicking a plot below enables you to pin this plot (hitting the `pin\n",
"current plot` button) for comparison with other plots.\n",
"Use the `Delete` button to unpin a selected plot.",
)
io = IOBuffer()
println(io, "Tips:")
println(io, "Keyboard shortcuts:")
println(io, "\tctrl+left-click: Select multiple nodes.")
println(io, "\tright-click and drag: to pan")
println(io, "\tscroll wheel: zoom in or out")
println(io, "\tspace: Enter the selected system")
println(io, "\tctrl+s: Save")
println(io, "\tctrl+r: Reset view")
println(io, "\tctrl+w: Close window")
println(
io,
"\tEsc (or MouseButton4): Exit the current system and into the parent system",
)
println(
io,
"\tholding x while scrolling over plots will zoom in/out in the x-direction.",
)
println(
io,
"\tholding y while scrolling over plots will zoom in/out in the y-direction.\n",
)
println(
io,
"Left-clicking a component will put information about this component here.\n",
)
println(io, "Clicking a plot below enables you to pin this plot (hitting the `pin")
println(io, "current plot` button) for comparison with other plots.")
print(io, "Use the `Delete` button to unpin a selected plot.")
vars[:default_text] = String(take!(io))
vars[:info_text] = Observable(vars[:default_text])
vars[:summary_text] = Observable("No model results")
vars[:dragging] = Ref(false)
Expand Down Expand Up @@ -219,7 +242,9 @@ function GUI(
notify(axes[:topo].finallimits)

# make sure all graphics is adapted to the spawned figure sizes
notify(get_toggle(gui, :expand_all).active)
if get_var(gui, :expand_all)
notify(get_toggle(gui, :expand_all).active)
end

# Enable inspector (such that hovering objects shows information)
# Linewidth set to zero as this boundary is slightly laggy on movement
Expand Down Expand Up @@ -305,7 +330,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)

# Download the file if it doesn't exist in the temporary directory
if !isfile(local_file_path)
@debug "Trying to download file $url to $local_file_path"
HTTP.download(url, local_file_path)
end

Expand All @@ -323,8 +347,9 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
strokecolor = :gray50,
strokewidth = 0.5,
inspectable = false,
depth_shift = 1.0f0 - 2.0f-5,
stroke_depth_shift = 1.0f0 - 3.0f-5,
)
Makie.translate!(countries_plot, 0, 0, -1)
ocean_coords = [(180, -90), (-180, -90), (-180, 90), (180, 90)]
ocean = poly!(
ax,
Expand All @@ -333,8 +358,9 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
strokewidth = 0.5,
strokecolor = :gray50,
inspectable = false,
depth_shift = 1.0f0,
stroke_depth_shift = 1.0f0 - 1.0f-5,
)
Makie.translate!(ocean, 0, 0, -2)
else # The design does not use the EnergyModelsGeography package: Create a simple Makie axis
ax = Axis(
gridlayout_topology_ax[1, 1];
Expand Down Expand Up @@ -411,7 +437,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
labelsize = vars[:fontsize],
titlesize = vars[:fontsize],
)
Makie.translate!(topo_legend.blockscene, 0, 0, vars[:z_translate_components] + 999)

# Initiate an axis for displaying information about the selected node
ax_info::Makie.Axis = Axis(
Expand Down Expand Up @@ -638,11 +663,6 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
:results => nothing, :topo => topo_legend,
)

# Ensure that menus are on top
for menu ∈ values(menus)
translate!(menu.blockscene, 0.0f0, 0.0f0, vars[:z_translate_components] + 2000.0f0)
end

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

Expand All @@ -652,18 +672,13 @@ function create_makie_objects(vars::Dict, design::EnergySystemDesign)
)

# Update the title of the figure
topo_title_obj = text!(
text!(
ax,
vars[:topo_title_loc_x],
vars[:topo_title_loc_y];
text = vars[:title],
fontsize = vars[:fontsize],
)
Makie.translate!(
topo_title_obj,
0.0f0,
0.0f0,
vars[:z_translate_components] + 999.0f0,
depth_shift = -1.0f0,
)

return fig, buttons, menus, toggles, axes, legends
Expand Down
Loading
Loading