JavaScript使用Chart.js无法渲染多个折线图问题求解
多折线图插入失败问题修复方案
核心错误原因
- 使用
panel.innerHTML +=追加内容时,会重绘panel内所有已存在的DOM节点,已初始化的Chart实例绑定的canvas元素会被销毁,导致之前渲染的图表丢失。 - 单个canvas元素重复初始化两次Chart实例,实例冲突导致渲染异常。
- HTML结构顺序错误,
<DOCTYPE>、<html>根标签需放在所有资源引入标签之前。 - 未提前声明
chartMap变量就直接调用set方法,会抛出未定义错误。 - 代码中存在无效属性调用:
newChart.value、i.value均不存在,会触发运行时报错。 - CSS的border属性语法错误,样式不生效。
修复后的可运行代码
<!DOCTYPE html> <html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script> <style> .column { float: left; width: 50%; padding: 10px; box-sizing: border-box; } .row { clear: both; display: table; width: 100%; } #cboxes { margin: 10px 0; } </style> </head> <body> <div id="cboxes"></div> <div id="panel"></div> <script> // 全局变量声明 const xValues = [50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150]; const yValues = [7, 8, 8, 9, 9, 9, 10, 11, 14, 14, 15]; const chartMap = new Map(); // 测试用参数,可根据实际需求替换 const paramList = "温度,湿度,气压"; const valueList = "25,60,1013"; function addParamsToPanel(parameter, paramValue, isDisplay, i) { if (isDisplay) { displayPanel(parameter, paramValue,i); } } function updatePanel(paramList, valueList) { const param = paramList.toString().split(','); const paramValue = valueList.toString().split(','); for (var i = 0; i < param.length; i++) { var p = document.createElement("div"); var checkBox = document.createElement("input"); var label = document.createElement("label"); checkBox.type = "checkbox"; checkBox.id = param[i]; p.appendChild(checkBox); p.appendChild(label); document.getElementById("cboxes").appendChild(p); label.appendChild(document.createTextNode(param[i])); checkBox.checked = true; addParamsToPanel(param[i], paramValue[i], checkBox.checked, i); } } function displayPanel(parameter, paramValue, i) { const panel = document.getElementById('panel'); const today = new Date(); const time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds(); const newChartId = 'paramChart_' + parameter; // 改用创建节点追加,避免销毁已有DOM const rowDiv = document.createElement('div'); rowDiv.className = 'row'; rowDiv.innerHTML = ` <div class="column"> <form> <label id="paramname_${parameter}" for="paramvalue">${parameter}</label> <input type="text" id="paramvalue_${parameter}" name="param" value="${paramValue}" readonly> </form> </div> <div id="chart_${i}" class="column"> <canvas id="${newChartId}" style="width:100%;max-height:100px;max-width:700px;border: solid rgb(4, 31, 65);"></canvas> </div> `; panel.appendChild(rowDiv); const chart = new Chart(newChartId, { type: "line", data: { labels: xValues, datasets: [{ fill: false, backgroundColor: "rgba(0,0,255,1.0)", borderColor: "rgba(0,0,255,0.1)", data: yValues, showLine: true, spanGaps: true }] }, options: { legend: { display: false }, scales: { yAxes: [{ ticks: { min: 6, max: 16 } }] } } }); chartMap.set(newChartId, chart); // 修复无效属性调用,替换为实际要新增的数值 chart.data.datasets[0].data.push(Number(paramValue)); chart.data.labels.push(time); chart.update(); } // 初始化调用 updatePanel(paramList, valueList); </script> </body> </html>
补充说明
如果需要动态更新已有图表的数据,直接从chartMap中取出对应实例修改数据后调用update()方法即可,不需要重复初始化Chart。
内容的提问来源于stack exchange,提问作者C A Anusha
相关产品推荐
相关产品推荐

