All files / src/app/student-page/components/my-grade AssignmentGradesBarChart.jsx

90% Statements 18/20
78.57% Branches 11/14
75% Functions 6/8
86.66% Lines 13/15

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92          1x 16x 16x   16x 8x             8x 13x 13x 13x 8x   16x                                                                                                                           16x   16x        
import { useTheme } from "@mui/material/styles";
import { Typography } from "@mui/material";
import ReactApexChart from "react-apexcharts";
import { bandColor } from "@/app/student-page/page/my-grade/gradeBands";
 
const AssignmentGradesBarChart = ({ assignments, average }) => {
    const theme = useTheme();
    const graded = (assignments ?? []).filter((a) => typeof a.grade === "number");
 
    if (graded.length === 0) {
        return (
            <Typography variant="body2" color="text.secondary">
                No graded assignments yet.
            </Typography>
        );
    }
 
    const sorted = [...graded].sort((a, b) => (a.date_close ?? "").localeCompare(b.date_close ?? ""));
    const categories = sorted.map((a) => a.title ?? "Untitled");
    const values = sorted.map((a) => a.grade);
    const colors = sorted.map((a) => bandColor(theme, a.grade));
    const hasAverage = typeof average === "number" && Number.isFinite(average);
 
    const options = {
        chart: { type: "bar", toolbar: { show: false } },
        plotOptions: {
            bar: {
                distributed: true,
                borderRadius: 4,
                borderRadiusApplication: "end",
                columnWidth: "55%",
            },
        },
        colors,
        legend: { show: false },
        dataLabels: {
            enabled: true,
            offsetY: -20,
            formatter: (val) => val.toFixed(2),
            style: { colors: [theme.palette.text.secondary], fontSize: "12px" },
        },
        grid: { borderColor: theme.palette.divider },
        xaxis: {
            categories,
            labels: {
                style: { colors: theme.palette.text.secondary },
                rotate: -25,
                trim: true,
                hideOverlappingLabels: true,
            },
            axisBorder: { color: theme.palette.divider },
            axisTicks: { color: theme.palette.divider },
        },
        yaxis: {
            max: 100,
            min: 0,
            labels: { style: { colors: theme.palette.text.secondary } },
            title: { text: "Grade", style: { color: theme.palette.text.secondary, fontSize: "12px" } },
        },
        tooltip: {
            theme: theme.palette.mode,
            y: { formatter: (val) => `${val.toFixed(2)} / 100` },
        },
        annotations: hasAverage
            ? {
                  yaxis: [
                      {
                          y: average,
                          borderColor: theme.palette.text.secondary,
                          strokeDashArray: 4,
                          label: {
                              text: `Average ${average.toFixed(2)}`,
                              position: "left",
                              style: {
                                  color: theme.palette.getContrastText(theme.palette.grey[700]),
                                  background: theme.palette.grey[700],
                                  fontSize: "11px",
                              },
                          },
                      },
                  ],
              }
            : {},
    };
 
    const series = [{ name: "Grade", data: values }];
 
    return <ReactApexChart options={options} series={series} type="bar" height={320} />;
};
 
export default AssignmentGradesBarChart;