Fixed
[{"id":"ea7c02fa77fe6efc","type":"ui-template","z":"a1ded7aeb5c2fa56","group":"1c6f457dfe15977b","page":"","ui":"","name":"Custom Line Chart","order":1,"width":"6","height":"5","head":"","format":"<template>\n <div class=\"base-container\">\n <div class=\"chart-container\" ><canvas ref=\"chart\" /></div>\n </div> \n</template>\n\n<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n\n<script>\n export default {\n data() { \n return {\n keep:10000, //keep data for 10 seconds \n }\n },\n \n mounted() {\n this.$socket.on('msg-input:' + this.id, this.onInput)\n\n // code here when the component is first loaded\n let interval = setInterval(() => {\n if (window.Chart) {\n // the chart.js is loaded, so we can now use it\n clearInterval(interval);\n this.draw()\n }\n }, 100);\n },\n methods: {\n draw () {\n const ctx = this.$refs.chart\n const datasets = []\n \n // Render the chart\n const chart = new Chart(ctx, {\n \n type: 'line',\n data: {\n datasets: [\n {label: \"first\", data:[]},\n {label: \"second\",data:[]}\n ]\n },\n options: {\n maintainAspectRatio: false,//let the chart take the shape of the container\n animation: false,// do not animate\n responsive: true,// and please be responisve\n scales: {\n x: {\n type: 'time',//x-axis is configured to be time\n time: {\n unit: 'second',//time resolution second\n displayFormats: {\n second: 'HH:mm:ss' // render ticks in that format\n }\n },\n ticks: {\n stepSize: 1, // by default render gridlaine and tick for defined step (1 here means every second)\n autoSkip: false, // turn off automatic tick count calculations\n maxTicksLimit:10, //limit total ticks amount (overrides setpSize obviously)\n maxRotation:0 //do not allow ticks to be rotated\n }\n }\n },\n elements:{\n line:{\n borderWidth:2,//line thickness\n tension:0.3 //line curvature \n },\n point:{\n pointRadius:0 //remove points (any positive number makes points at defined size)\n }\n },\n parsing: {\n xAxisKey: 'time',\n yAxisKey: 'value'\n },\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Chart.js Line Chart. Basic Options'\n }\n } \n },\n });\n // make this available to all elements of the component\n this.chart = chart\n console.log(this.data)\n },\n clearOldData(){\n this.chart.data.datasets.forEach(dataset => {\n dataset.data = dataset.data.filter(point => point.time > Date.now() - this.keep)\n })\n },\n clearChart(){\n this.chart.data.datasets.forEach(dataset => {\n dataset.data = []\n })\n this.chart.update()\n },\n\n addDataPoint(topic,valueOrFulldata){\n let dataset = this.chart.data.datasets.find(ds => ds.label == topic)\n if(typeof valueOrFulldata === \"number\"){\n dataset.data.push({\n time: (new Date()).getTime(),\n value: valueOrFulldata\n })\n } \n else{\n dataset.data.push({\n time: valueOrFulldata.time,\n value: valueOrFulldata.value\n })\n } \n \n this.chart.update()\n },\n onInput (msg) {\n if(Array.isArray(msg.payload)){\n if(msg.payload.length == 0){\n this.clearChart()\n return\n }\n else{\n // historycal data. for each item in array add the data to proper dataset\n // the data has format [{topic:\"first\",time:123456789,value:120}, and many more of such ...]\n msg.payload.forEach(point => {\n this.addDataPoint(point.topic,point)\n }) \n }\n }\n else{\n this.clearOldData()\n this.addDataPoint(msg.topic,msg.payload)\n }\n }\n }\n }\n</script>\n<style>\n.base-container{\n width:100%;\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n container: chat / size;/*make this container available for container querys*/\n}\n.chart-container{\n position: relative;\n margin: auto;\n height: 100cqb;/*use container query units to give full height of the container (100% of container height) */\n width: 100cqi;/*use container query units to give full width of the container (100% of container height)*/\n display: flex;\n justify-content: center;\n align-items: center;\n}\n \n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":710,"y":500,"wires":[[]]},{"id":"caff24894c090d95","type":"ui-slider","z":"a1ded7aeb5c2fa56","group":"1c6f457dfe15977b","name":"Slider 1","label":"Slider 1","tooltip":"","order":2,"width":0,"height":0,"passthru":false,"outs":"all","topic":"slider-1","topicType":"str","thumbLabel":"true","showTicks":"always","min":0,"max":10,"step":1,"className":"","color":"","colorTrack":"","colorThumb":"","x":260,"y":500,"wires":[["7470f177a4852b22"]]},{"id":"7470f177a4852b22","type":"function","z":"a1ded7aeb5c2fa56","name":"randomly choose topic","func":"const t = Math.random() > .5 ? \"second\" : \"first\"\nmsg.topic = t\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":500,"wires":[["ea7c02fa77fe6efc"]]},{"id":"1c6f457dfe15977b","type":"ui-group","name":"Custom Bar Chart","page":"d0621b8f20aee671","width":"6","height":"1","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false"},{"id":"d0621b8f20aee671","type":"ui-page","name":"Charts","ui":"29792df7d7b05e2e","path":"/charts","icon":"home","layout":"notebook","theme":"5075a7d8e4947586","order":2,"className":"","visible":"true","disabled":"false"},{"id":"29792df7d7b05e2e","type":"ui-base","name":"My Dashboard","path":"/dashboard","appIcon":"","includeClientData":true,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"showPageTitle":true,"navigationStyle":"default","titleBarStyle":"default"},{"id":"5075a7d8e4947586","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094CE","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px"}}]