Apexcharts how to add js scripts

Hi,

I've been trying to make apexcharts to work on the dashboard via template + ui_template nodes.
The chart works only the first time after deploy, afterwards it does not.

Heres the flow:

[{"id":"320dd3f4.959a0c","type":"ui_template","z":"d7ed593d.5dede8","group":"44218e32.34a34","name":"","order":0,"width":"24","height":"10","format":"","storeOutMessages":false,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":480,"y":60,"wires":[[]]},{"id":"f2298587.17ad98","type":"inject","z":"d7ed593d.5dede8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":120,"y":60,"wires":[["cccc681a.03f018"]]},{"id":"cccc681a.03f018","type":"template","z":"d7ed593d.5dede8","name":"apex timeline","field":"template","fieldType":"msg","format":"html","syntax":"mustache","template":"<html>\n    <head>\n        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n        <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css\">\n        <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js\"></script>\n        <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js\"></script>\n        <script src=\"https://cdn.jsdelivr.net/npm/apexcharts\"></script>\n    </head>\n    <body>\n        <div id=\"chart_1\"></div>\n        <script>\n            var options = {\n                series: [\n                  {\n                    name: 'Bob',\n                    data: [\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-08').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-02').getTime(),\n                          new Date('2019-03-05').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-07').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-03').getTime(),\n                          new Date('2019-03-09').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-08').getTime(),\n                          new Date('2019-03-11').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Validation',\n                        y: [\n                          new Date('2019-03-11').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-01').getTime(),\n                          new Date('2019-03-03').getTime()\n                        ],\n                      }\n                    ]\n                  },\n                  {\n                    name: 'Joe',\n                    data: [\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-02').getTime(),\n                          new Date('2019-03-05').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-06').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ],\n                        goals: [\n                          {\n                            name: 'Break',\n                            value: new Date('2019-03-10').getTime(),\n                            strokeColor: '#CD2F2A'\n                          }\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-03').getTime(),\n                          new Date('2019-03-07').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Deployment',\n                        y: [\n                          new Date('2019-03-20').getTime(),\n                          new Date('2019-03-22').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-10').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ]\n                      }\n                    ]\n                  },\n                  {\n                    name: 'Dan',\n                    data: [\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-10').getTime(),\n                          new Date('2019-03-17').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Validation',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-09').getTime()\n                        ],\n                        goals: [\n                          {\n                            name: 'Break',\n                            value: new Date('2019-03-07').getTime(),\n                            strokeColor: '#CD2F2A'\n                          }\n                        ]\n                      },\n                    ]\n                  }\n                ],\n                  chart: {\n                  height: 450,\n                  type: 'rangeBar'\n                },\n                plotOptions: {\n                  bar: {\n                    horizontal: true,\n                    barHeight: '80%'\n                  }\n                },\n                xaxis: {\n                  type: 'datetime'\n                },\n                stroke: {\n                  width: 1\n                },\n                fill: {\n                  type: 'solid',\n                  opacity: 1,\n                },\n                legend: {\n                  position: 'top',\n                  horizontalAlign: 'left'\n                }\n                };\n        \n            var chart_1 = new ApexCharts(document.querySelector(\"#chart_1\"), options);\n            chart_1.render();\n        </script>\n    </body>\n</html>\n\n\n\n","output":"str","x":290,"y":60,"wires":[["320dd3f4.959a0c"]]},{"id":"44218e32.34a34","type":"ui_group","name":"1","tab":"27c6cdce.0f2ff2","order":1,"disp":true,"width":"30","collapse":false},{"id":"27c6cdce.0f2ff2","type":"ui_tab","name":"DA","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

There is virtualy no info whatsoever how to implement other chart into existing dashboard. No tutorial, no explanations no nothing. This has started to get really frustrating - the problem is I only have basic js knowledge and thats it.

I have copied the code (more or less) from this video: Node-red:Apex Chart - YouTube
This is the only "tutorial" on internet I could find.

This is the error message I'm keep ketting:

VM1837:158 Uncaught ReferenceError: ApexCharts is not defined
    at <anonymous>:158:27
    at b (app.min.js:20)
    at He (app.min.js:20)
    at S.fn.init.append (app.min.js:20)
    at S.fn.init.<anonymous> (app.min.js:20)
    at $ (app.min.js:20)
    at S.fn.init.html (app.min.js:20)
    at app.min.js:592
    at m.$digest (app.min.js:174)
    at m.$apply (app.min.js:177)

Please can anybody help me with this one, and also with a possible solution to import scripts from local storage (C:\apexcharts-bundle\dist)

Thank you very much in advance

That isn't what Dashboard is for. It is aimed at people with no html/js experience and enables them to have a UI simply by providing nodes in Node-RED flows.

If you want a custom UI, you may wish to try uibuilder.

It is helpful to share the ui_template code directly not just the flow file (since that takes time to paste into NR and tidy up afterwards).

If I am reading the raw flow correctly, I think you have assumed that the ui_template needs to have a full HMTL file. But the ui_template node is just a snippet that is inserted into the Dashboard page.

All you need to do is put the script file into the folder you have declared in settings.js as the static resources folder.

Thanks for answering.

Since this is only my sidejob I can't afford to dedicate more time to develop my dashboard in uibuilder - my backup json has got 1,5mb. Version 2.0 will be made in uibuilder

I would like to use inject + template + (empty)ui_template beucase later I need to add sockets and append data arrays.
Template code:

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
    </head>
    <body>
        <div id="chart_1"></div>
        <script>
            var options = {
                series: [
                  {
                    name: 'Bob',
                    data: [
                      {
                        x: 'Design',
                        y: [
                          new Date('2019-03-05').getTime(),
                          new Date('2019-03-08').getTime()
                        ]
                      },
                      {
                        x: 'Code',
                        y: [
                          new Date('2019-03-02').getTime(),
                          new Date('2019-03-05').getTime()
                        ]
                      },
                      {
                        x: 'Code',
                        y: [
                          new Date('2019-03-05').getTime(),
                          new Date('2019-03-07').getTime()
                        ]
                      },
                      {
                        x: 'Test',
                        y: [
                          new Date('2019-03-03').getTime(),
                          new Date('2019-03-09').getTime()
                        ]
                      },
                      {
                        x: 'Test',
                        y: [
                          new Date('2019-03-08').getTime(),
                          new Date('2019-03-11').getTime()
                        ]
                      },
                      {
                        x: 'Validation',
                        y: [
                          new Date('2019-03-11').getTime(),
                          new Date('2019-03-16').getTime()
                        ]
                      },
                      {
                        x: 'Design',
                        y: [
                          new Date('2019-03-01').getTime(),
                          new Date('2019-03-03').getTime()
                        ],
                      }
                    ]
                  },
                  {
                    name: 'Joe',
                    data: [
                      {
                        x: 'Design',
                        y: [
                          new Date('2019-03-02').getTime(),
                          new Date('2019-03-05').getTime()
                        ]
                      },
                      {
                        x: 'Test',
                        y: [
                          new Date('2019-03-06').getTime(),
                          new Date('2019-03-16').getTime()
                        ],
                        goals: [
                          {
                            name: 'Break',
                            value: new Date('2019-03-10').getTime(),
                            strokeColor: '#CD2F2A'
                          }
                        ]
                      },
                      {
                        x: 'Code',
                        y: [
                          new Date('2019-03-03').getTime(),
                          new Date('2019-03-07').getTime()
                        ]
                      },
                      {
                        x: 'Deployment',
                        y: [
                          new Date('2019-03-20').getTime(),
                          new Date('2019-03-22').getTime()
                        ]
                      },
                      {
                        x: 'Design',
                        y: [
                          new Date('2019-03-10').getTime(),
                          new Date('2019-03-16').getTime()
                        ]
                      }
                    ]
                  },
                  {
                    name: 'Dan',
                    data: [
                      {
                        x: 'Code',
                        y: [
                          new Date('2019-03-10').getTime(),
                          new Date('2019-03-17').getTime()
                        ]
                      },
                      {
                        x: 'Validation',
                        y: [
                          new Date('2019-03-05').getTime(),
                          new Date('2019-03-09').getTime()
                        ],
                        goals: [
                          {
                            name: 'Break',
                            value: new Date('2019-03-07').getTime(),
                            strokeColor: '#CD2F2A'
                          }
                        ]
                      },
                    ]
                  }
                ],
                  chart: {
                  height: 450,
                  type: 'rangeBar'
                },
                plotOptions: {
                  bar: {
                    horizontal: true,
                    barHeight: '80%'
                  }
                },
                xaxis: {
                  type: 'datetime'
                },
                stroke: {
                  width: 1
                },
                fill: {
                  type: 'solid',
                  opacity: 1,
                },
                legend: {
                  position: 'top',
                  horizontalAlign: 'left'
                }
                };
        
            var chart_1 = new ApexCharts(document.querySelector("#chart_1"), options);
            chart_1.render();
        </script>
    </body>
</html>

Can I ask a bit more help with this one?

TotallyInformation
All you need to do is put the script file into the folder you have declared in settings.js as the static resources folder.

Not sure where is settings.js static resources folder declared:
here:
//userDir: '/home/nol/.node-red/',

here:
//nodesDir: '/home/nol/.node-red/nodes',

or here:
//httpStatic: '/home/nol/node-red-static/',
?

So, do I need to move all js files from apexcharts and chartjs to one folder?

One more question: This is the error messages after installing apexcharts or chartjs locally:

npm install chart.js
npm WARN saveError ENOENT: no such file or directory, open '/home/pi/package.json'
npm WARN enoent ENOENT: no such file or directory, open '/home/pi/package.json'
npm WARN pi No description
npm WARN pi No repository field.
npm WARN pi No README data
npm WARN pi No license field.

+ chart.js@3.5.0
added 1 package and audited 106 packages in 5.488s

1 package is looking for funding
  run `npm fund` for details

found 7 vulnerabilities (3 moderate, 3 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details

Not sure what does it mean and how to fix it?

I think you may be over-complecating things.

You can use >1 ui_template. Use 1 for anything static like attaching the external scripts - don't send anything to that, just have it as a stand-alone node.

Another ui_template node can then be used to handle sending of data. However, remember that all of the data processing happening in the front-end is embedded within the Angular v1 app. So you can't just send some data and expect it to magically appear like it does with the other Dashboard nodes (they handle the magic for you, the ui_template node does not). I have some example code on my website and you can probably find it in the Cookbook as well.

You don't need any of the html, head or body tags - these are part of the Dashboard framework. The css and external script links can go into the ui_template that has no inputs as can the static div. That is because you only ever need to deal with it once.

That one

You don't HAVE to, you may choose to.

You appear to be trying to install to the Pi uses home folder. If you only need the files, either use them from a CDN has you have been doing or download them direct from GitHub.

im not sure but i think this happens because you are trying to create the chart before the dashboard elements are ready/drawn. maybe the developers of the dashboard can better explain if this is the case

One possible workaround is to delay in a setTimeout of 1 second the drawing of your chart.

Test Flow:

[{"id":"320dd3f4.959a0c","type":"ui_template","z":"4895ea10b4ee9ead","group":"44218e32.34a34","name":"","order":0,"width":"24","height":"10","format":"<html>\n\n<head>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <!-- <link rel=\"stylesheet\" href=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css\"> -->\n  <!-- <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js\"></script> -->\n  <!-- <script src=\"https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js\"></script> -->\n  <script src=\"https://cdn.jsdelivr.net/npm/apexcharts\"></script>\n</head>\n\n<body>\n  <div id=\"chart_1\" style=\"width:900px\"></div>\n  <script>\n    var options = {\n                series: [\n                  {\n                    name: 'Bob',\n                    data: [\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-08').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-02').getTime(),\n                          new Date('2019-03-05').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-07').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-03').getTime(),\n                          new Date('2019-03-09').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-08').getTime(),\n                          new Date('2019-03-11').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Validation',\n                        y: [\n                          new Date('2019-03-11').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-01').getTime(),\n                          new Date('2019-03-03').getTime()\n                        ],\n                      }\n                    ]\n                  },\n                  {\n                    name: 'Joe',\n                    data: [\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-02').getTime(),\n                          new Date('2019-03-05').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Test',\n                        y: [\n                          new Date('2019-03-06').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ],\n                        goals: [\n                          {\n                            name: 'Break',\n                            value: new Date('2019-03-10').getTime(),\n                            strokeColor: '#CD2F2A'\n                          }\n                        ]\n                      },\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-03').getTime(),\n                          new Date('2019-03-07').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Deployment',\n                        y: [\n                          new Date('2019-03-20').getTime(),\n                          new Date('2019-03-22').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Design',\n                        y: [\n                          new Date('2019-03-10').getTime(),\n                          new Date('2019-03-16').getTime()\n                        ]\n                      }\n                    ]\n                  },\n                  {\n                    name: 'Dan',\n                    data: [\n                      {\n                        x: 'Code',\n                        y: [\n                          new Date('2019-03-10').getTime(),\n                          new Date('2019-03-17').getTime()\n                        ]\n                      },\n                      {\n                        x: 'Validation',\n                        y: [\n                          new Date('2019-03-05').getTime(),\n                          new Date('2019-03-09').getTime()\n                        ],\n                        goals: [\n                          {\n                            name: 'Break',\n                            value: new Date('2019-03-07').getTime(),\n                            strokeColor: '#CD2F2A'\n                          }\n                        ]\n                      },\n                    ]\n                  }\n                ],\n                  chart: {\n                  height: 450,\n                  type: 'rangeBar'\n                },\n                plotOptions: {\n                  bar: {\n                    horizontal: true,\n                    barHeight: '80%'\n                  }\n                },\n                xaxis: {\n                  type: 'datetime'\n                },\n                stroke: {\n                  width: 1\n                },\n                fill: {\n                  type: 'solid',\n                  opacity: 1,\n                },\n                legend: {\n                  position: 'top',\n                  horizontalAlign: 'left'\n                }\n                };\n        \n           \n\n            setTimeout(()=> {\n\n             var chart_1 = new ApexCharts(document.querySelector(\"#chart_1\"), options);\n             chart_1.render();\n           },1000) \n          \n  </script>\n</body>\n\n</html>","storeOutMessages":false,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":640,"y":1320,"wires":[[]]},{"id":"f2298587.17ad98","type":"inject","z":"4895ea10b4ee9ead","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"","payloadType":"date","x":380,"y":1320,"wires":[["320dd3f4.959a0c"]]},{"id":"44218e32.34a34","type":"ui_group","name":"Apexchart","tab":"27c6cdce.0f2ff2","order":1,"disp":true,"width":"30","collapse":false},{"id":"27c6cdce.0f2ff2","type":"ui_tab","name":"DA","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

2 Likes

It works every time now, thank you!

The charts now loads immediatelly after redeploy. How to make it appear only on my input?

I have put the files in this folder:

C:/Users/rtkl1/.node-red/node-red-static/

But node-red still wont load the script with this line:

<script src="http://localhost:1880/apexcharts.js"></script>

Http static:

httpStatic: 'C:/Users/rtkl1/.node-red/node-red-static/',

That will only work if the client browser is on the same device as the Node-RED server.

By the way i later noticed that the NR dashboard theme was overriding the chart's svg fill css property.
If you have this problem also, set in the dashboard Options to use Angular theme. (source)

image image

Select the ui_template node in its Help tab the 2nd example code snippet, describes how you can $watch for incoming msgs. If you send a msg (to ui_template) that has the same structure as your chart's options then it will be more easy to create and render a new chart with every new set of data.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.