@@ -25,7 +25,7 @@ using ColorSchemes: ColorSchemes, ColorScheme
2525using SciMLBase: SciMLBase
2626
2727# defined based on the julia version
28- using NetworkDynamics: AnnotatedIOBuffer, AnnotatedString
28+ using NetworkDynamics: AnnotatedIOBuffer, AnnotatedString, @styled_str
2929
3030include (" utils.jl" )
3131
@@ -43,7 +43,8 @@ include("timeseries.jl")
4343
4444const SymbolicCompIndex = Union{VIndex{Int,Nothing}, EIndex{Int,Nothing}}
4545
46- export inspect
46+ export inspect, dump_app_state
47+ export set_sol!, set_state!, set_graphplot!, set_timeseries!, define_timeseries!
4748
4849@kwdef struct GraphPlot
4950 nstate:: Observable{Vector{Symbol}} = [:nothing ]
@@ -243,6 +244,140 @@ function inspect(sol; restart=false, reset=false)
243244 nothing
244245end
245246
247+ function appstate ()
248+ isnothing (APPSTATE[]) && error (" Uninitialized appstate. To initialize call `set_sol!(sol)` or `inspect(sol)`!" )
249+ APPSTATE[]
250+ end
251+
252+ # helper constrcut to mark undefined keyword arguments
253+ struct NotSpecified end
254+ function set_maybe! (obs:: Observable , val)
255+ if obs[] != val
256+ obs[] = val
257+ end
258+ end
259+ set_maybe! (obs:: Observable , :: NotSpecified ) = nothing
260+
261+ """
262+ set_sol!(sol)
263+
264+ Set the solution of the current appstate to `sol`.
265+ """
266+ function set_sol! (sol)
267+ if isnothing (APPSTATE[])
268+ APPSTATE[] = AppState (sol)
269+ else
270+ APPSTATE[]. sol[] = sol
271+ end
272+ nothing
273+ end
274+
275+ """
276+ set_state!(; sol, t, tmin, tmax)
277+
278+ Set the solution, current time and time limits of the current appstate.
279+
280+ To automaticially create commands see [`dump_app_state()`](@ref).
281+ """
282+ function set_state! (; sol = NotSpecified (),
283+ t = NotSpecified (),
284+ tmin = NotSpecified (),
285+ tmax = NotSpecified ())
286+ sol != NotSpecified () && set_sol! (sol)
287+ set_maybe! (appstate (). t, t)
288+ set_maybe! (appstate (). tmin, tmin)
289+ set_maybe! (appstate (). tmax, tmax)
290+ nothing
291+ end
292+
293+ """
294+ set_graphplot!(; nstate, estate, nstate_rel, estate_rel, ncolorrange, ecolorrange)
295+
296+ Set the properties of the graphplot of the current appstate.
297+
298+ To automaticially create commands see [`dump_app_state()`](@ref).
299+ """
300+ function set_graphplot! (; nstate = NotSpecified (),
301+ estate = NotSpecified (),
302+ nstate_rel = NotSpecified (),
303+ estate_rel = NotSpecified (),
304+ ncolorrange = NotSpecified (),
305+ ecolorrange = NotSpecified ())
306+ gp = appstate (). graphplot
307+ set_maybe! (gp. nstate, nstate)
308+ set_maybe! (gp. estate, estate)
309+ set_maybe! (gp. nstate_rel, nstate_rel)
310+ set_maybe! (gp. estate_rel, estate_rel)
311+ set_maybe! (gp. ncolorrange, ncolorrange)
312+ set_maybe! (gp. ecolorrange, ecolorrange)
313+ nothing
314+ end
315+
316+ """
317+ set_timeseries!(key; selcomp, states, rel)
318+
319+ Set properties of the timeseries plot with key `key`. See also [`define_timeseries!`](@ref).
320+
321+ To automaticially create commands see [`dump_app_state()`](@ref).
322+ """
323+ function set_timeseries! (key; selcomp = NotSpecified (),
324+ states = NotSpecified (),
325+ rel = NotSpecified ())
326+ if ! haskey (appstate (). tsplots, key)
327+ appstate (). tsplots[key] = TimeseriesPlot ()
328+ end
329+ tsplot = appstate (). tsplots[key]
330+ set_maybe! (tsplot. selcomp, selcomp)
331+ set_maybe! (tsplot. states, states)
332+ set_maybe! (tsplot. rel, rel)
333+ nothing
334+ end
335+
336+ """
337+ define_timeseries!(tsarray)
338+
339+ Defines timeseries, where `tsarray` is an array of timeseries keyword arguments
340+ (see [`set_timeseries!`](@ref)).
341+
342+ To automaticially create commands see [`dump_app_state()`](@ref).
343+ """
344+ function define_timeseries! (tsarray)
345+ if length (tsarray) != length (appstate (). tsplots[])
346+ @warn " Due to current limitations, you need to reload the page if the number of timeseries plots changes"
347+ empty! (appstate (). tsplots[])
348+ tskeys = [gendomid (" ts" ) for _ in tsarray]
349+ else
350+ tskeys = keys (appstate (). tsplots[])
351+ end
352+ for (key, ts) in zip (tskeys, tsarray)
353+ set_timeseries! (key; pop! (tsargs)... )
354+ end
355+ nothing
356+ end
357+
358+ """
359+ dump_app_state()
360+
361+ Generate a list of [`set_sol!`](@ref), [`set_state!`](@ref), [`set_graphplot!`](@ref) and [`define_timeseries!`](@ref)
362+ commands to recreate the current appstate.
363+ The intended usecase is to quickly recreate "starting points" for interactive exploration.
364+ """
365+ function dump_app_state ()
366+ appstate ()
367+ println (" To recreate the current state, run the following commands:\n " )
368+ println (styled " set_sol!({red:sol}) # optional if after inspect(sol)" )
369+ println (" set_state!(; t=$(appstate (). t[]) , tmin=$(appstate (). tmin[]) , tmax=$(appstate (). tmax[]) )" )
370+ gp = appstate (). graphplot
371+ println (" set_graphplot!(; nstate=$(gp. nstate[]) , estate=$(gp. estate[]) , nstate_rel=$(gp. nstate_rel[]) , estate_rel=$(gp. estate_rel[]) , ncolorrange=$(gp. ncolorrange[]) , ecolorrange=$(gp. ecolorrange[]) )" )
372+ println (" define_timeseries!([" )
373+ for ts in values (appstate (). tsplots[])
374+ selstr = replace (repr (ts. selcomp[]), r" ^.*\[ " => " [" )
375+ println (" (; selcomp=$(selstr) , states=$(ts. states[]) , rel=$(ts. rel[]) )," )
376+ end
377+ println (" ])" )
378+ nothing
379+ end
380+
246381function apptheme ()
247382 Theme (
248383 fontsize= 10 ,
0 commit comments