I am using the Dashboard nodes but also want to show an animation. D3 would be perfect for the animation, therefore I an wondering if it is possible to fill a group of a dashboard tab in Node-Red with D3?
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
<script src="https://rawgit.com/gka/d3-jetpack/master/d3-jetpack.js"></script>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", '800px')
.attr("height", '800px');
var data = [{x: 100, y: 100, h: 10, w: 50, c: "red"}, {x: 200, y: 200, h: 20, w: 15, c: "yellow"}, {x: 300, y: 300, h: 60, w: 80, c: "green"}]
svg.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("width", function(d) { return d.w; })
.attr("height", function(d) { return d.h; })
.style("fill", function(d) { return d.c; })
//# sourceURL=userscript.js
</script>
In order to use external js libs from inside your ui_template
code, it's best to put the src links and the html/css/svg code into a separate templates. In the first one, choose the "Add to site <head> section" option, and include your library references:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
<script src="https://rawgit.com/gka/d3-jetpack/master/d3-jetpack.js"></script>
Then, add the other ui_template
node to your dashboard tab/group, and include this code:
<style>
#myBoxes {
height: 800px;
width: 800px;
}
</style>
<svg id="myBoxes">
<!-- svg content goes here -->
</svg>
<script>
(function(scope) {
// watch for msgs from node-red
scope.$watch('msg.payload', function(payload) {
drawBoxes("myBoxes", payload);
})
})(scope);
function drawBoxes(id, data) {
var svg = d3.select("#" + id);
var rect = svg.selectAll("rect")
.data(data);
rect.enter()
.append("rect");
rect.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("width", function(d) { return d.w; })
.attr("height", function(d) { return d.h; })
.style("fill", function(d) { return d.c; });
rect.exit()
.remove();
}
</script>
I made several revisions to your sample code --
<svg>
element, with a unique idscope.$watch(...)
to receive new msgs from node-redHere is a sample flow with a few different inputs:
[{"id":"7b4017ce.0802d8","type":"inject","z":"76a6ae8d.8a35","name":"red/white/blue","topic":"","payload":"[{\"x\":100,\"y\":100,\"h\":40,\"w\":50,\"c\":\"red\"},{\"x\":200,\"y\":200,\"h\":20,\"w\":75,\"c\":\"white\"},{\"x\":300,\"y\":300,\"h\":20,\"w\":75,\"c\":\"blue\"}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":540,"wires":[["3adb8b4a.dbf3c4"]]},{"id":"3adb8b4a.dbf3c4","type":"ui_template","z":"76a6ae8d.8a35","group":"f2c8d56c.4d75b8","name":"D3 template","order":1,"width":0,"height":0,"format":"<style>\n #myBoxes {\n height: 800px;\n width: 800px;\n }\n</style>\n\n<svg id=\"myBoxes\">\n <!-- svg content goes here -->\n</svg>\n\n<script>\n(function(scope) { \n // watch for msgs from node-red\n scope.$watch('msg.payload', function(payload) {\n drawBoxes(\"myBoxes\", payload);\n })\n})(scope);\n\nfunction drawBoxes(id, data) {\n var svg = d3.select(\"#\" + id);\n var rect = svg.selectAll(\"rect\")\n .data(data);\n\n rect.enter()\n .append(\"rect\");\n \n rect.attr(\"x\", function(d) { return d.x; })\n .attr(\"y\", function(d) { return d.y; }) \n .attr(\"width\", function(d) { return d.w; })\n .attr(\"height\", function(d) { return d.h; })\n .style(\"fill\", function(d) { return d.c; });\n \n rect.exit()\n .remove();\n}\n</script>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":510,"y":540,"wires":[[]]},{"id":"e1ab2277.a8f19","type":"ui_template","z":"76a6ae8d.8a35","group":"d215108d.8b51b","name":"D3 libraries","order":0,"width":0,"height":0,"format":"<script src=\"https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js\"></script>\n<script src=\"https://rawgit.com/gka/d3-jetpack/master/d3-jetpack.js\"></script>\n","storeOutMessages":true,"fwdInMessages":true,"templateScope":"global","x":510,"y":500,"wires":[[]]},{"id":"a4d0e22c.4689","type":"inject","z":"76a6ae8d.8a35","name":"black/white","topic":"","payload":"[{\"x\":100,\"y\":100,\"h\":40,\"w\":40,\"c\":\"black\"},{\"x\":200,\"y\":200,\"h\":40,\"w\":40,\"c\":\"white\"}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":580,"wires":[["3adb8b4a.dbf3c4"]]},{"id":"e7af594f.9862d8","type":"inject","z":"76a6ae8d.8a35","name":"red/yellow/green","topic":"","payload":"[{\"x\":100,\"y\":100,\"h\":10,\"w\":50,\"c\":\"red\"},{\"x\":200,\"y\":200,\"h\":20,\"w\":15,\"c\":\"yellow\"},{\"x\":300,\"y\":300,\"h\":60,\"w\":80,\"c\":\"green\"}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":220,"y":500,"wires":[["3adb8b4a.dbf3c4"]]},{"id":"f2c8d56c.4d75b8","type":"ui_group","z":"","name":"D3","tab":"e3e3a35c.7a77f","order":2,"disp":true,"width":"12","collapse":false},{"id":"d215108d.8b51b","type":"ui_group","z":"","name":"Recalls","tab":"3c000bae.098b94","order":2,"disp":true,"width":"18"},{"id":"e3e3a35c.7a77f","type":"ui_tab","z":"","name":"Libraries","icon":"fa-bank","order":6},{"id":"3c000bae.098b94","type":"ui_tab","z":"","name":"Vehicles","icon":"fa-car"}]