This repository has been archived by the owner on Nov 16, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathnode-red-custom-table-chart-widget.json
1 lines (1 loc) · 12.3 KB
/
node-red-custom-table-chart-widget.json
1
[{"id":"18d60280.ae51ce","type":"ui_template","z":"4ca6d44e.16a0ec","group":"1444eda7.0423a2","name":"D3 Chart Widget","order":0,"width":"16","height":"16","format":"<!-- external links -->\n<script src=\"http://d3js.org/d3.v3.min.js\"></script> \n<link rel=\"stylesheet\" href=\"http://billmill.org/css/style.css\" /> \n<style>\n<!-- D3 table style --> \ntable {\n border-collapse: collapse;\n}\nth {\n border-bottom: 2px solid #ddd;\n padding: 8px;\n font-weight: bold;\n}\ntd {\n padding: 8px;\n border-top: 1px solid #ddd;\n}\n#chart {\n padding: 0px;\n}\n.xaxislabel {\n font-size: 9px;\n}\n\n<!--spinner style --> \n\n/* Center the loader */\n#loader {\n position: absolute;\n left: 50%;\n top: 50%;\n z-index: 1;\n width: 150px;\n height: 150px;\n margin: -75px 0 0 -75px;\n border: 16px solid #f3f3f3;\n border-radius: 50%;\n border-top: 16px solid #3498db;\n width: 120px;\n height: 120px;\n -webkit-animation: spin 2s linear infinite;\n animation: spin 2s linear infinite;\n}\n\n@-webkit-keyframes spin {\n 0% { -webkit-transform: rotate(0deg); }\n 100% { -webkit-transform: rotate(360deg); }\n}\n\n@keyframes spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n}\n\n/* Add animation to \"page content\" */\n.animate-bottom {\n position: relative;\n -webkit-animation-name: animatebottom;\n -webkit-animation-duration: 1s;\n animation-name: animatebottom;\n animation-duration: 1s\n}\n\n@-webkit-keyframes animatebottom {\n from { bottom:-100px; opacity:0 } \n to { bottom:0px; opacity:1 }\n}.spinner {\n margin: 100px auto;\n width: 50px;\n height: 40px;\n text-align: center;\n font-size: 10px;\n}\n\n.spinner > div {\n background-color: #333;\n height: 100%;\n width: 6px;\n display: inline-block;\n \n -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;\n animation: sk-stretchdelay 1.2s infinite ease-in-out;\n}\n\n.spinner .rect2 {\n -webkit-animation-delay: -1.1s;\n animation-delay: -1.1s;\n}\n\n.spinner .rect3 {\n -webkit-animation-delay: -1.0s;\n animation-delay: -1.0s;\n}\n\n.spinner .rect4 {\n -webkit-animation-delay: -0.9s;\n animation-delay: -0.9s;\n}\n\n.spinner .rect5 {\n -webkit-animation-delay: -0.8s;\n animation-delay: -0.8s;\n}\n\n@-webkit-keyframes sk-stretchdelay {\n 0%, 40%, 100% { -webkit-transform: scaleY(0.4) } \n 20% { -webkit-transform: scaleY(1.0) }\n}\n\n@keyframes sk-stretchdelay {\n 0%, 40%, 100% { \n transform: scaleY(0.4);\n -webkit-transform: scaleY(0.4);\n } 20% { \n transform: scaleY(1.0);\n -webkit-transform: scaleY(1.0);\n }\n}\n\n@keyframes animatebottom { \n from{ bottom:-100px; opacity:0 } \n to{ bottom:0; opacity:1 }\n}\n</style>\n<h3 align=\"center\">Table With Embedded Line Chart </h3>\n<div id=\"datatable\" ng-if=\"msgReady\" ng-style=\"msgStyle\" ></div>\n<div class=\"spinner\" ng-if=\"!msgReady\">\n <div class=\"rect1\"></div>\n <div class=\"rect2\"></div>\n <div class=\"rect3\"></div>\n <div class=\"rect4\"></div>\n <div class=\"rect5\"></div>\n</div>\n\n<script>\n\n;(function(scope) {\n \n scope.msgReady = false;\n scope.msgStyle = { 'height':'700px' };\n \n \n var timer = setInterval(function() { //check that D3 libs are loaded, if not wait\n if (!window.d3) return;\n clearInterval(timer);\n \n scope.msgReady = true; \n scope.$watch('msg', function (msg) { //watch for an incoming NR msg\n \n if (msg) {\n \n d3.select(\"#datatable\").selectAll(\"*\").remove();\n \n var rows = msg.payload;\n \n var table = d3.select(\"#datatable\").append(\"table\");\n thead = table.append(\"thead\");\n tbody = table.append(\"tbody\");\n\n thead.append(\"th\").text(\"Date\");\n thead.append(\"th\").text(\"Opponent\");\n thead.append(\"th\").text(\"Result\");\n thead.append(\"th\").text(\"Rating\");\n thead.append(\"th\").text(\"\");\n\n var tr = tbody.selectAll(\"tr\")\n .data(rows)\n .enter().append(\"tr\");\n\n var td = tr.selectAll(\"td\")\n .data(function(d) { return [d.dt, d.opp, d.result, d.mu]; })\n .enter().append(\"td\")\n .text(function(d) { return d; });\n\n var width = 80,mx = 10, radius = 2,\n height = d3.select(\"table\")[0][0].clientHeight;\n\n // Now add the chart column\n d3.select(\"#datatable tbody tr\").append(\"td\")\n .attr(\"id\", \"chart\")\n .attr(\"width\", width + \"px\")\n .attr(\"rowspan\", rows.length);\n\n var chart = d3.select(\"#chart\").append(\"svg\")\n .attr(\"class\", \"chart\")\n .attr(\"width\", width)\n .attr(\"height\", height);\n\n var maxMu = 0;\n var minMu = Number.MAX_VALUE;\n for (i=0; i < rows.length; i++) {\n if (rows[i].mu > maxMu) { maxMu = rows[i].mu; }\n if (rows[i].mu < minMu) { minMu = rows[i].mu; }\n }\n\n var dates = rows.map(function(t) { return t.dt; });\n\n var xscale = d3.scale.linear()\n .domain([minMu, maxMu])\n .range([mx, width-mx])\n .nice();\n\n var yscale = d3.scale.ordinal()\n .domain(dates)\n .rangeBands([0, height]);\n\n chart.selectAll(\".xaxislabel\")\n .data(xscale.ticks(2))\n .enter().append(\"text\")\n .attr(\"class\", \"xaxislabel\")\n .attr(\"x\", function(d) { return xscale(d); })\n .attr(\"y\", 10)\n .attr(\"text-anchor\", \"middle\")\n .text(String)\n\n chart.selectAll(\".xaxistick\")\n .data(xscale.ticks(2))\n .enter().append(\"line\")\n .attr(\"x1\", function(d) { return xscale(d); })\n .attr(\"x2\", function(d) { return xscale(d); })\n .attr(\"y1\", 10)\n .attr(\"y2\", height)\n .attr(\"stroke\", \"#eee\")\n .attr(\"stroke-width\", 1);\n\n chart.selectAll(\".line\")\n .data(rows)\n .enter().append(\"line\")\n .attr(\"x1\", function(d) { return xscale(d.mu); })\n .attr(\"y1\", function(d) { return yscale(d.dt) + yscale.rangeBand()/2; })\n .attr(\"x2\", function(d,i) { return rows[i+1] ? xscale(rows[i+1].mu) : xscale(d.mu); })\n .attr(\"y2\", function(d,i) { return rows[i+1] ? yscale(rows[i+1].dt) + yscale.rangeBand()/2 : yscale(d.dt) + yscale.rangeBand()/2; })\n .attr(\"stroke\", \"#777\")\n .attr(\"stroke-width\", 1);\n\n var pt = chart.selectAll(\".pt\")\n .data(rows)\n .enter().append(\"g\")\n .attr(\"class\", \"pt\")\n .attr(\"transform\", function(d) { return \"translate(\" + xscale(d.mu) + \",\" + (yscale(d.dt) + yscale.rangeBand()/2) + \")\"; });\n\n pt.append(\"circle\")\n .attr(\"cx\", 0)\n .attr(\"cy\", 0)\n .attr(\"r\", radius)\n .attr(\"opacity\", .5)\n .attr(\"fill\", \"#ff0000\");\n\n } // if\n }); // watch\n\n\n }, 3000); // close out the setInterval \n // 3 secs for spinner demo\n\n})(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":602.3003234863281,"y":356.8004741668701,"wires":[[]]},{"id":"8f387961.25fc58","type":"inject","z":"4ca6d44e.16a0ec","name":"","topic":"","payload":"","payloadType":"date","repeat":"3","crontab":"","once":true,"onceDelay":0.1,"x":152.3000030517578,"y":359.066725730896,"wires":[["d3ce3d90.6b48f"]]},{"id":"d3ce3d90.6b48f","type":"function","z":"4ca6d44e.16a0ec","name":"random csv","func":"\n\nvar msg = {};\nmsg.topic = \"Line Chart\";\n\nvar count = Math.floor(Math.random() * 2);\n\nswitch( count ) {\n\ncase 0 :\nmsg.payload ='mu,sigma,opp,result,date\\n'+\n'1662.30921255,290.31746003,FC Augsburg,1,2013-08-10T00:00:00\\n'+\n'1710.31516965,260.486532706,TSV Eintracht Braunschweig,1,2013-08-18T00:00:00\\n'+\n'1833.29188401,225.673906004,Werder Bremen,1,2013-08-23T00:00:00\\n'+\n'1857.5300504,214.245325191,Eintracht Frankfurt,1,2013-09-01T00:00:00\\n'+\n'1875.73400724,205.674370682,Hamburg SV,1,2013-09-14T00:00:00\\n'+\n'1784.18071145,185.716271567,Napoli,0,2013-09-18T00:00:00\\n'+\n'1718.35291449,179.834040342,Nurnberg,0.5,2013-09-21T00:00:00\\n'+\n'1740.98858679,171.270511287,SC Freiburg,1,2013-09-28T00:00:00\\n'+\n'1786.58260116,157.720707589,Marseille,1,2013-10-01T00:00:00\\n'+\n'1693.24904256,150.534136974,Borussia Monchengladbach,0,2013-10-05T00:00:00\\n'+\n'1730.8689396,141.113609063,Hannover 96,1,2013-10-19T00:00:00\\n'+\n'1796.86111973,134.157129861,Arsenal,1,2013-10-22T00:00:00\\n'+\n'1815.9808198,129.14679898,Schalke 04,1,2013-10-26T00:00:00\\n'+\n'1827.35641274,126.152133747,VfB Stuttgart,1,2013-11-01T00:00:00\\n'+\n'1792.11402645,120.045882423,Arsenal,0,2013-11-06T00:00:00';\nbreak;\ncase 1 :\nmsg.payload ='mu,sigma,opp,result,date\\n'+\n'1762.30921255,290.31746003,FC Augsburg,1,2013-08-10T00:00:00\\n'+\n'1719.31516965,260.486532706,TSV Eintracht Braunschweig,1,2013-08-18T00:00:00\\n'+\n'1633.29188401,225.673906004,Werder Bremen,1,2013-08-23T00:00:00\\n'+\n'1897.5300504,214.245325191,Eintracht Frankfurt,1,2013-09-01T00:00:00\\n'+\n'1775.73400724,205.674370682,Hamburg SV,1,2013-09-14T00:00:00\\n'+\n'1884.18071145,185.716271567,Napoli,0,2013-09-18T00:00:00\\n'+\n'1818.35291449,179.834040342,Nurnberg,0.5,2013-09-21T00:00:00\\n'+\n'1840.98858679,171.270511287,SC Freiburg,1,2013-09-28T00:00:00\\n'+\n'1686.58260116,157.720707589,Marseille,1,2013-10-01T00:00:00\\n'+\n'1793.24904256,150.534136974,Borussia Monchengladbach,0,2013-10-05T00:00:00\\n'+\n'1830.8689396,141.113609063,Hannover 96,1,2013-10-19T00:00:00\\n'+\n'1896.86111973,134.157129861,Arsenal,1,2013-10-22T00:00:00\\n'+\n'1615.9808198,129.14679898,Schalke 04,1,2013-10-26T00:00:00\\n'+\n'1727.35641274,126.152133747,VfB Stuttgart,1,2013-11-01T00:00:00\\n'+\n'1892.11402645,120.045882423,Arsenal,0,2013-11-06T00:00:00';\nbreak;\ndefault :\nmsg.payload ='mu,sigma,opp,result,date\\n'+\n'1682.30921255,290.31746003,FC Augsburg,1,2013-08-10T00:00:00\\n'+\n'1810.31516965,260.486532706,TSV Eintracht Braunschweig,1,2013-08-18T00:00:00\\n'+\n'1733.29188401,225.673906004,Werder Bremen,1,2013-08-23T00:00:00\\n'+\n'1657.5300504,214.245325191,Eintracht Frankfurt,1,2013-09-01T00:00:00\\n'+\n'1775.73400724,205.674370682,Hamburg SV,1,2013-09-14T00:00:00\\n'+\n'1884.18071145,185.716271567,Napoli,0,2013-09-18T00:00:00\\n'+\n'1818.35291449,179.834040342,Nurnberg,0.5,2013-09-21T00:00:00\\n'+\n'1640.98858679,171.270511287,SC Freiburg,1,2013-09-28T00:00:00\\n'+\n'1786.58260116,157.720707589,Marseille,1,2013-10-01T00:00:00\\n'+\n'1893.24904256,150.534136974,Borussia Monchengladbach,0,2013-10-05T00:00:00\\n'+\n'1730.8689396,141.113609063,Hannover 96,1,2013-10-19T00:00:00\\n'+\n'1796.86111973,134.157129861,Arsenal,1,2013-10-22T00:00:00\\n'+\n'1815.9808198,129.14679898,Schalke 04,1,2013-10-26T00:00:00\\n'+\n'1847.35641274,126.152133747,VfB Stuttgart,1,2013-11-01T00:00:00\\n'+\n'1792.11402645,120.045882423,Arsenal,0,2013-11-06T00:00:00';\n\nbreak;\n}\nreturn msg;","outputs":1,"noerr":0,"x":337.3001174926758,"y":342.866943359375,"wires":[["e66191ed.19ddc"]]},{"id":"e66191ed.19ddc","type":"function","z":"4ca6d44e.16a0ec","name":"csv2json","func":"\nvar csv = [];\nvar lines=msg.payload.split(\"\\n\");\nvar headers=lines[0].split(\",\");\nfor(var i=1;i<lines.length;i++){\n var obj = {};\n var currentline=lines[i].split(\",\");\n\tfor(var j=0;j<headers.length;j++) obj[headers[j]] = currentline[j];\n\tcsv.push(obj);\n}\n\nvar result = [];\nfor(var i=1; i<csv.length;i++){\n csv[i].mu = parseFloat(csv[i].mu).toFixed(1);\n csv[i].sigma = parseFloat(csv[i].sigma).toFixed(1);\n csv[i].dt = new Date(Date.parse(csv[i].date));\n\n var res = parseFloat(csv[i].result);\n if (res < .5) {\n csv[i].result = \"loss\";\n } else if (res > .5) {\n csv[i].result = \"win\";\n } else {\n csv[i].result = \"draw\";\n }\n result.push(csv[i]);\n}\nmsg.payload = result;\n\nreturn msg;","outputs":1,"noerr":0,"x":429.3000793457031,"y":400.2669153213501,"wires":[["18d60280.ae51ce"]]},{"id":"1444eda7.0423a2","type":"ui_group","z":"","name":"","tab":"6bb5e46c.104aec","order":1,"disp":true,"width":"16","collapse":false},{"id":"6bb5e46c.104aec","type":"ui_tab","z":"","name":"UI Widget","icon":"dashboard","order":3}]