使用 Chart.js 不会出现 HTML Javascript 圆环图

问题描述 投票:0回答:1

我有这个 HTML 代码来显示一个圆环图,其中包含通过 PHP 脚本从数据库检索的数据库记录。数据已成功检索并可以在浏览器控制台上看到。 但图表不显示。我该如何解决这个问题?

console.log('Script loaded'); // Check if script is loaded

// Fetch total number of students from PHP file using fetch API
fetch('/javatopia/api/lvTotalStudents.php')
  .then(response => response.json())
  .then(data => {
    console.log('Total Students Data:', data); // Log total students data
    document.getElementById('totalStudents').innerHTML = 'There are currently <strong>' + data.totalStudents + '</strong> students enrolled.';
  })
  .catch(error => {
    console.error('Error fetching total number of students:', error);
  });

// Fetch module names and IDs from PHP file using fetch API and populate dropdown menu
fetch('/javatopia/api/lvParticipationPerModule.php')
  .then(response => response.json())
  .then(data => {
    console.log('Fetched Modules:', data); // Log fetched module data
    const moduleSelect = document.getElementById('moduleSelect');
    data.forEach(module => {
      const option = document.createElement('option');
      option.value = module.moduleId;
      option.text = module.moduleName;
      moduleSelect.appendChild(option);
    });
  })
  .catch(error => {
    console.error('Error fetching module data:', error);
  });

// Fetch data for line chart and initialize the chart
fetch('/javatopia/api/lvPerformance.php')
  .then(response => response.json())
  .then(data => {
    console.log('Line Chart Data:', data); // Log line chart data
    // Prepare data for Chart.js line chart
    const topics = Object.keys(data);
    const averageMarks = Object.values(data);
    const ctxLine = document.getElementById('averageMarks').getContext('2d');

    new Chart(ctxLine, {
      type: 'line',
      data: {
        labels: topics,
        datasets: [{
          label: 'Average Marks per Topic',
          data: averageMarks,
          fill: false,
          borderColor: 'rgb(75, 192, 192)',
          tension: 0.1
        }]
      },
      options: {
        scales: {
          y: {
            beginAtZero: true,
            max: 5, // Set the maximum value for the y-axis
          }
        }
      }
    });
  })
  .catch(error => {
    console.error('Error fetching line chart data:', error);
  });

// Set default module ID and event listener for "Go" button click
document.addEventListener('DOMContentLoaded', function() {
  console.log('DOM Loaded'); // Check if DOM is loaded
  const defaultModuleId = 3; // Set your default module ID here
  document.getElementById('moduleSelect').value = defaultModuleId;
  fetchModuleCompletionData(defaultModuleId);
});

document.getElementById('goButton').addEventListener('click', function() {
  console.log('Go Button Clicked'); // Check if Go button is clicked
  const selectedModuleId = document.getElementById('moduleSelect').value;
  fetchModuleCompletionData(selectedModuleId);
});

// Function to fetch and update module completion data for the donut chart
function fetchModuleCompletionData(moduleId) {
  moduleId = parseInt(moduleId); // Convert moduleId to a number
  console.log('Fetching Module Completion Data for Module ID:', moduleId);

  fetch(`/javatopia/api/lvParticipationPerModule.php?moduleId=${moduleId}`)
    .then(response => response.json())
    .then(data => {
      console.log('Module Completion Data:', data); // Log module completion data
      const ctxDonut = document.getElementById('moduleCompletionChart').getContext('2d');
      let moduleCompletionChart = window.moduleCompletionChart;
      if (moduleCompletionChart && moduleCompletionChart.data) {
        moduleCompletionChart.data.labels = ['Completed', 'Not Completed'];
        moduleCompletionChart.data.datasets[0].data = [data.completed, data.not_completed];
        moduleCompletionChart.update();
      } else {
        window.moduleCompletionChart = new Chart(ctxDonut, {
          type: 'doughnut',
          data: {
            labels: ['Completed', 'Not Completed'],
            datasets: [{
              label: 'Module Completion',
              data: [data.completed, data.not_completed],
              backgroundColor: ['#36A2EB', '#FF6384'],
              borderWidth: 1
            }]
          },
          options: {
            responsive: true,
            maintainAspectRatio: false
          }
        });
      }

      // Ensure the canvas is visible and not hidden
      const canvas = document.getElementById('moduleCompletionChart');
      if (canvas) {
        canvas.style.display = 'block';
      }
    })
    .catch(error => {
      console.error('Error fetching module completion data:', error);
    });
}
<link href="/javatopia/lib/bootstrap/assets/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.0/chart.min.js"></script>

<div id="totalStudents" align="center" style="position: relative; margin-top: 3vw; margin-bottom: 0.5vw;"></div>
<div id="averagePointsPerTopic" class="chart-container" align="center" style="position: relative; height:20vh; width:40vw; margin-top: 2.5vw; margin-bottom: 15vw; margin-left: 30vw;">
  <h2>Average performance per topic</h2>
  <canvas id="averageMarks"></canvas>
</div>
<div id="donutChartContainer" align="center" style="position: relative; margin-left: 35vw; height: 20vw; width: 30vw; margin-top: 2.5vw; margin-bottom: 15vw;">
  <h2>Module Completion</h2>
  <select id="moduleSelect">
    <!-- Options will be populated dynamically -->
  </select>
  <button id="goButton">Go</button>
  <canvas id="moduleCompletionChart" style="display: block;"></canvas>
</div>

下面是控制台日志

lvDashboard3.2.html:24 Script loaded
lvDashboard3.2.html:92 DOM Loaded
lvDashboard3.2.html:107 Fetching Module Completion Data for Module ID: 3
lvDashboard3.2.html:30 Total Students Data: {totalStudents: 4}
lvDashboard3.2.html:58 Line Chart Data: {Intro: '2.50', Syntax: '3.75', Output: '2.50', Comments: '2.50'}
lvDashboard3.2.html:41 Fetched Modules: (4) [{…}, {…}, {…}, {…}]
lvDashboard3.2.html:112 Module Completion Data: (4) [{…}, {…}, {…}, {…}]

以下是邮递员的回复数据。

[
    {
        "moduleId": "3",
        "moduleName": "Intro",
        "completed": 4,
        "not_completed": 0
    },
    {
        "moduleId": "4",
        "moduleName": "Syntax",
        "completed": 4,
        "not_completed": 0
    },
    {
        "moduleId": "5",
        "moduleName": "Output",
        "completed": 4,
        "not_completed": 0
    },
    {
        "moduleId": "6",
        "moduleName": "Comments",
        "completed": 2,
        "not_completed": 2
    }
]
javascript html chart.js
1个回答
0
投票

是的,正如 @kikon 提到的,为圆环图返回的响应数据是一个数组,但您将其作为对象进行处理。

您需要在后端进行更改以将响应作为对象返回:

{
  "completed": 14,
  "not_completed": 2
}

或者您需要在 JavaScript 函数中转换数据,分别对数组中的每个

completed
not_completed
值求和

console.log('Module Completion Data:', data); // Log module completion data

let completed = data.map((x) => x.completed).reduce((acc, cur) => acc + cur, 0);
let not_completed = data
  .map((x) => x.not_completed)
  .reduce((acc, cur) => acc + cur, 0);

const ctxDonut = document
  .getElementById('moduleCompletionChart')
  .getContext('2d');
let moduleCompletionChart = window.moduleCompletionChart;
if (moduleCompletionChart && moduleCompletionChart.data) {
  moduleCompletionChart.data.labels = ['Completed', 'Not Completed'];
  moduleCompletionChart.data.datasets[0].data = [completed, not_completed];
  moduleCompletionChart.update();
} else {
  window.moduleCompletionChart = new Chart(ctxDonut, {
    type: 'doughnut',
    data: {
      labels: ['Completed', 'Not Completed'],
      datasets: [
        {
          label: 'Module Completion',
          data: [completed, not_completed],
          backgroundColor: ['#36A2EB', '#FF6384'],
          borderWidth: 1,
        },
      ],
    },
    options: {
      responsive: true,
      maintainAspectRatio: false,
    },
  });
}

演示@StackBlitz

© www.soinside.com 2019 - 2024. All rights reserved.