@@ -65,8 +65,8 @@ setMethod(f = "dag_execute",
65
65
# Check that all nodes are valid
66
66
for (node_name in names(nodes )) {
67
67
node = nodes [[node_name ]]
68
- if (! is(node , ' model_node' ) && ! is(node , ' data_node' ) && ! is(node , ' prediction_node' )) {
69
- stop(' Node "' , node_name , ' " must be a model_node, data_node, or prediction_node object' )
68
+ if (! is(node , ' model_node' ) && ! is(node , ' data_node' ) && ! is(node , ' prediction_node' ) && ! is( node , ' chart_node ' ) ) {
69
+ stop(' Node "' , node_name , ' " must be a model_node, data_node, prediction_node, or chart_node object' )
70
70
}
71
71
}
72
72
@@ -333,6 +333,93 @@ setMethod(f = "dag_execute",
333
333
cat(' Model output: ' , class(result )[1 ], ' \n ' )
334
334
}
335
335
}
336
+ } else if (is(current_node , ' chart_node' )) {
337
+ # Chart nodes: execute chart_plot
338
+
339
+ # Find all input objects for this node
340
+ input_objects = list ()
341
+
342
+ # Look for edges pointing to this node
343
+ for (edge in dag $ edges ) {
344
+ if (edge $ to == current ) {
345
+ from_node = edge $ from
346
+ from_param = edge $ from_param
347
+ to_param = edge $ to_param
348
+
349
+ if (from_node %in% names(results )) {
350
+ from_output = results [[from_node ]]
351
+ from_node_obj = nodes [[from_node ]]
352
+
353
+ # Handle different from_param values
354
+ if (from_param == " asis" || is.null(from_param )) {
355
+ # Pass the object as-is (for data nodes)
356
+ input_value = from_output
357
+ } else if (from_param == " predicted" ) {
358
+ # Use predicted() output (for model nodes to other model nodes)
359
+ if (is(from_output , ' struct_class' ) && is(from_output , ' model' )) {
360
+ tryCatch({
361
+ input_value = predicted(from_output )
362
+ }, error = function (e ) {
363
+ stop(' Failed to get predicted output from ' , from_node , ' : ' , e $ message )
364
+ })
365
+ } else {
366
+ stop(' Cannot get predicted output from non-model node: ' , from_node )
367
+ }
368
+ } else {
369
+ # Use named slot/parameter
370
+ if (is(from_output , ' struct_class' )) {
371
+ tryCatch({
372
+ input_value = from_output [[from_param ]]
373
+ }, error = function (e ) {
374
+ stop(' Failed to get parameter "' , from_param , ' " from ' , from_node , ' : ' , e $ message )
375
+ })
376
+ } else {
377
+ stop(' Cannot get parameter from non-struct object: ' , from_node )
378
+ }
379
+ }
380
+
381
+ # Handle different to_param values for chart nodes
382
+ if (to_param == " input_object" || is.null(to_param )) {
383
+ # Add to input_objects list in order
384
+ input_objects = c(input_objects , list (input_value ))
385
+ } else {
386
+ # Set named parameter for the chart
387
+ chart_obj = chart(current_node )
388
+ chart_obj [[to_param ]] = input_value
389
+ current_node @ chart = chart_obj
390
+ }
391
+ }
392
+ }
393
+ }
394
+
395
+ # Set the input_objects for the current node
396
+ current_node @ input_objects = input_objects
397
+
398
+ if (verbose ) {
399
+ cat(' Executing chart: ' , class(chart(current_node ))[1 ], ' with chart_plot\n ' )
400
+ }
401
+
402
+ # Execute the chart using chart_plot
403
+ chart_obj = chart(current_node )
404
+
405
+ # Call chart_plot with the chart object and input objects
406
+ if (length(input_objects ) == 0 ) {
407
+ # No input objects, just call chart_plot with the chart
408
+ result = chart_plot(chart_obj )
409
+ } else if (length(input_objects ) == 1 ) {
410
+ # Single input object
411
+ result = chart_plot(chart_obj , input_objects [[1 ]])
412
+ } else {
413
+ # Multiple input objects - use do.call to pass them as arguments
414
+ result = do.call(chart_plot , c(list (chart_obj ), input_objects ))
415
+ }
416
+
417
+ # Store the result (chart_plot returns a plot object)
418
+ results [[current ]] = result
419
+
420
+ if (verbose ) {
421
+ cat(' Chart output: plot object of class ' , class(result )[1 ], ' \n ' )
422
+ }
336
423
}
337
424
338
425
# Update in-degrees and add new sources to queue
0 commit comments