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.