@@ -25,7 +25,7 @@ using ColorSchemes: ColorSchemes, ColorScheme
25
25
using SciMLBase: SciMLBase
26
26
27
27
# defined based on the julia version
28
- using NetworkDynamics: AnnotatedIOBuffer, AnnotatedString
28
+ using NetworkDynamics: AnnotatedIOBuffer, AnnotatedString, @styled_str
29
29
30
30
include (" utils.jl" )
31
31
@@ -43,7 +43,8 @@ include("timeseries.jl")
43
43
44
44
const SymbolicCompIndex = Union{VIndex{Int,Nothing}, EIndex{Int,Nothing}}
45
45
46
- export inspect
46
+ export inspect, dump_app_state
47
+ export set_sol!, set_state!, set_graphplot!, set_timeseries!, define_timeseries!
47
48
48
49
@kwdef struct GraphPlot
49
50
nstate:: Observable{Vector{Symbol}} = [:nothing ]
@@ -243,6 +244,140 @@ function inspect(sol; restart=false, reset=false)
243
244
nothing
244
245
end
245
246
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
+
246
381
function apptheme ()
247
382
Theme (
248
383
fontsize= 10 ,
0 commit comments