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
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Version 0.5.18 (2025-11-24)

### Bugfix

* Fix missing distinction between different `TransmissionMode`s in the "data"-menu by including the `id` field in parentheses.

### 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.
Expand All @@ -16,6 +20,8 @@
* 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]`
* Also expand `TransmissionMode`s in the info-box.
* For the labeling, use square brackets around indices in the string construction.

## Version 0.5.17 (2025-11-19)

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.
57 changes: 47 additions & 10 deletions ext/EMGExt/EMGExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,11 @@ Returns the `Transmission`s of a `SystemGeo` `system`.
EMG.get_transmissions(system::EMGUI.SystemGeo) = EMGUI.get_connections(system)

"""
get_modes(system::EMGUI.SystemGeo)
EMG.modes(conn::EMGUI.Connection)

Get all transmission modes of a `SystemGeo` `system`.
Returns an array of the transmission modes for a `Connection` `conn`.
"""
function get_modes(system::EMGUI.SystemGeo)
transmission_modes = TransmissionMode[]
for t ∈ get_transmissions(system)
append!(transmission_modes, modes(t))
end
return transmission_modes
end
EMG.modes(conn::EMGUI.Connection) = EMG.modes(EMGUI.get_element(conn))

############################################################################################
## From datastructures.jl
Expand Down Expand Up @@ -85,7 +79,7 @@ function EMGUI.get_plotables(system::EMGUI.SystemGeo)
get_nodes(system),
get_links(system),
get_areas(system),
get_modes(system),
modes(get_transmissions(system)),
)
end

Expand Down Expand Up @@ -194,4 +188,47 @@ end
Map types to header symbols for saving results.
"""
EMGUI._type_to_header(::Type{<:TransmissionMode}) = :element

############################################################################################
## From info_axis_utils.jl
"""
print_nested_structure!(
element::Vector{<:TransmissionMode},
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
)

Appends the nested structure of element in a nice format to the `io` buffer for `element`.
The parameter `indent` tracks the indentation level, the parameter `vector_limit` is used
to truncate large vectors and `show_the_n_last_elements` specifies how many of the last elements to show.
"""
function EMGUI.print_nested_structure!(
element::Vector{<:TransmissionMode},
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
)
indent += 1
indent_str::String = EMGUI.create_indent_string(indent)
for (i, field1) ∈ enumerate(element)
if i == vector_limit + 1
println(io, indent_str, "...")
continue
end
if i <= vector_limit || i > length(element) - show_the_n_last_elements
type = typeof(field1)
println(io, indent_str, i, " (", type, "):")
EMGUI.print_nested_structure!(
field1,
io,
indent,
vector_limit,
show_the_n_last_elements,
)
end
end
end
end
20 changes: 14 additions & 6 deletions src/utils_GUI/GUI_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -644,22 +644,30 @@ function update_descriptive_names!(gui::GUI)
end

"""
select_data!(gui::GUI, name::String)
select_data!(gui::GUI, name::String; selection::Vector = Any[])

Select the data with name `name` from the `available_data` menu.
Select the data with name `name` from the `available_data` menu. If `selection` is provided,
it is used to further specify which data to select.
"""
function select_data!(gui::GUI, name::String)
function select_data!(gui::GUI, name::String; selection::Vector = Any[])
# Fetch the available data menu object
menu = get_menu(gui, :available_data)

# Fetch all menu options
available_data = [get_name(x[2]) for x ∈ collect(menu.options[])]
items = collect(menu.options[])

# Find menu number for data with name `name`
i_selected = findfirst(x -> x == name, available_data)
if isempty(selection)
i_selected = findfirst(x -> get_name(x[2]) == name, items)
else
i_selected = findfirst(
x -> get_name(x[2]) == name && issubset(selection, get_selection(x[2])),
items,
)
end

# Select data
menu.i_selected = i_selected
return nothing
end

"""
Expand Down
221 changes: 134 additions & 87 deletions src/utils_GUI/info_axis_utils.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
Expandable::Type = Union{
Vector,
Dict,
EMB.Node,
Resource,
Link,
TimeStructure,
Data,
AbstractInvData,
Investment,
LifetimeMode,
TimeProfile,
}
"""
update_info_box!(gui::GUI, element)

Expand All @@ -10,114 +23,148 @@ function update_info_box!(gui::GUI, element)
return nothing
end
io = IOBuffer()
print_nested_structure!(
element,
io;
vector_limit = 5,
show_the_n_last_elements = 1,
)
type = typeof(element)
if isa(element, Dict) || isa(element, Vector)
println(io, type)
else
println(io, element, " (", type, ")")
end
print_nested_structure!(element, io, 0, 5, 1)
info_text[] = String(take!(io))
end

"""
create_indent_string(indent::Int64)

Create an indentation string based on the `indent` level.
"""
create_indent_string(indent::Int64) = " "^indent

"""
print_nested_structure!(
element,
io::IOBuffer;
indent::Int64=0,
vector_limit::Int64=typemax(Int64),
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
)

Appends the nested structure of element in a nice format to the io buffer. The
parameter `vector_limit` is used to truncate large vectors.
Appends the nested structure of element in a nice format to the `io` buffer for `element`.
The parameter `indent` tracks the indentation level, the parameter `vector_limit` is used
to truncate large vectors and `show_the_n_last_elements` specifies how many of the last elements to show.
"""
function print_nested_structure!(
element,
io::IOBuffer;
indent::Int64 = 0,
vector_limit::Int64 = typemax(Int64),
show_the_n_last_elements::Int64 = 3,
element::Any,
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
)
if indent == 0
type = typeof(element)
if isa(element, Dict) || isa(element, Vector)
println(io, type)
indent += 1
indent_str::String = create_indent_string(indent)
for field1 ∈ fieldnames(typeof(element))
value1 = getfield(element, field1)
if isa(value1, Expandable)
println(io, indent_str, field1, " (", typeof(value1), "):")
print_nested_structure!(
value1,
io,
indent,
vector_limit,
show_the_n_last_elements,
)
else
println(io, element, " (", type, ")")
if isa(value1, OperationalProfile) &&
!isa(value1, FixedProfile) &&
length(value1.vals) > vector_limit
# Truncate large vectors
println(io, indent_str, field1, ": ", typeof(value1))
else
println(io, indent_str, field1, ": ", value1)
end
end
end
return nothing
end
function print_nested_structure!(
element::Dict,
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
)
indent += 1
indent_str::String = " "^indent
expandable::Union = Union{
Vector,
Dict,
EMB.Node,
Resource,
Link,
TimeStructure,
Data,
AbstractInvData,
Investment,
LifetimeMode,
TimeProfile,
}
if isa(element, Vector)
if eltype(element) <: expandable
for (i, field1) ∈ enumerate(element)
if i == vector_limit + 1
println(io, indent_str, "...")
continue
end
if i <= vector_limit || i > length(element) - show_the_n_last_elements
type = typeof(field1)
if isa(field1, expandable)
println(io, indent_str, i, " (", type, "):")
print_nested_structure!(field1, io; indent, vector_limit)
else
println(io, indent_str, i, ": ", type, "(", field1, ")")
end
end
end
indent_str::String = create_indent_string(indent)
for field1 ∈ keys(element)
if isa(element[field1], Expandable)
println(io, indent_str, field1, " (", typeof(element[field1]), "):")
print_nested_structure!(
element[field1],
io,
indent,
vector_limit,
show_the_n_last_elements,
)
else
print(io, indent_str, "[")
for (i, field1) ∈ enumerate(element)
if i == vector_limit + 1
print(io, " ... ")
continue
end
if i <= vector_limit || i > length(element) - show_the_n_last_elements
print(io, field1)
if i != length(element)
print(io, ", ")
end
end
end
println(io, "]")
println(io, indent_str, field1, " => ", element[field1])
end
end
end
function print_nested_structure!(
element::Vector{T},
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
) where {T<:Expandable}
indent += 1
indent_str::String = create_indent_string(indent)
for (i, field1) ∈ enumerate(element)
if i == vector_limit + 1
println(io, indent_str, "...")
continue
end
elseif isa(element, Dict)
for field1 ∈ keys(element)
if isa(element[field1], expandable)
println(io, indent_str, field1, " (", typeof(element[field1]), "):")
print_nested_structure!(element[field1], io; indent, vector_limit)
if i <= vector_limit || i > length(element) - show_the_n_last_elements
type = typeof(field1)
if isa(field1, Expandable)
println(io, indent_str, i, " (", type, "):")
print_nested_structure!(
field1,
io,
indent,
vector_limit,
show_the_n_last_elements,
)
else
println(io, indent_str, field1, " => ", element[field1])
println(io, indent_str, i, ": ", type, "(", field1, ")")
end
end
else
for field1 ∈ fieldnames(typeof(element))
value1 = getfield(element, field1)
if isa(value1, expandable)
println(io, indent_str, field1, " (", typeof(value1), "):")
print_nested_structure!(value1, io; indent, vector_limit)
else
if isa(value1, OperationalProfile) &&
!isa(value1, FixedProfile) &&
length(value1.vals) > vector_limit
# Truncate large vectors
println(io, indent_str, field1, ": ", typeof(value1))
else
println(io, indent_str, field1, ": ", value1)
end
end
return nothing
end
function print_nested_structure!(
element::Vector{T},
io::IOBuffer,
indent::Int64,
vector_limit::Int64,
show_the_n_last_elements::Int64,
) where {T}
indent += 1
indent_str::String = create_indent_string(indent)
print(io, indent_str, "[")

for (i, field1) ∈ enumerate(element)
if i == vector_limit + 1
print(io, " ... ")
continue
end
if i <= vector_limit || i > length(element) - show_the_n_last_elements
print(io, field1)
if i != length(element)
print(io, ", ")
end
end
end
println(io, "]")
return nothing
end
Loading
Loading