如何用JQuery处理DRF接口数据并生成Chart.js各类图表?
Got it, let's break this down step by step. I'll walk you through fetching the data with jQuery, transforming it into formats Chart.js can use, and building each of your three required charts.
Prerequisites
First, make sure you've included the necessary libraries and chart containers in your HTML:
<!-- jQuery --> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <!-- Chart.js --> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <!-- Canvas elements for each chart --> <canvas id="lineChart" width="400" height="200"></canvas> <canvas id="weekdayBarChart" width="400" height="200"></canvas> <canvas id="hourBarChart" width="400" height="200"></canvas>
Step 1: Fetch and Preprocess Data
We'll start by pulling data from your DRF endpoint and adding useful properties (like parsed dates, weekday numbers, and hours) to make filtering and counting easier.
$(document).ready(function() { // Fetch data from your API $.getJSON('http://localhost/api/data', function(rawData) { // Transform raw data into a more usable format const processedData = rawData.map(entry => { const dateObj = new Date(entry.date); return { ...entry, dateObj: dateObj, dayOfWeek: dateObj.getDay(), // 0 = Sunday, 6 = Saturday hour: parseInt(entry.time.split(':')[0]) // Extract hour as number }; }); // Build each chart with the processed data buildLineChart(processedData); buildWeekdayBarChart(processedData); buildHourBarChart(processedData); }).fail(function() { alert('Oops, failed to load data from the API. Check your endpoint!'); }); });
Step 2: Line Chart (Jan 1-30 Booking Trends)
This chart will show total people per day for every day in January 2018—even days with no bookings (which will display as 0).
function buildLineChart(data) { // Create an array of all dates from Jan 1 to Jan 30, 2018 const januaryDates = []; for (let day = 1; day <= 30; day++) { januaryDates.push(new Date(2018, 0, day)); // Months are 0-indexed in JS } // Calculate total people for each date const dailyTotals = januaryDates.map(date => { const dateString = date.toISOString().split('T')[0]; // Format to YYYY-MM-DD return data .filter(entry => entry.date === dateString) .reduce((total, entry) => total + entry.people, 0); }); // Format dates for the x-axis (e.g., "Jan 1") const xLabels = januaryDates.map(date => `${date.toLocaleString('en-US', { month: 'short' })} ${date.getDate()}` ); // Initialize the line chart const ctx = document.getElementById('lineChart').getContext('2d'); new Chart(ctx, { type: 'line', data: { labels: xLabels, datasets: [{ label: 'Total Booked People', data: dailyTotals, borderColor: 'rgb(75, 192, 192)', tension: 0.1, fill: true, backgroundColor: 'rgba(75, 192, 192, 0.2)' }] }, options: { scales: { y: { beginAtZero: true, title: { display: true, text: 'Number of People' } }, x: { title: { display: true, text: 'Date (January 2018)' } } } } }); }
Step 3: Bar Chart (Bookings by Weekday)
This chart counts total people for each day of the week, with readable weekday names on the x-axis.
function buildWeekdayBarChart(data) { // Map numeric weekday values to names (matches getDay() output) const weekdayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; // Calculate total people per weekday const weekdayTotals = weekdayNames.map((_, index) => { return data .filter(entry => entry.dayOfWeek === index) .reduce((total, entry) => total + entry.people, 0); }); // Initialize the bar chart const ctx = document.getElementById('weekdayBarChart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { labels: weekdayNames, datasets: [{ label: 'Total Booked People', data: weekdayTotals, backgroundColor: 'rgba(255, 99, 132, 0.6)' }] }, options: { scales: { y: { beginAtZero: true, title: { display: true, text: 'Number of People' } }, x: { title: { display: true, text: 'Day of Week' } } } } }); }
Step 4: Bar Chart (Bookings by Hour)
Even though your sample data only has 21:00 entries, this code works for any hour values in your API data.
function buildHourBarChart(data) { // Get all unique hours from the data, sorted numerically const uniqueHours = [...new Set(data.map(entry => entry.hour))].sort((a, b) => a - b); // Calculate total people per hour const hourTotals = uniqueHours.map(hour => { return data .filter(entry => entry.hour === hour) .reduce((total, entry) => total + entry.people, 0); }); // Format hours for the x-axis (e.g., "21:00") const xLabels = uniqueHours.map(hour => `${hour.toString().padStart(2, '0')}:00`); // Initialize the bar chart const ctx = document.getElementById('hourBarChart').getContext('2d'); new Chart(ctx, { type: 'bar', data: { labels: xLabels, datasets: [{ label: 'Total Booked People', data: hourTotals, backgroundColor: 'rgba(54, 162, 235, 0.6)' }] }, options: { scales: { y: { beginAtZero: true, title: { display: true, text: 'Number of People' } }, x: { title: { display: true, text: 'Hour of Day' } } } } }); }
Quick Notes
- If you want weekdays to start on Monday instead of Sunday, just reorder the
weekdayNamesarray and adjust the index mapping. - The line chart includes every day in January—days with no bookings will show 0, so you get a full view of the month's trends.
- You can tweak colors, tooltips, or layout by modifying the
optionsobject in each chart initialization.
内容的提问来源于stack exchange,提问作者Francesco Iacovelli

