You'll need to download the needed files from here GitHub - leeoniya/uPlot: 📈 A small, fast chart for time series, lines, areas, ohlc & bars
and then serve them from your static folder.
If performance matters and you are ready for a bit of JavaScript struggle, It is the way to go.
Here's the starting point
[{"id":"d03aad8c.fcdf9","type":"ui_template","z":"c0ddb509.b04f48","group":"304730.1de8e8d","name":"chart","order":1,"width":"15","height":"8","format":"<script src=\"/uplot/uPlot.iife.min.js\"></script>\n<div id=\"chart\"></div>\n<script>\ndata = [[],[],[],[]];\ntopics = [\"InternalTopicForTime\",\"first\",\"second\",\"third\"]\nopts = {\n\twidth: 790,\n\theight: 350,\n\ttitle: \"u-Plot Live\",\n\tscales: {\n\t\tx: {\n\t\t\ttime: true,\n\t\t\t\n\t\t},\n\t},\n\tms:1,\n\t\n\tcursor: {\n\t\tdataIdx: (self, seriesIdx, hoveredIdx) => {\n\t\t\tlet seriesData = self.data[seriesIdx];\n\t\t\tif (seriesData[hoveredIdx] == null) {\n\t\t\t\tlet nonNullLft = hoveredIdx,\n\t\t\t\t\tnonNullRgt = hoveredIdx,\n\t\t\t\t\ti;\n\t\t\t\ti = hoveredIdx;\n\t\t\t\twhile (nonNullLft == hoveredIdx && i-- > 0) if (seriesData[i] != null) nonNullLft = i;\n\n\t\t\t\ti = hoveredIdx;\n\t\t\t\twhile (nonNullRgt == hoveredIdx && i++ < seriesData.length)\n\t\t\t\t\tif (seriesData[i] != null) nonNullRgt = i;\n\n\t\t\t\treturn nonNullRgt - hoveredIdx > hoveredIdx - nonNullLft ? nonNullLft : nonNullRgt;\n\t\t\t}\n\t\t\treturn hoveredIdx;\n\t\t},\n\t},\n\tseries: [\n\t {\n\t\t\tvalue: '{HH}:{mm}:{ss}',\n\t\t},\n\t\t{\n\t\t\tstroke: \"red\",\n\t\t//\tfill: \"rgba(255,0,0,0.1)\",\n\t\t\n\t\t\tspanGaps: true,\n\t\t},\n\t\t{\n\t\t\tstroke: \"yellow\",\n\t\t//\tfill: \"rgba(255,255,0,0.1)\",\n\t\t\n\t\t\tspanGaps: true,\n\t\t},\n\t\t{\n\t\t\tstroke: \"blue\",\n\t//\t\tfill: \"rgba(0,0,255,0.1)\",\n\t\t\t\n\t\t\tspanGaps: true,\n\t\t},\n\t],\n\taxes: [\n\t\t{\n\t\t\tstroke: '#f5f5dc',\n\t\t\tvalues: '{HH}:{mm}',\n\n\t\t\tgrid: {\n\t\t\t\twidth: 1 / devicePixelRatio,\n\t\t\t\tstroke: '#f5f5dc40',\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\twidth: 1 / devicePixelRatio,\n\t\t\t\tstroke: '#f5f5dc40',\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tstroke: '#f5f5dc',\n\t\t\t\n\t\t\tgrid: {\n\t\t\t\twidth: 1 / devicePixelRatio,\n\t\t\t\tstroke: '#f5f5dc40',\n\t\t\t},\n\t\t\tticks: {\n\t\t\t\twidth: 1 / devicePixelRatio,\n\t\t\t\tstroke: '#f5f5dc40',\n\t\t\t},\n\t\t},\n\t],\n};\nchart = new uPlot(opts, data, document.querySelector(\"#chart\"));\n\nfunction addChartPoint(val,topic,chart){\n let now = Date.now() \n let old = now - 1000 * 60 * 10\n topics.forEach((t,i) => {\n if(i == 0){\n data[i].push(now)\n \n }else{\n if(t == topic){\n data[i].push(val)\n }\n else{\n data[i].push(null)\n }\n }\n })\n if(data[0][0] < old){\n data.forEach(d => {\n d.shift() \n })\n }\n chart.setData(data);\n\n \n}\t\n(function(scope) {\n scope.$watch('msg', function(msg) {\n if (msg) {\n addChartPoint(msg.payload,msg.topic,chart) \n }\n });\n})(scope);\t\n\t\n\t\n</script>\n\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":750,"y":880,"wires":[[]]},{"id":"8add092.e71a0f8","type":"ui_template","z":"c0ddb509.b04f48","group":"304730.1de8e8d","name":"CSS","order":2,"width":0,"height":0,"format":"<link rel=\"stylesheet\" href=\"/uplot/uPlot.min.css\">\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":750,"y":840,"wires":[[]]},{"id":"80084862.4b7958","type":"inject","z":"c0ddb509.b04f48","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"4","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":840,"wires":[["ce98f28c.2c44b","d1cbaf33.01dbd","199fd4f5.95db2b"]]},{"id":"ce98f28c.2c44b","type":"delay","z":"c0ddb509.b04f48","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1000","randomLast":"3000","randomUnits":"milliseconds","drop":false,"x":300,"y":880,"wires":[["1f5e593f.7a4a57"]]},{"id":"d1cbaf33.01dbd","type":"delay","z":"c0ddb509.b04f48","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"200","randomLast":"400","randomUnits":"milliseconds","drop":false,"x":300,"y":920,"wires":[["dff1d044.a229b"]]},{"id":"199fd4f5.95db2b","type":"change","z":"c0ddb509.b04f48","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"first","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":840,"wires":[["c605cc0d.8e445"]]},{"id":"1f5e593f.7a4a57","type":"change","z":"c0ddb509.b04f48","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"second","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":880,"wires":[["c605cc0d.8e445"]]},{"id":"dff1d044.a229b","type":"change","z":"c0ddb509.b04f48","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"third","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":920,"wires":[["c605cc0d.8e445"]]},{"id":"c605cc0d.8e445","type":"random","z":"c0ddb509.b04f48","name":"","low":1,"high":"5000","inte":"true","property":"payload","x":620,"y":880,"wires":[["d03aad8c.fcdf9"]]},{"id":"304730.1de8e8d","type":"ui_group","name":"Chart","tab":"ebf9c239.14c15","order":3,"disp":true,"width":"15","collapse":false},{"id":"ebf9c239.14c15","type":"ui_tab","name":"Home","icon":"dashboard","order":1,"disabled":false,"hidden":false}]