You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:06:05