@@ -7,7 +7,7 @@ using Bonito: Grid, @js_str, onload, jsrender
7
7
using WGLMakie. Makie
8
8
using WGLMakie. Makie. Colors
9
9
using WGLMakie. Makie. ColorSchemes
10
- using NetworkDynamics: extract_nw
10
+ using NetworkDynamics: extract_nw, SymbolicIndex
11
11
using NetworkDynamics: SII
12
12
using Graphs: nv, ne
13
13
using GraphMakie
@@ -69,6 +69,7 @@ function graphplot_card(app; kwargs...)
69
69
error (" Received more than one node state to plot..." )
70
70
end
71
71
notify (node_state)
72
+ nothing
72
73
end ;
73
74
74
75
edge_state = Observable (Vector {Float32} (undef, NE))
@@ -83,6 +84,7 @@ function graphplot_card(app; kwargs...)
83
84
error (" Received more than one edge state to plot..." )
84
85
end
85
86
notify (edge_state)
87
+ nothing
86
88
end ;
87
89
88
90
node_color = Observable (Vector {RGB{Float64}} (undef, NV))
@@ -92,6 +94,7 @@ function graphplot_card(app; kwargs...)
92
94
node_color[][i] = isnan (statevec[i]) ? RGB (0 ,0 ,0 ) : get (scheme, statevec[i], range)
93
95
end
94
96
notify (node_color)
97
+ nothing
95
98
end
96
99
97
100
edge_color = Observable (Vector {RGB{Float64}} (undef, NE))
@@ -101,32 +104,32 @@ function graphplot_card(app; kwargs...)
101
104
edge_color[][i] = isnan (statevec[i]) ? RGB (0 ,0 ,0 ) : get (scheme, statevec[i], range)
102
105
end
103
106
notify (edge_color)
107
+ nothing
104
108
end
105
109
106
110
notify (app. t) # trigger updates
107
111
108
112
SMALL = 30
109
113
BIG = 50
110
114
node_size = Observable (fill (SMALL, NV))
111
- onany (app. sel_nodes; update= true ) do selected
112
- @debug " GP: app.sel_nodes => node_size"
113
- fill! (node_size[], SMALL)
114
- for sel in selected
115
- node_size[][sel] = BIG
116
- end
117
- notify (node_size)
118
- end
119
-
120
115
THIN = 3
121
116
THICK = 6
122
117
edge_width = Observable (fill (THIN, NE))
123
- onany (app. sel_edges; update= true ) do selected
124
- @debug " GP: app.sel_edges => edge_width"
118
+
119
+ onany (app. graphplot. selcomp) do selcomp
120
+ @debug " GP: Sel comp => node_size, edge_width"
121
+ fill! (node_size[], SMALL)
125
122
fill! (edge_width[], THIN)
126
- for sel in selected
127
- edge_width[][sel] = THICK
123
+ for s in selcomp
124
+ if s isa VIndex
125
+ node_size[][s. compidx] = BIG
126
+ else
127
+ edge_width[][s. compidx] = THICK
128
+ end
128
129
end
130
+ notify (node_size)
129
131
notify (edge_width)
132
+ nothing
130
133
end
131
134
132
135
g = @lift $ (nw). im. g
@@ -157,6 +160,7 @@ function graphplot_card(app; kwargs...)
157
160
on (ax. scene. viewport) do lims
158
161
@debug " GP: viewport => adapt xy scaling"
159
162
adapt_xy_scaling! (ax)
163
+ nothing
160
164
end
161
165
Card (fig; class= " graphplot-card" , kwargs... )
162
166
end
@@ -201,6 +205,7 @@ function timeslider_card(app)
201
205
@debug " app.tmin, app.tmax => clamp app.t[]"
202
206
app. t[] = _t
203
207
end
208
+ nothing
204
209
end
205
210
t_slider = ContinuousSlider (twindow, app. t; arrowkeys= true )
206
211
Card (
@@ -233,7 +238,8 @@ function gpstate_control_card(app, type)
233
238
on (app. sol; update= true ) do _sol
234
239
_nw = extract_nw (_sol)
235
240
idxs = VEIndex .(1 : nv (_nw))
236
- options[] = state_options (_nw, idxs)
241
+ options[] = gen_state_options (_nw, idxs)
242
+ nothing
237
243
end
238
244
multisel = MultiSelect (options, stateobs; placeholder= " Select state for coloring" , multi= false , T= Symbol)
239
245
selector = Grid (
@@ -281,13 +287,15 @@ function gpstate_control_card(app, type)
281
287
else
282
288
error (" More than one state for maxrange calculation..." )
283
289
end
290
+ nothing
284
291
end ;
285
292
286
293
onany (thumb_l, thumb_r; update= true ) do _thumb_l, _thumb_r
287
294
@debug " GP: $(type) color slider => app.gp.colorrange"
288
295
# store the thumb position
289
296
thumb_pos_cache[thumb_pos_key ()] = (_thumb_l, _thumb_r)
290
297
colorrange[] = (_thumb_l, _thumb_r)
298
+ nothing
291
299
end
292
300
293
301
fig = with_theme (apptheme ()) do
@@ -326,14 +334,15 @@ function _maxrange(sol, idxs, rel)
326
334
extrema (Iterators. flatten (u_for_t))
327
335
end
328
336
329
- function state_options (nw:: Network , sidxs)
337
+ function gen_state_options (nw:: Network , sidxs)
338
+ options = OptionGroup{Symbol}[]
339
+ isempty (sidxs) && return options
330
340
groups = [
331
341
(" Outputs & States" , cf -> unique! (vcat (NetworkDynamics. outsym_flat (cf), sym (cf)))),
332
- (" Inputs" , NetworkDynamics. insym_all),
342
+ (" Inputs" , cf -> collect ( NetworkDynamics. insym_all (cf)) ),
333
343
(" Observables" , obssym),
334
344
(" Parameters" , psym),
335
345
]
336
- options = OptionGroup{Symbol}[]
337
346
exclusive_syms = Symbol[]
338
347
for (label, getter) in groups
339
348
common_syms = mapreduce (∩ , sidxs) do sidx
@@ -354,6 +363,55 @@ function state_options(nw::Network, sidxs)
354
363
options
355
364
end
356
365
366
+ function timeseries_card (app)
367
+ comp_options = Observable {Vector{OptionGroup{SymbolicIndex}}} ()
368
+ on (app. sol; update= true ) do _sol
369
+ @debug " TS: app.sol => comp_options"
370
+ g = extract_nw (_sol). im. g
371
+ vg = OptionGroup {SymbolicIndex} (" Nodes" , VIndex .(1 : nv (g)))
372
+ eg = OptionGroup {SymbolicIndex} (" Edges" , EIndex .(1 : ne (g)))
373
+ comp_options[] = [vg, eg]
374
+ nothing
375
+ end
376
+
377
+ state_options = Observable {Vector{OptionGroup{Symbol}}} ()
378
+ onany (app. sol, app. tsplot. selcomp; update= true ) do _sol, _sel
379
+ @debug " TS: app.sol, app.tsplot.selcomp => state_options"
380
+ _nw = extract_nw (_sol)
381
+ state_options[] = gen_state_options (_nw, _sel)
382
+ nothing
383
+ end
384
+
385
+ comp_sel = MultiSelect (comp_options, app. tsplot. selcomp;
386
+ placeholder= " Select components" ,
387
+ multi= true ,
388
+ option_to_string= _sidx_to_str,
389
+ T= SymbolicIndex)
390
+ comp_sel_dom = Grid (DOM. span (" States" ), comp_sel; columns = " 70px 1fr" , align_items = " center" )
391
+ state_sel = MultiSelect (state_options, app. tsplot. states;
392
+ placeholder= " Select states" ,
393
+ multi= true ,
394
+ T= Symbol)
395
+ state_sel_dom = Grid (DOM. span (" Components" ), state_sel; columns = " 70px 1fr" , align_items = " center" )
396
+
397
+ # hl choice of elements in graphplot
398
+ on (app. tsplot. selcomp; update= true ) do _sel
399
+ if app. graphplot. selcomp[] != _sel
400
+ app. graphplot. selcomp[] = _sel
401
+ end
402
+ nothing
403
+ end
404
+
405
+ Card (
406
+ Grid (
407
+ comp_sel_dom,
408
+ state_sel_dom,
409
+ )
410
+ )
411
+ end
412
+ function _sidx_to_str (s)
413
+ (s isa VIndex ? " v" : " e" ) * string (s. compidx)
414
+ end
357
415
function clear_obs! (nt:: NamedTuple )
358
416
for v in values (nt)
359
417
clear_obs! (v)
0 commit comments