Lights Control with dynamic chart

[{"id":"70a2131.4af1aec","type":"ui_template","z":"66c8dbc5.4245b4","group":"9d7320e.521fce","name":"chart","order":1,"width":"24","height":"10","format":"\n\t<style>\n\t\thtml,body{\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n \theight:100%;\n\t\t}\n\t\tcanvas {\n\t\t\tbackground-color : #eee;\n\t\t\tposition: absolute;\n\t\t}\n\t\t</style>\n\t<body><canvas id=\"chartJSContainer\" style=\"height: 300px; width: 1011px; display: block;\" width=\"1011\" height=\"300\" class=\"chartjs-render-monitor\"></canvas>\n\t<script>\n\t\t\tvar options = {\n\t\t\t type: 'line',\n\t\t\t data: {\n\t\t\t labels: [\"00:00\", \"03:00\", \"06:00\", \"09:00\", \"12:00\", \"15:00\", \"18:00\", \"21:00\", \"24:00\"],\n datasets: [{\n label: \"Light cycle\",\n data: [12, 19, 3, 5, 12, 13, 3, 5, 12],\n backgroundColor: 'rgba(75, 192, 192, 0.2)',\n borderColor: \"#c0c0c0\",\n pointBorderColor: \"#00ccff\",\n pointBackgroundColor: \"#00ccff\",\n\t\t\t \tborderWidth: 1},\n\t\t\t\t\t\t]\n\t\t\t },\n\t\t\t options: {\n\t\t\t \tscales: {\n\t\t\t \tyAxes: [{\n\t\t\t ticks: {\n\t\t\t\t\treverse: false,\n\t\t\t\t\tmax: 25,\n min: 0\n\t\t\t }\n\t\t\t }]\n\t\t\t },\n\t\t\t\t\tdragData: true,\n\t\t\t\t\tdragX: false,\n\t\t\t\t\tonDragStart: function (e) {\n\t\t\t\t\t\tconsole.log(e)\n\t\t\t\t\t},\n\t\t\t\t\tonDrag: function (e, datasetIndex, index, value) {\n\t\t\t\t\t\tconsole.log(datasetIndex, index, value)\n\t\t\t\t\t},\n\t\t\t\t\tonDragEnd: function (e, datasetIndex, index, value) {\n\t\t\t\t\t\tconsole.log(datasetIndex, index, value)\n\t\t\t\t\t}\n\t\t\t }\n\t\t\t}\n\n\t\t\tvar ctx = document.getElementById('chartJSContainer').getContext('2d');\n\t\t\twindow.test = new Chart(ctx, options);\n\t\t</script>\n<script src=\"https://cdn.jsdelivr.net/npm/chartjs-plugin-dragdata@0.2.1/dist/chartjs-plugin-dragData.min.js\"></script>\n\t\t\n\n</body></html>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":638,"y":140,"wires":[["1b014fee.e549d"]]},{"id":"9d7320e.521fce","type":"ui_group","z":"","name":"Dynamic Light Control","tab":"385f5e22.9cd6f2","order":1,"disp":true,"width":"28","collapse":false},{"id":"385f5e22.9cd6f2","type":"ui_tab","z":"","name":"Day Cycle feeding","icon":"dashboard","order":7}]

trying to set up a draggable chart for controlling my lights, but having some trouble catching the functon from template node. have tried with external source and local source like import 'chartjs-plugin-dragdata'
JS is not my strongest trade, so if you could help me out abit i would be happi :slight_smile:
image

thanks, best regards
Karl

I am not an expert on chart.js but a different approach to using an external framework would be to embed it in an iframe. I have done this successfully with three.js and there is a Worldmap project that does this.
Checkout this post.

You will have a completely independent page so you will need to communicate with a web socket.

Here is a bit of example JavaScript I am using to communicate with Node Red socket nodes:
Note, /ws/3d is the URL I enter in the Node Red Sockets.

//////////////    Web Socket  /////////////////////////////
			var wsUri = "ws://localhost:1880/ws/3d";
			var ws = new WebSocket(wsUri);
			ws.onopen = function(ev) {
				console.log('page connected to Node Red');
				ws.send("Node Red Connected to page");
			};
			ws.onclose = function(ev) {
				console.log('WS-Disonnected!');
			}
			ws.onmessage = function(ev) {
				var payload = JSON.parse(ev.data);
				console.log( ev.data );
				 
				loadCube();
				
			}
			////////////////////////////////////////////////////////////

Here is the node setup:

[{"id":"ca989476.976d38","type":"inject","z":"5b3f5c0c.e4cf04","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":400,"y":360,"wires":[["da543a91.683088"]]},{"id":"9c4a5d24.5038e","type":"websocket in","z":"5b3f5c0c.e4cf04","name":"","server":"99240cd8.92c75","client":"","x":400,"y":420,"wires":[["ebf6cac.9464938"]]},{"id":"ebf6cac.9464938","type":"debug","z":"5b3f5c0c.e4cf04","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":580,"y":420,"wires":[]},{"id":"da543a91.683088","type":"websocket out","z":"5b3f5c0c.e4cf04","name":"","server":"99240cd8.92c75","client":"","x":580,"y":360,"wires":[]},{"id":"99240cd8.92c75","type":"websocket-listener","z":"","path":"/ws/3d","wholemsg":"false"}]

thats a smooth way afo sorting it. i was kinda expecting it to work with just a local call for the function after instaling it through "npm install chartjs-plugin-dragdata --save" but it did not, the only way i have been able to aproximate a function this war is to call for the dragdata function from external location. also after updating to node-red V0.19.5 its not responding to mouse events at all

Best regards
Karl

i copied the code from the maker of the dragdata, adjusted it litle bit, and it works sometimes :slight_smile:
[{"id":"5e32bc3.b200a44","type":"ui_template","z":"36bc8134.650efe","group":"61e2a9bf.001ce8","name":"chart","order":1,"width":"24","height":"6","format":"<html><head>\n\t\t<meta charset=\"utf-8\">\n\t\t<title>Chart.js Drag Data Points Plugin</title>\n\t\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.js\"></script><style type=\"text/css\">/* Chart.js */\n@-webkit-keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}@keyframes chartjs-render-animation{from{opacity:0.99}to{opacity:1}}.chartjs-render-monitor{-webkit-animation:chartjs-render-animation 0.001s;animation:chartjs-render-animation 0.001s;}</style>\n\t\t<script src=\"https://cdn.jsdelivr.net/npm/chartjs-plugin-dragdata@0.2.1/dist/chartjs-plugin-dragData.min.js\"></script>\n\n\t\t<style>\n\t\thtml,body{\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n \theight:100%;\n\t\t}\n\t\tcanvas {\n\t\t\tbackground-color : #eee;\n\t\t\tposition: absolute;\n\t\t}\n\t\t</style>\n\t</head>\n\t<body><div class=\"chartjs-size-monitor\" style=\"position: absolute; left: 0px; top: 0px; right: 0px; bottom: 0px; overflow: hidden; pointer-events: none; visibility: hidden; z-index: -1;\">\n\t <div class=\"chartjs-size-monitor-expand\" style=\"position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;\">\n\t <div style=\"position:absolute;width:1000000px;height:1000000px;left:0;top:0\"></div></div><div class=\"chartjs-size-monitor-shrink\" style=\"position:absolute;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1;\">\n\t <div style=\"position:absolute;width:200%;height:200%;left:0; top:0\"></div></div></div>\n\t\t<canvas id=\"chartJSContainer\" style=\"height: 300px; width: 1011px; display: block;\" width=\"1011\" height=\"300\" class=\"chartjs-render-monitor\"></canvas>\n\t\t<script>\n\t\t\tvar options = {\n\t\t\t type: 'line',\n\t\t\t data: {\n\t\t\t labels: [\"Red\", \"Blue\", \"Yellow\", \"Green\", \"Purple\", \"Orange\"],\n\t\t\t datasets: [\n\t\t\t\t {\n\t\t\t\t label: '# of Votes',\n\t\t\t\t data: [12, 19, 3, 5, 2, 3],\n\t\t\t \tborderWidth: 1\n\t\t\t \t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: '# of Points',\n\t\t\t\t\t\t\tdata: [7, 11, 5, 8, 3, 7],\n\t\t\t\t\t\t\tborderWidth: 1\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t },\n\t\t\t options: {\n\t\t\t \tscales: {\n\t\t\t \tyAxes: [{\n\t\t\t ticks: {\n\t\t\t\t\t\t\t\treverse: false\n\t\t\t }\n\t\t\t }]\n\t\t\t },\n\t\t\t\t\tdragData: true,\n\t\t\t\t\tonDragStart: function (e) {\n\t\t\t\t\t\tconsole.log(e)\n\t\t\t\t\t},\n\t\t\t\t\tonDrag: function (e, datasetIndex, index, value) {\n\t\t\t\t\t\tconsole.log(datasetIndex, index, value)\n\t\t\t\t\t},\n\t\t\t\t\tonDragEnd: function (e, datasetIndex, index, value) {\n\t\t\t\t\t\tconsole.log(datasetIndex, index, value)\n\t\t\t\t\t}\n\t\t\t }\n\t\t\t}\n\n\t\t\tvar ctx = document.getElementById('chartJSContainer').getContext('2d');\n\t\t\twindow.test = new Chart(ctx, options);\n\t\t</script>\n\t\n\n</body></html>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":602,"y":187,"wires":[[]]},{"id":"61e2a9bf.001ce8","type":"ui_group","z":"","name":"Dynamic Light Control","tab":"44beb5dc.9e170c","order":1,"disp":true,"width":"28","collapse":false},{"id":"44beb5dc.9e170c","type":"ui_tab","z":"","name":"Day Cycle feeding","icon":"dashboard","order":6}]

now i just need to add refresh and save buttons for storing to mysql and reading from my sql

best regards
Karl

[{"id":"bf82ecf5.314e2","type":"ui_template","z":"36bc8134.650efe","group":"3911eed9.4b7722","name":"chart1","order":3,"width":"24","height":"6","format":"\n<body>\n<canvas id=\"canvas1\" width=\"1120\" height=\"200\"></canvas>\n<script>\n (function(scope){\n scope.$watch('msg', function(msg) {\n msg\n if (msg) {\n myData = msg;\n }\n });\n})(scope);\nvar datasource2 = myData;\nvar datasource = [12,19,3,5,12,13,3,5,12,1,19,3,5,12,13,3,5,12,3,6,8,9,3,4,2];\nvar ctx = document.getElementById(\"canvas1\").getContext('2d');\nvar myChart = new Chart(ctx, {\n type: 'line',\n data: {\n labels: [\"00:00\",\"01:00\",\"02:00\", \"03:00\",\"04:00\",\"05:00\", \"06:00\",\"07:00\",\"08:00\", \"09:00\",\"10:00\",\"11:00\",\n\t\t\t \"12:00\",\"13:00\",\"14:00\", \"15:00\",\"16:00\",\"17:00\", \"18:00\",\"19:00\",\"20:00\", \"21:00\",\"22:00\",\"23:00\", \"24:00\"],\n datasets: [{\n label: 'Feeding Cycle',\n data: datasource,\n borderWidth: 1\n }]\n },\n options: {\n\t\t\t \tscales: {\n\t\t\t \tyAxes: [{\n\t\t\t ticks: {\n\t\t\t draggable: true,\n\t\t\t\t\treverse: false,\n\t\t\t\t\tmax: 30,\n min: 0\n\t\t\t }\n\t\t\t }]\n\t\t\t },\n\tdragData: true,\n\tdraggable: true,\n\tonDragStart: function (e) {console.log(e)},\n\tonDrag: function (e, datasetIndex, index, value) {console.log(datasetIndex, index, value)},\n\tonDragEnd: function (e, datasetIndex, index, value) {console.log(datasetIndex, index, value)},\n }\n});\n</script>\n\n<script>\n(function($scope) {\n$scope.sendRow = function(obj) {\n//var ctx = document.getElementById(\"canvas1\").chart.config.data;\n//var ctx1 = (this.config.data.datasets[0].data[0,1,2,3,4,5,6,7,8,9]);\n $scope.send({ \"payload\": ctx });\n};\n}\n)(scope);\n</script>\n\n\n<div>\n<md-button id=\"lagre\" class=\"md-warn\" ng-click=\"sendRow($index+1)\" position=\"absolute\" top=\"200\" left=\"y\">\n Lagre\n</md-button>\n</div>\n</body>","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":672,"y":323.0000915527344,"wires":[["79b7aeed.cfd71"]]},{"id":"3911eed9.4b7722","type":"ui_group","z":"","name":"Dynamic Feeding","tab":"b9f44ffb.b19ae","order":1,"disp":true,"width":"28","collapse":false},{"id":"b9f44ffb.b19ae","type":"ui_tab","z":"","name":"Foring kurve","icon":"dashboard","order":6}]

injecting this array into the UI template, now just need some help catching the array instead of my static values, also save them as msg.payload when hitting the save button.

i did the npm install dragdata, but still im unable to run it from local source, any ideas how to sort that?

Best regards
Karl

If you are wanting to use it in your front-end code (Dashboard), then you have to add it somewhere that Node-RED's ExpressJS web server will serve it up. So you would have to install it to the static folder that you can configure in settings.js

Alternatively, uibuilder will let you serve up packages that are installed in your userDir, you can even add/remove them using its package manager. Possibly a little overkill for your needs though. However, it does have the advantage that you can see exactly what is installed and what path (url) it is using as a root.

Thank you. found solution, works great now