Básicamente
Cada vez que llamo a addData como
addData("TEST1", 1);o
addData("TEST2", 1);luego verifico si el gráfico llamado "TEST1" ya existe y, si existe, devuelvo el objeto del gráfico y, si no, creo un nuevo
y luego inserto datos en él
y funciona hasta el punto de que cuando creo, por ejemplo, el segundo gráfico, el primero desaparece
¿pero por qué?
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <div id="charts"> </div> <script> var dict = new Object(); function addData(name, data) { var chart = dict[name]; if (chart == undefined) { console.log("adding chart:" + name); chart = AddChart(name); } else { console.log("skipping chart creation:" + name); } chart.data.labels.push(new Date().toLocaleTimeString()); chart.data.datasets.forEach((dataset) => { dataset.data.push(data); }); chart.update(); } function AddChart(name) { const data = { labels: [], datasets: [{ label: name, backgroundColor: 'rgb(255, 99, 132)', borderColor: 'rgb(255, 99, 132)', data: [], }] }; const config = { type: 'line', data: data, options: { responsive: false, maintainAspectRatio: false, } }; var cont = document.getElementById("charts"); cont.innerHTML += `<div width="140px" height="140px"><canvas id="chart_${name}"></canvas></div>`; const myChart = new Chart ( document.getElementById(`chart_${name}`).getContext('2d'), config ); dict[name] = myChart; console.log("added"); console.log(dict); return dict[name]; } addData("TEST1", 1); addData("TEST2", 1); </script>Su código me parece bien y no sé por qué no se muestra el primer gráfico. Mirando el DOM en Chrome innerHTML , veo que ambos canvas se agregaron correctamente al HTML interno del div .
El problema se puede resolver. En lugar de usar el HTML interno del div , puede usar document.createElement() para crear el div secundario y su canvas , luego innerHTML Node.appendChild() para agregar la nueva estructura al DOM de la siguiente manera:
let canvas = document.createElement('canvas'); canvas.setAttribute('id', 'chart_' + name); canvas.setAttribute('width', '250'); canvas.setAttribute('height', '200'); let canvasContainer = document.createElement('div'); canvasContainer.appendChild(canvas); document.getElementById("charts").appendChild(canvasContainer); Lo mismo podría hacerse a través de dos líneas de código usando la función jQuery .append() de la siguiente manera:
let chartContainer = $(`<div><canvas id="chart_${name}" width="140px" height="140px"></canvas></div>`); $('#charts').append(chartContainer);Eche un vistazo a su código modificado a continuación y vea cómo funciona.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js" integrity="sha512-QSkVNOCYLtj73J4hbmVoOV6KVZuMluZlioC+trLpewV8qMjsWqlIQvkn1KGX2StWvPMdWGBqim1xlC8krl1EKQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <div id="charts"></div> <script> let dict = new Object(); function addData(name, data) { let chart = dict[name]; if (!chart) { chart = addChart(name); dict[name] = chart; } chart.data.labels.push(new Date().toLocaleTimeString()); chart.data.datasets.forEach(dataset => dataset.data.push(data)); chart.update(); } function addChart(name) { let data = { labels: [], datasets: [{ label: name, backgroundColor: 'rgb(255, 99, 132)', borderColor: 'rgb(255, 99, 132)', data: [], }] }; let config = { type: 'line', data: data, options: { responsive: false, maintainAspectRatio: true, } }; let canvas = document.createElement('canvas'); canvas.setAttribute('id', 'chart_' + name); canvas.setAttribute('width', '250'); canvas.setAttribute('height', '200'); let canvasContainer = document.createElement('div'); canvasContainer.appendChild(canvas); document.getElementById("charts").appendChild(canvasContainer); return new Chart(`chart_${name}`, config ); } addData("TEST1", 1); addData("TEST1", 2); addData("TEST2", 1); addData("TEST2", 3); </script>