136 lines
3.2 KiB
JavaScript

/**
* Chart utilities for activity visualization
*/
class ActivityChart {
constructor(canvasId) {
this.canvasId = canvasId;
this.chart = null;
this.initChart();
}
initChart() {
// Check if Chart.js is available
if (typeof Chart === "undefined") {
console.error("Chart.js is not loaded");
return;
}
const chartElement = document.getElementById(this.canvasId);
if (!chartElement) {
console.error(
`Chart canvas element with id "${this.canvasId}" not found`
);
return;
}
this.ctx = chartElement.getContext("2d");
}
/**
* Render the activity chart with provided data
* @param {Array} data - Chart data array
*/
render(data) {
if (!this.ctx) {
console.error("Chart context not available");
return;
}
// Extract the data for the chart
const labels = data.map((item) => `${item.hour}:00`);
const successData = data.map((item) => item.success);
const errorData = data.map((item) => item.error);
const pendingData = data.map((item) => item.pending);
// Destroy existing chart if it exists
if (this.chart) {
this.chart.destroy();
}
this.chart = new Chart(this.ctx, {
type: "bar",
data: {
labels: labels,
datasets: [
{
label: "Success",
data: successData,
backgroundColor: "#28a745",
stack: "Stack 0",
},
{
label: "Error",
data: errorData,
backgroundColor: "#dc3545",
stack: "Stack 0",
},
{
label: "Pending",
data: pendingData,
backgroundColor: "#ffc107",
stack: "Stack 0",
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
stacked: true,
title: {
display: true,
text: "Hour",
},
},
y: {
stacked: true,
beginAtZero: true,
title: {
display: true,
text: "Papers Scraped",
},
},
},
},
});
}
/**
* Load and render chart data for specified time range
* @param {number} hours - Number of hours to show data for
*/
async loadData(hours) {
try {
const response = await fetch(`/scraper/stats?hours=${hours}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
console.log("Stats data loaded:", data);
this.render(data);
} catch (error) {
console.error("Failed to load activity stats:", error);
// Hide the chart or show an error message
const chartContainer = document.getElementById(
this.canvasId
).parentElement;
if (chartContainer) {
chartContainer.innerHTML =
'<p class="text-muted">Chart data unavailable</p>';
}
}
}
/**
* Destroy the chart instance
*/
destroy() {
if (this.chart) {
this.chart.destroy();
this.chart = null;
}
}
}