如何将Django views中的数组传递给JS文件渲染图表并解决getContext报错
问题原因与修复方案
1. 核心报错原因:DOM未加载完成就执行JS
你看到的Cannot read properties of null (reading 'getContext')报错,是因为JS代码执行时,页面上的<canvas id="chartBig1">元素还没渲染完成,document.getElementById("chartBig1")拿到的是空值,调用方法自然报错。
2. 次要问题:Django模板变量转JS变量的写法错误
你在views里已经用mark_safe(json.dumps())把数据序列化为合法的JS数组格式了,前端不需要再加JSON.parse,也不需要套单引号,多余的转换反而可能引发引号转义异常。
具体修改步骤
第一步:确认HTML中存在对应canvas元素
先检查charts.html里有没有下面的代码,确保id完全匹配、大小写一致:
<canvas id="chartBig1"></canvas>
第二步:修改charts.html中的JS代码
把所有JS逻辑包裹在DOM加载完成的回调中,同时简化变量赋值逻辑(顺便修复原代码中config对象的语法漏写逗号问题):
// 等页面所有DOM元素加载完成后再执行图表逻辑 $(document).ready(function(){ // 直接赋值即可,不需要JSON.parse和额外引号 var chart_labels = {{labelss}}; var chart_data = {{datas}}; var ctx = document.getElementById("chartBig1").getContext('2d'); var gradientStroke = ctx.createLinearGradient(0, 230, 0, 50); gradientStroke.addColorStop(1, 'rgba(72,72,176,0.1)'); gradientStroke.addColorStop(0.4, 'rgba(72,72,176,0.0)'); gradientStroke.addColorStop(0, 'rgba(119,52,169,0)'); //purple colors var config = { type: 'line', data: { labels: chart_labels, datasets: [{ label: "My First dataset", fill: true, backgroundColor: gradientStroke, borderColor: '#d346b1', borderWidth: 2, borderDash: [], borderDashOffset: 0.0, pointBackgroundColor: '#d346b1', pointBorderColor: 'rgba(255,255,255,0)', pointHoverBackgroundColor: '#d346b1', pointBorderWidth: 20, pointHoverRadius: 4, pointHoverBorderWidth: 15, pointRadius: 4, data: chart_data }] }, options: gradientChartOptionsConfigurationWithTooltipPurple }; var myChartData = new Chart(ctx, config); $("#0").click(function() { var data = myChartData.config.data; data.datasets[0].data = chart_data; data.labels = chart_labels; myChartData.update(); }); $("#1").click(function() { var chart_data = [80, 120, 105, 110, 95, 105, 90, 100, 80, 95, 70, 120]; var data = myChartData.config.data; data.datasets[0].data = chart_data; data.labels = chart_labels; myChartData.update(); }); $("#2").click(function() { var chart_data = [60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130]; var data = myChartData.config.data; data.datasets[0].data = chart_data; data.labels = chart_labels; myChartData.update(); }); });
如果你的项目没有引入jQuery,也可以把所有JS代码放在body标签的最末尾,紧挨着</body>标签之前,也能保证DOM加载完成后再执行JS。
内容的提问来源于stack exchange,提问作者harish krishna
相关产品推荐
相关产品推荐

