Display a chart in PDF

I prepared a working example:

There is still an error: "SyntaxError: Unexpected token S in JSON at position 0", but the PDF is generating correctly.

[{"id":"e26c21c5.1443c","type":"function","z":"783f535.d2680ac","name":"contents","func":"//globals\nvar CompanyName = \"CompanyName\";\nvar CompanyLogoURL = \"https://dynamic.brandcrowd.com/asset/logo/522494d1-50ee-4316-bbc9-58b1f90bab5e/logo?v=4\";\n\n//flow variables\nvar startdate = 1578485832986;  //date in unix timestamp\nvar enddate = 1578485832986 + 24*60*60*1000;    //next day ;)\nvar selected_machine = \"MachineName\";\nvar selected_machine_name = \"MachineName2\";\n\nvar content_var_prod_mean = 123;\nvar content_var_prod_max = 456;\nvar content_var_prod_min = 789;\nvar content_var_prod_sum = 1233;\n\nvar content_var_inac_count = 2;\nvar content_var_inac_sum = 5;\nvar content_var_inac_mean = 7;\n\n\nvar options = {year: 'numeric', month: '2-digit', day: '2-digit'};\nvar d = new Date();\nvar dateNow = d.toLocaleDateString('pl-PL', options);\nd = new Date(startdate);\ndateFrom = d.toLocaleDateString('pl-PL', options);\nd = new Date(enddate);\ndateTo = d.toLocaleDateString('pl-PL', options);\n\n\nvar content_table_worktime = flow.get('flow_content_table_worktime')||0;\n\n//data for circle diagram\nvar contents_diag_circle_data = \"[80,23,15,7,1]\";   //only numerical data\nvar contents_diag_circle_label = \"[\\\"Hello\\\",\\\"Hi\\\",\\\"Howdy\\\",\\\"Wadup\\\",\\\"Yo\\\"]\";\nvar contents_diag_circle_color = \"[\\\"#39ca74\\\",\\\"#e54d42\\\",\\\"#f0c330\\\",\\\"#3999d8\\\",\\\"#35485d\\\"]\";\n\n\n\nvar contents = {\n    CompanyName: CompanyName,\n    CompanyLogoURL: CompanyLogoURL,\n    machineName: selected_machine_name,\n    dateNow: dateNow,\n    dateFrom: dateFrom,\n    dateTo: dateTo,\n    content_table_worktime: content_table_worktime,\n    content_var_prod_mean: content_var_prod_mean,\n    content_var_prod_max: content_var_prod_max,\n    content_var_prod_min: content_var_prod_min,\n    content_var_prod_sum: content_var_prod_sum,\n    content_var_inac_count: content_var_inac_count,\n    content_var_inac_sum: content_var_inac_sum,\n    content_var_inac_mean: content_var_inac_mean,\n    \n    contents_diag_circle_data: contents_diag_circle_data,\n    contents_diag_circle_label: contents_diag_circle_label,\n    contents_diag_circle_color: contents_diag_circle_color\n}\n\nreturn contents;","outputs":1,"noerr":0,"x":420,"y":480,"wires":[["a1011341.14d6a","d12b0fc4.66fc2"]]},{"id":"d12b0fc4.66fc2","type":"debug","z":"783f535.d2680ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":570,"y":520,"wires":[]},{"id":"d070f7c6.9f0fa8","type":"debug","z":"783f535.d2680ac","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":810,"y":520,"wires":[]},{"id":"a1011341.14d6a","type":"template","z":"783f535.d2680ac","name":"Raport_template1_main","field":"payload","fieldType":"msg","format":"html","syntax":"mustache","template":"<html>\n<script>\n\ndiv {\n  width: 100%;\n  text-align: center;\n}\ndiv p {\n  text-align: center;\n  font-family: \"Arial\", sans-serif;\n  font-size: 16px;\n  color: #bdc3c7;\n}\n</script>\n\n <body>\n<p><span style=\"color: #008080;\">&nbsp;</span></p>\n<table style=\"height: 27px; margin-left: auto; margin-right: auto;\" border=\"1\" width=\"90%\">\n<tbody>\n<tr>\n<td style=\"width: 75%;\"><span style=\"color: #008080;\"><strong>Raport</strong></span></td>\n<td style=\"width: 25%;\"><span style=\"color: #008080;\"><strong><img style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"{{CompanyLogoURL}}\" alt=\"{{CompanyName}}\" width=\"150\" height=\"33\" /></strong></span></td>\n</tr>\n</tbody>\n</table>\n<table style=\"height: 12px; width: 90%; margin-left: auto; margin-right: auto;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 15%;\"><span style=\"color: #008080;\"><strong>Maszyna:</strong></span></td>\n<td style=\"width: 35%;\"><span style=\"color: #008080;\">{{machineName}}</span></td>\n<td style=\"width: 25%;\"><span style=\"color: #008080;\"><strong>OD:</strong> {{dateFrom}}</span></td>\n<td style=\"width: 25%;\"><span style=\"color: #008080;\"><strong>DO:</strong> {{dateTo}}</span></td>\n</tr>\n</tbody>\n</table>\n<table style=\"height: 12px; width: 90%; margin-left: auto; margin-right: auto;\" border=\"1\">\n<tbody>\n<tr>\n<td style=\"width: 10%;\"><span style=\"color: #008080;\"><strong>Firma:</strong></span></td>\n<td style=\"width: 90%;\"><span style=\"color: #008080;\">{{CompanyName}}</span></td>\n</tr>\n</tbody>\n</table>\n<table style=\"height: 26px; margin-left: auto; margin-right: auto;\" width=\"90%\">\n<tbody>\n<tr>\n<td style=\"width: 512.267px;\"><span style=\"color: #008080;\"><strong>Wydajność</strong></span></td>\n</tr>\n</tbody>\n</table>\n<table style=\"height: 243px; margin-left: auto; margin-right: auto;\" border=\"1\" width=\"90%\">\n<tbody>\n<tr style=\"height: 249px;\">\n<td style=\"width: 540.8px; height: 249px; text-align: center;\"><span style=\"color: #008080;\">  \n\n<canvas id=\"canvas\" width=\"600\" height=\"400\"></canvas>\n  \n</span></td>\n</tr>\n<tr style=\"height: 33.6px;\">\n<td style=\"width: 540.8px; height: 33.6px;\">\n<table style=\"height: 15px;\" width=\"100%\">\n<tbody>\n<tr>\n<td style=\"width: 25%;\"><strong><span style=\"color: #008080;\">Średnia: </span></strong><span style=\"color: #008080;\">{{content_var_prod_mean}}</span></td>\n<td style=\"width: 25%;\"><strong><span style=\"color: #008080;\">MAX: </span></strong><span style=\"color: #008080;\">{{content_var_prod_max}}</span></td>\n<td style=\"width: 25%;\"><strong><span style=\"color: #008080;\">MIN: </span></strong><span style=\"color: #008080;\">{{content_var_prod_min}}</span></td>\n<td style=\"width: 25%;\"><strong><span style=\"color: #008080;\">SUMA: </span></strong><span style=\"color: #008080;\">{{content_var_prod_sum}}</span></td>\n</tr>\n</tbody>\n</table>\n</td>\n</tr>\n</tbody>\n</table>\n{{{content_table_worktime}}}\n<br >\n\n<div>\n  <canvas id=\"canvas\" width=\"600\" height=\"400\">\n  </canvas>\n  <p>Change the 'myData' values to see the labels dynamically adjust.</p>\n</div>\n\n\n<script>\n/* <3 \nhttp://html5.litten.com/graphing-data-in-the-html5-canvas-element-part-iv-simple-pie-charts/\n*/\n\nvar myColor = {{{contents_diag_circle_color}}};\nvar myData = {{contents_diag_circle_data}};\nvar myLabel = {{{contents_diag_circle_label}}};\n\nfunction getTotal(){\n  var myTotal = 0;\n  for (var j = 0; j < myData.length; j++) {\n    myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;\n  }\n  return myTotal;\n}\n\nfunction plotData() {\n  var canvas;\n  var ctx;\n  var lastend = 0;\n  var myTotal = getTotal();\n  var doc;\n  canvas = document.getElementById(\"canvas\");\n  var x = (canvas.width)/2;\n  var y = (canvas.height)/2;\n  var r = 150;\n  \n  ctx = canvas.getContext(\"2d\");\n  ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n  for (var i = 0; i < myData.length; i++) {\n    ctx.fillStyle = myColor[i];\n    ctx.beginPath();\n    ctx.moveTo(x,y);\n    ctx.arc(x,y,r,lastend,lastend+(Math.PI*2*(myData[i]/myTotal)),false);\n    ctx.lineTo(x,y);\n    ctx.fill();\n    \n    // Now the pointers\n    ctx.beginPath();\n    var start = [];\n    var end = [];\n    var last = 0;\n    var flip = 0;\n    var textOffset = 0;\n    var precentage = (myData[i]/myTotal)*100;\n    start = getPoint(x,y,r-20,(lastend+(Math.PI*2*(myData[i]/myTotal))/2));\n    end = getPoint(x,y,r+20,(lastend+(Math.PI*2*(myData[i]/myTotal))/2));\n    if(start[0] <= x)\n    {\n      flip = -1;\n      textOffset = -110;\n    }\n    else\n    {\n      flip = 1;\n      textOffset = 10;\n    }\n    ctx.moveTo(start[0],start[1]);\n    ctx.lineTo(end[0],end[1]);\n    ctx.lineTo(end[0]+120*flip,end[1]);\n    ctx.strokeStyle = \"#bdc3c7\";\n    ctx.lineWidth   = 2;\n    ctx.stroke();\n    // The labels\n    ctx.font=\"17px Arial\";\n    ctx.fillText(myLabel[i]+\" \"+precentage.toFixed(2)+\"%\",end[0]+textOffset,end[1]-4); \n    // Increment Loop\n    lastend += Math.PI*2*(myData[i]/myTotal);\n    \n  }\n}\n// Find that magical point\nfunction getPoint(c1,c2,radius,angle) {\n  return [c1+Math.cos(angle)*radius,c2+Math.sin(angle)*radius];\n}\n// The drawing\nplotData();\n\n</script>\n </body>\n</html>","output":"str","x":630,"y":480,"wires":[["d070f7c6.9f0fa8","45fa9069.d09e6"]]},{"id":"45fa9069.d09e6","type":"function","z":"783f535.d2680ac","name":"path","func":"\nvar main_path = \"C:/AAAtemp/\";  //please type your path\nvar name = \"Raport.pdf\";\n\nmsg.filename = main_path + name;\nreturn msg;","outputs":1,"noerr":0,"x":870,"y":480,"wires":[["366155a5.fee86a"]]},{"id":"366155a5.fee86a","type":"HTML-PDF","z":"783f535.d2680ac","name":"HTML-PDF","output":"file","x":1050,"y":480,"wires":[[]]},{"id":"e8e37d37.081ef","type":"comment","z":"783f535.d2680ac","name":"edit your path","info":"","x":870,"y":440,"wires":[]},{"id":"f3cb7a4.6ea3d88","type":"tableify","z":"783f535.d2680ac","name":"","before":"","after":"","tableStyle":"id=\"table\" border=\"1\" width=\"90%\" cellpadding=\"0\" align=\"center\" ","theadStyle":"width: 10%; color: #008080;","tbodyStyle":"","trStyle":"","tdStyle":"width: 10%; color: #008080;","x":520,"y":340,"wires":[["aa42809b.90314"]]},{"id":"aa42809b.90314","type":"function","z":"783f535.d2680ac","name":"flow_content_table_worktime","func":"msg.topic = \"flow_content_table_worktime\";\nreturn msg;","outputs":1,"noerr":0,"x":740,"y":340,"wires":[["1200576f.ea6529"]]},{"id":"1200576f.ea6529","type":"function","z":"783f535.d2680ac","name":"flow set","func":"var value = msg.payload;\nflow.set(msg.topic,value);\nnode.status({fill:\"blue\",shape:\"ring\",text:msg.topic +\" : \"+ \"+table\"});\nreturn msg;","outputs":1,"noerr":0,"x":960,"y":340,"wires":[["e26c21c5.1443c"]]},{"id":"b60fbe1c.e45bd","type":"comment","z":"783f535.d2680ac","name":"tableify data","info":"https://flows.nodered.org/node/node-red-contrib-tableify","x":530,"y":300,"wires":[]},{"id":"69139d9a.cf39e4","type":"function","z":"783f535.d2680ac","name":"build array (2)","func":"var arr =[[\"Paul\",\"Doe\",24],[\"Greg\",\"Jones\",31],[\"Able\",\"Smith\",29]];\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"x":340,"y":340,"wires":[["f3cb7a4.6ea3d88"]]},{"id":"d08a681f.5bbda8","type":"inject","z":"783f535.d2680ac","name":"Go","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":170,"y":340,"wires":[["69139d9a.cf39e4"]]},{"id":"5d2839ca.05f928","type":"comment","z":"783f535.d2680ac","name":"example - readme","info":"oryginal post:\nhttps://discourse.nodered.org/t/display-a-chart-in-pdf/20040/13\n\nother diagrams:\nhttps://html5.litten.com/graphing-data-in-the-html5-canvas-element-part-iv-simple-pie-charts/\n\nMain contributors:\nwojtekdera\nhathemi\n","x":170,"y":240,"wires":[]},{"id":"c4586094.3096a","type":"comment","z":"783f535.d2680ac","name":"generate example array","info":"","x":340,"y":300,"wires":[]},{"id":"1d22d083.fbfdff","type":"inject","z":"783f535.d2680ac","name":"Go","topic":"","payload":"1","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":"","x":190,"y":480,"wires":[["e26c21c5.1443c"]]}]

It outputs a PDF in path: C:\AAAtemp (default) like:

I hope it will help you. Klick like if so :wink:
Best regards

3 Likes