Hi all,
I am currently developing a package for AWS Stepfunctions: (GitHub - DyfanJones/aws-step-functions-data-science-sdk-r: Step Functions Data Science SDK for building machine learning (ML) workflows and pipelines on AWS). The package has been developed from the Python version (GitHub - aws/aws-step-functions-data-science-sdk-python: Step Functions Data Science SDK for building machine learning (ML) workflows and pipelines on AWS).
I wish to render the JavaScript graphs within RStudio. I am coming across the following javascript error: sfn.min.js:60 Uncaught TypeError: Cannot read property 'getBBox' of null. However the jupyter notebook version renders successfully. (I believe it due to my lack of understanding of how the htmlwidget package works).
Jupyter Notebook rendering code example:
IRdisplay::display_html('<link rel="stylesheet" type="text/css" href="https://do0of8uwbahzz.cloudfront.net/graph.css">
<div id="graph-966" class="workflowgraph">
<svg></svg>
</div>
<script type="text/javascript">
require.config({
paths: {
sfn: "https://do0of8uwbahzz.cloudfront.net/sfn",
}
});
require([\'sfn\'], function(sfn) {
var element = document.getElementById(\'graph-966\')
var options = {
width: parseFloat(getComputedStyle(element, null).width.replace("px", "")),
height: 600,
layout: \'LR\',
resizeHeight: true
};
var definition = {"StartAt":"MyPassState","States":{"MyPassState":{"Type":"Pass","Next":"Wait for 3 seconds"},"Wait for 3 seconds":{"Seconds":3,"Type":"Wait","Next":"Convert HelloWorld to Base64"},"Convert HelloWorld to Base64":{"Parameters":{"FunctionName":"MyLambda","Payload":{"input":"HelloWorld"}},"Resource":"arn:aws:states:::lambda:invoke","Type":"Task","End":true,"Retry":[{"Error_equals":["States.TaskFailed"],"Interval_seconds":15,"Max_attempts":2,"Backoff_rate":4}],"Catch":[{"Error_equals":"States.TaskFailed","Next":"LambdaTaskFailed"}]},"LambdaTaskFailed":{"Type":"Fail"}}};
var elementId = \'#graph-966\';
var graph = new sfn.StateMachineGraph(definition, elementId, options);
graph.render();
});
</script>')
Htmlwidget version
R binding:
sfn_flow_graph <- function(definition, portrait = FALSE, width = NULL, height = 600) {
if (isFALSE(portrait))
layout = 'LR'
else
layout = 'TB'
# forward options using params
params = list(
definition = definition,
layout = layout
)
# create widget
htmlwidgets::createWidget(
name = 'sfn_flow_graph',
params,
width = width,
height = height,
package = 'stepfunctions',
elementId = sprintf('graph-%d', as.integer(stats::runif(1, 0, 999)))
)
}
JavaScript binding:
HTMLWidgets.widget({
name: "sfn_flow_graph",
type: "output",
factory: function(el, width, height) {
return {
renderValue: function(x) {
// Commmented out code from jupyter notebook rendering: workflow_widgets_graph.R
// var element = document.getElementById(el.id);
// parseFloat(getComputedStyle(element, null).width.replace("px", ""))
var options = {
width: width,
height: height,
layout: x.layout,
resizeHeight: true
};
var definition = x.definition;
var graph = new sfn.StateMachineGraph(definition, '#'+el.id, options);
graph.render();
},
resize: function(width, height) {
}
};
}
});
yaml Dependencies:
dependencies:
- name: d3
version: 4.13.0
src: "htmlwidgets/lib/d3"
script: "d3.min.js"
- name: dagre
version: 0.6.3
src: "htmlwidgets/lib/dagre-d3"
script: "dagre-d3.min.js"
- name: sfn
version: 0.1.5
src: "htmlwidgets/lib/sfn_graph"
script: "sfn.min.js"
stylesheet: "sfn.css"
Example of running code:
state_def <- "{\"StartAt\":\"MyPassState\",\"States\":{\"MyPassState\":{\"Type\":\"Pass\",\"Next\":\"Wait for 3 seconds\"},\"Wait for 3 seconds\":{\"Seconds\":3,\"Type\":\"Wait\",\"Next\":\"Convert HelloWorld to Base64\"},\"Convert HelloWorld to Base64\":{\"Parameters\":{\"FunctionName\":\"MyLambda\",\"Payload\":{\"input\":\"HelloWorld\"}},\"Resource\":\"arn:aws:states:::lambda:invoke\",\"Type\":\"Task\",\"End\":true,\"Retry\":[{\"Error_equals\":[\"States.TaskFailed\"],\"Interval_seconds\":15,\"Max_attempts\":2,\"Backoff_rate\":4}],\"Catch\":[{\"Error_equals\":\"States.TaskFailed\",\"Next\":\"LambdaTaskFailed\"}]},\"LambdaTaskFailed\":{\"Type\":\"Fail\"}}}"
state_list = jsonlite::fromJSON(state_def)
sfn_flow_graph(
definition = jsonlite::toJSON(state_list, auto_unbox= T)
)
This returns an error:
sfn.min.js:60 Uncaught TypeError: Cannot read property 'getBBox' of null
at width (sfn.min.js:60)
at t.value (sfn.min.js:60)
at Object.renderValue (sfn_flow_graph.js:24)
at Object.renderValue (htmlwidgets.js:886)
at htmlwidgets.js:653
at Array.forEach (<anonymous>)
at forEach (htmlwidgets.js:55)
at htmlwidgets.js:576
at Array.forEach (<anonymous>)
at forEach (htmlwidgets.js:55)
The error seems to be coming from aws javascript dependency "sfn.min.js" however I think it is because the dependencies of "sfn.min.js" (d3, dagre-d3) not being picked up.
My code is currently on the branch "htmlwidget" of repo: aws-step-functions-data-science-sdk-r
Any help with this would be greatly appreciated.
