在Django中实现Chart.js饼图无数据时显示提示的问题
解决Django+Chart.js饼图无数据时的显示问题
问题分析
当前代码存在三个核心问题:
- AJAX请求参数拼写错误(
methode应为method),可能导致请求失败、图表无法渲染; - 当所有数据为0时,百分比计算出现除以0的情况,导致显示
NaN%; - 之前的无数据处理逻辑破坏了Chart.js的初始化流程,导致图表无法正常显示。
解决方案
1. 修改HTML,添加无数据提示元素
在Canvas旁新增一个隐藏的无数据提示容器,用于无数据时替换图表显示:
<div class="card bg-light mb-4"> <div class="card-header"> Assigned Tickets-By Priority </div> <div class="card-body"> <div id="noDataMsg" style="display:none; text-align:center; padding: 40px; font-size:18px;">暂无数据</div> <canvas id="myChart" width="400" height="400"></canvas> </div> </div>
2. 修正JS代码,处理无数据逻辑
- 修复AJAX请求的拼写错误;
- 请求成功后判断是否有有效数据,切换显示图表或无数据提示;
- 优化百分比计算逻辑,避免除以0导致的
NaN%:
<script> {% block jquery %} var endpoint = '/api/chart1' var defaultData = [] var labels = [] $.ajax({ method: "GET", // 修正拼写错误:methode -> method url: endpoint, success: function(data){ labels = data.labels defaultData = data.default // 判断是否存在大于0的有效数据 const hasValidData = defaultData.some(val => val > 0); if (hasValidData) { // 显示图表,隐藏无数据提示 document.getElementById('noDataMsg').style.display = 'none'; document.getElementById('myChart').style.display = 'block'; setChart1(); } else { // 显示无数据提示,隐藏图表 document.getElementById('noDataMsg').style.display = 'block'; document.getElementById('myChart').style.display = 'none'; } }, error: function(error_data){ console.log("请求错误:", error_data) // 请求失败时也显示无数据提示 document.getElementById('noDataMsg').style.display = 'block'; document.getElementById('myChart').style.display = 'none'; } }) function setChart1(){ var ctx = document.getElementById('myChart').getContext('2d'); Chart.register(ChartDataLabels); var myChart = new Chart(ctx, { type: 'pie', plugins: [ChartDataLabels], data: { labels: labels, datasets: [{ label: '', data: defaultData, backgroundColor: [ 'rgba(255, 51, 51, 0.2)', 'rgba(255, 255, 0, 0.2)', 'rgba(0, 204, 204, 0.2)', ], borderColor: [ 'rgba(255, 51, 51, 1)', 'rgba(204, 204, 0, 1)', 'rgba(0, 204, 204, 1)', ], borderWidth: 1 }] }, options: { plugins: { tooltip: { enabled: false }, datalabels: { anchor: 'center', align: 'center', formatter: (value, ctx) => { const sum = ctx.chart.data.datasets[0].data.reduce((total, curr) => total + curr, 0); // 处理总和为0的情况,避免NaN if (sum === 0) return '0%'; return `${(value * 100 / sum).toFixed(2)}%`; }, color: '#000', } } } }); } {% endblock %} </script>
3. Django视图优化(可选)
可以在后端提前判断是否有数据,减少前端逻辑:
def get_chart1(request): high_tickets = Issue.objects.filter(priority='High', assigned_users=request.user).count() low_tickets = Issue.objects.filter(priority='Low', assigned_users=request.user).count() med_tickets = Issue.objects.filter(priority='Medium', assigned_users=request.user).count() labels = ['High', 'Med', 'Low'] default_data = [high_tickets, med_tickets, low_tickets] data = { 'labels': labels, 'default': default_data, 'has_data': any(val > 0 for val in default_data) # 新增字段,前端可直接使用 } return JsonResponse(data)
关键注意点
- 确保Chart.js和ChartDataLabels插件已正确引入,否则图表无法渲染;
- 修复AJAX的
method拼写错误是核心,之前的请求可能根本没成功; - 通过DOM元素显隐切换实现无数据提示,比直接修改Chart配置更稳定。
内容的提问来源于stack exchange,提问作者L30N3CH0
相关产品推荐
相关产品推荐

