diff --git a/src/GUI.jl b/src/GUI.jl
index a136a1dc3ea4740dad77516ab1c8f2fcae968d13..be70fbc04a6e9135973d5db46c09a543491d33af 100644
--- a/src/GUI.jl
+++ b/src/GUI.jl
@@ -96,7 +96,7 @@ function render_plot(screen)
dates = @param(core.startdate):@param(core.enddate)
axlimits = @lift((1, length(dates), 0, maximum($pops[!,:Abundance])))
ax = Axis(plotimage[1,1], xlabel="Date", ylabel="Population size",
- limits=axlimits, xticks=Persefone.gettickmarks(dates))
+ limits=axlimits, xticks=Persefone.datetickmarks(dates))
for s in @param(nature.targetspecies)
points = @lift(Vector{Float32}(@subset($pops, :Species .== s).Abundance))
iszero(size(points[])[1]) && continue
@@ -108,6 +108,65 @@ function render_plot(screen)
display(screen, plotimage.scene)
end
+#TODO adapt the next two functions to QML and integrate them into the interface
+
+"""
+ skylarkpopulation(model)
+
+Plot a line graph of total population size and individual demographics of skylarks over time.
+Returns a Makie figure object.
+"""
+function skylarkpopulation(model::SimulationModel)
+ !("Skylark" in @param(nature.targetspecies)) && return nothing
+ pops = @data("skylark_abundance")
+ f = Figure()
+ dates = @param(core.startdate):@param(core.enddate)
+ axlimits = (1, length(dates), 0, maximum(pops[!,:TotalAbundance]))
+ ax = Axis(f[1,1], xlabel="Date", ylabel="Population size",
+ limits=axlimits, xticks=Persefone.datetickmarks(dates))
+ lines!(f[1,1], Vector{Float32}(pops.TotalAbundance), linewidth=3, label="Total abundance")
+ lines!(f[1,1], Vector{Float32}(pops.Mating), linewidth=3, label="Mating")
+ lines!(f[1,1], Vector{Float32}(pops.Breeding), linewidth=3, label="Breeding")
+ lines!(f[1,1], Vector{Float32}(pops.Nonbreeding), linewidth=3, label="Non-breeding")
+ lines!(f[1,1], Vector{Float32}(pops.Juvenile), linewidth=3, label="Juvenile")
+ lines!(f[1,1], Vector{Float32}(pops.Migrants), linewidth=3, label="Migrants")
+ axislegend("Demographic"; position=:lt)
+ f
+end
+
+"""
+ croptrends(model)
+
+Plot a dual line graph of cropped area and average plant height per crop over time.
+Returns a Makie figure object.
+"""
+function croptrends(model::SimulationModel)
+ cropdata = @data("fields")
+ f = Figure(size=(1200,1000))
+ dates = @param(core.startdate):@param(core.enddate)
+ # plot cropped area over time
+ axlimitsarea = (1, length(dates), 0, maximum(cropdata[!,:Area])*1.1)
+ ax1 = Axis(f[1,1], xlabel="Date", ylabel="Cropped area (ha)",
+ limits=axlimitsarea, xticks=Persefone.datetickmarks(dates))
+ for c in unique(cropdata.Crop)
+ points = @select!(@subset(cropdata, :Crop .== c), :Area)
+ (iszero(size(points)[1]) || iszero(sum(points.Area))) && continue
+ lines!(f[1,1], Vector{Float32}(points.Area), linewidth=3, label=c)
+ end
+ axislegend("Crop"; position=:rt)
+ # plot average crop height over time
+ axlimitsheight = (1, length(dates), 0, maximum(cropdata[!,:Height])*1.1)
+ ax2 = Axis(f[2,1], xlabel="Date", ylabel="Average plant height (cm)",
+ limits=axlimitsheight, xticks=datetickmarks(dates))
+ for c in unique(cropdata.Crop)
+ points = @select!(@subset(cropdata, :Crop .== c), :Height)
+ (iszero(size(points)[1]) || iszero(sum(points.Height))) && c != "no growth" && continue
+ lines!(f[2,1], Vector{Float32}(points.Height), linewidth=3, label=c)
+ end
+ axislegend("Crop"; position=:rt)
+ f
+end
+
on(delay) do d
println("Delay is now $(round(d, digits=1)) seconds.") #XXX DEBUG
end
@@ -153,6 +212,8 @@ The main function that creates the application.
function launch()
global model, timer
+ println("NOTE: this software is in development. Expect bugs.")
+
activateqmlfunctions()
timer = QTimer()
diff --git a/src/main.qml b/src/main.qml
index 8ebfc9ea2c31f9194896ec3acd68af768b83ef1e..d4fdc457b5b150199e51337dab9309a086d6c58c 100644
--- a/src/main.qml
+++ b/src/main.qml
@@ -92,14 +92,14 @@ ApplicationWindow {
Button {
id: backButton
text: "<"
- ToolTip.text: "Back"
+ ToolTip.text: "Step back"
ToolTip.visible: hovered
onClicked: { Julia.previousstep() }
}
Button {
id: stepButton
text: ">"
- ToolTip.text: "Step"
+ ToolTip.text: "Step forward"
ToolTip.visible: hovered
onClicked: { Julia.nextstep() }
}
@@ -142,10 +142,19 @@ ApplicationWindow {
text: "Persefone.jl Desktop"
informativeText: "A mechanistic model of agricultural landscapes \
and ecosystems in Europe.\n\n\
-© 2023 Daniel Vedder, Lea Kolb, Guy Pe'er\n\
+© 2024 Daniel Vedder, Guy Pe'er\n\
Distributed under the MIT license."
}
+ MessageDialog {
+ id: devDialog
+ text: "In Development"
+ informativeText: "Please note that this model and the desktop software \
+are still in active development. Expect bugs and unfinished functionality.\n\n\
+If you have questions, contact daniel.vedder@idiv.de."
+ visible: true
+ }
+
FileDialog {
id: loadFileChooser
defaultSuffix: "dat"