I'm facing an issue with displaying data on my pie chart using Chart.js. The legend for the chart appears, but the values show up as undefined
.
cshtml
@page
@model FinalProject.Pages.Exam.ReportModel
@{
Layout = null;
}
<h2>Letter Grade Report</h2>
<table>
<tr>
<th>Exam ID</th>
<th>Student ID</th>
<th>Score</th>
<th>Letter Grade</th>
</tr>
@foreach (var exam in Model.Exams)
{
<tr>
<td>@exam.ExamId</td>
<td>@exam.StudentID</td>
<td>@exam.Score</td>
<td>@FinalProject.Pages.Exam.ReportModel.CalculateLetterGrade(exam.Score)</td>
</tr>
}
</table>
<h2>Letter Grade Summary</h2>
<table>
<tr>
<th>Letter Grade</th>
<th>Total Count</th>
</tr>
@foreach (var gradeSummary in Model.GradeSummary)
{
<tr>
<td>@gradeSummary.LetterGrade</td>
<td>@gradeSummary.TotalCount</td>
</tr>
}
</table>
<!-- Add Chart.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js"></script>
<h2>Letter Grade Distribution (Pie Chart)</h2>
<div style="max-height:300px;">
<canvas id="gradeChart"></canvas>
</div>
<script>
let gradeData = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model.GradeSummary));
const data = {
labels: gradeData.map(g => g.letterGrade),
datasets: [{
label: 'Grade Distribution',
data: gradeData.map(g => g.totalCount),
backgroundColor: ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'],
hoverOffset: 4
}]
};
const config = {
type: 'pie',
data: data,
options: {
responsive: true,
maintainAspectRatio: false
}
};
new Chart(document.getElementById('gradeChart'), config);
</script>
cshtml.cs
using Microsoft.AspNetCore.Mvc.RazorPages;
using School.DAL;
using System;
using System.Collections.Generic;
using System.Linq;
namespace FinalProject.Pages.Exam
{
public class ReportModel : PageModel
{
private readonly IExamAdapter _examAdapter;
public ReportModel(IExamAdapter examAdapter)
{
_examAdapter = examAdapter;
}
public List<School.DAL.Exam> Exams { get; set; }
public List<GradeSummary> GradeSummary { get; set; }
public void OnGet()
{
Exams = _examAdapter.GetAll().ToList();
// Calculate letter grades and generate summary
GradeSummary = CalculateGradeSummary(Exams);
}
private List<GradeSummary> CalculateGradeSummary(List<School.DAL.Exam> exams)
{
var gradeSummary = new List<GradeSummary>();
var gradeGroups = exams.GroupBy(e => CalculateLetterGrade(e.Score));
foreach (var group in gradeGroups)
{
gradeSummary.Add(new GradeSummary
{
LetterGrade = group.Key,
TotalCount = group.Count()
});
}
return gradeSummary;
}
public static string CalculateLetterGrade(string score)
{
if (int.TryParse(score, out int scoreValue))
{
if (scoreValue >= 90) return "A";
else if (scoreValue >= 80) return "B";
else if (scoreValue >= 70) return "C";
else if (scoreValue >= 60) return "D";
else return "F";
}
else
{
// Handle the case where score is not a valid integer (e.g., invalid input)
return "Invalid";
}
}
}
public class GradeSummary
{
public string LetterGrade { get; set; }
public int TotalCount { get; set; }
}
}
Here is what is currently shown:https://i.sstatic.net/JbqV5.png
I experimented with changing the script and considering the use of Adapters instead of my current method, but I believe it can be easily resolved. The dynamic data originates from CRUD operations on the website, specifically through actions like edit.cshtml, edit.cshtml.cs, delete.cshtml..., and this page serves the purpose of reporting and charting the exam scores.