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

Django对接Chart.js绘制时序折线图时nan未定义报错求解

问题根因

NumPy生成的np.nan调用.tolist()转为Python原生列表后,元素为Python标准库的float('nan')类型。Django模板直接渲染该值时会输出小写的nan,但JavaScript环境中不存在名为nan的全局变量,同时Chart.js仅识别null作为折线空值断点,不识别JavaScript原生大写NaN,因此触发Uncaught ReferenceError报错。

可行解决方案

优先在后端完成格式转换,从根源避免非法JS语法输出。

不要在前端用正则替换、字符串匹配等方式处理渲染后的nan字符串,这类方案容错率低,一旦数据中存在包含"nan"的文本内容会出现误替换,稳定性差。

方案1:视图层直接替换NaN为None(最简便,适配现有模板逻辑)

Python的None值被Django模板渲染时会自动输出为JavaScript合法的null,完全符合Chart.js的空值识别规则。
在视图函数中生成orig_val、preds列表后,加一层列表推导转换即可:

import math

# 转换历史值序列
orig_val = [None if isinstance(x, float) and math.isnan(x) else x for x in orig_val]
# 转换预测值序列
preds = [None if isinstance(x, float) and math.isnan(x) else x for x in preds]

如果你的数据还没转成原生列表,仍是NumPy数组,可以用NumPy内置方法批量处理:

import numpy as np

orig_val = np.where(np.isnan(orig_np_arr), None, orig_np_arr).tolist()
preds = np.where(np.isnan(pred_np_arr), None, pred_np_arr).tolist()

转换完成后再把变量传给模板,现有模板里的{{ orig_val|safe }}、{{ preds|safe }}写法不需要改动,渲染后空值位置会自动输出null,Chart.js可正常识别。

  • 如果你希望空值位置折线直接断开形成断点,把两个dataset配置里的spanGaps设为false即可
  • 如果希望空值前后的点自动连线,保留spanGaps: true即可

方案2:用Django内置json_script标签传值(更安全规范)

直接用|safe渲染JS变量存在XSS注入风险,Django官方推荐用json_script模板标签传递数据给前端,该标签会自动处理特殊值转义,也会将非法NaN值转为兼容的null格式。
模板中写法调整为:

<!-- 先把数据渲染为安全的JSON脚本块 -->
{{ new_dates|json_script:"chart-labels" }}
{{ orig_val|json_script:"chart-hist-data" }}
{{ preds|json_script:"chart-pred-data" }}

<script>
// 读取解析数据
const labels = JSON.parse(document.getElementById('chart-labels').textContent);
const histData = JSON.parse(document.getElementById('chart-hist-data').textContent);
const predData = JSON.parse(document.getElementById('chart-pred-data').textContent);

// 初始化图表
new Chart(document.getElementById("chart"), {
  type: 'line',
  data: {
    labels: labels,
    datasets: [
      {
          data: histData,
          label: "Historical Sales",
          borderColor: "#3e95cd",
          fill: false,
          spanGaps: false
      },
      {
          data: predData,
          label: "Predictions",
          borderColor: "#22DD66",
          fill: false,
          spanGaps: false
      }
    ]
  },
  options: {
    title: {
      display: true,
      text: 'output chart'
    },
    maintainAspectRatio: false,
    responsive: true,
    scales: {
        xAxes: [{
            gridLines: {
                display:false
            }
        }],
        yAxes: [{
            gridLines: {
                display:false
            }
        }]
    },
    animation: {
          duration: 2000,
      },
  }
});
</script>

这种写法不需要提前在视图层手动替换NaN,模板标签会自动完成合法JSON转换,同时避免XSS风险,适合生产环境使用。

内容的提问来源于stack exchange,提问作者logisticregress

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 10:33:17