function TimeChart() { var lineChart = {}; const timeFormat = 'YYYY-MM-DD HH:mm:ss'; const insertedValues = new Map(); const chartColors = { red: 'rgb(255, 99, 132)', orange: 'rgb(255, 159, 64)', yellow: 'rgb(255, 205, 86)', green: 'rgb(75, 192, 192)', blue: 'rgb(54, 162, 235)', purple: 'rgb(153, 102, 255)', grey: 'rgb(201, 203, 207)' }; const labelTemperatura = 'Temperatura'; const labelUmiditatea = 'Umiditatea'; const percentSymbol = ' %'; const degreeSymbol = ' \u2103'; function toDate(time) { return moment.utc(time, timeFormat); } var color = Chart.helpers.color; var config = { type: 'line', data: { labels: [ // Date/Time Objects ], datasets: [{ label: labelUmiditatea, backgroundColor: color(chartColors.blue).alpha(0.5).rgbString(), borderColor: chartColors.blue, fill: false, yAxisID: "h", data: [ // Umiditatea ], }, { label: labelTemperatura, backgroundColor: color(chartColors.red).alpha(0.5).rgbString(), borderColor: chartColors.red, fill: false, yAxisID: "t", data: [ // Temperatura ], }] }, options: { title: { text: 'Meteo' }, tooltips: { callbacks: { label: function (tooltipItem, data) { var label = data.datasets[tooltipItem.datasetIndex].label || ''; var unitOfMesure = ''; if (label === labelTemperatura) { unitOfMesure = degreeSymbol; } else if (label === labelUmiditatea) { unitOfMesure = percentSymbol; } if (label) { label += ': '; } label += Math.round(tooltipItem.yLabel * 100) / 100; return label + unitOfMesure; } } }, scales: { xAxes: [{ type: 'time', time: { unit: 'hour', unitStepSize: 1, tooltipFormat: 'HH:mm:ss, DD MMM', displayFormats: { hour: 'HH:mm' } }, scaleLabel: { display: true } }], yAxes: [{ id: 'h', scaleLabel: { display: true }, gridLines: { display: false }, ticks: { fontStyle: "bold", fontColor: chartColors.blue, suggestedMax: 65, suggestedMin: 25, callback: function (value, index, values) { return value + '%'; } } }, { id: 't', position: 'right', scaleLabel: { display: true }, gridLines: { display: false }, ticks: { fontStyle: "bold", fontColor: chartColors.red, suggestedMax: 25, suggestedMin: 21, callback: function (value, index, values) { return Number(value).toFixed(1) + ' \u2103'; } } }] }, } }; function addData(index, xValue, yValue) { if (config.data.datasets.length > 0) { if (!insertedValues.has(xValue + index)) { insertedValues.set(xValue + index, {}); config.data.datasets[index].data.push({x: toDate(xValue), y: yValue}); update(); } } } function update() { var dataValues = config.data.datasets[0].data; if (dataValues.length > 0) { var minXValue = dataValues[0].x.clone().local().startOf('day'); var maxXValue = dataValues[dataValues.length - 1].x.clone().local().startOf('day').add(1, 'day'); config.options.scales.xAxes[0].ticks.min = minXValue; config.options.scales.xAxes[0].ticks.max = maxXValue; } publicApi.lineChart.update(); } function setLineChart(ctx) { publicApi.lineChart = new Chart(ctx, config); } var publicApi = { setLineChart: setLineChart, addData: addData, update: update }; return publicApi; }