feature: Added chart functionality

This commit is contained in:
Keith Solomon
2025-02-09 14:07:31 -06:00
parent f72930006b
commit 3220a88fb3
5 changed files with 74 additions and 141 deletions

View File

@@ -521,9 +521,6 @@
}
}
@layer utilities {
.collapse {
visibility: collapse;
}
.absolute {
position: absolute;
}
@@ -545,9 +542,6 @@
.right-2 {
right: calc(var(--spacing) * 2);
}
.col-span-4 {
grid-column: span 4 / span 4;
}
.container {
width: 100%;
@media (width >= 40rem) {
@@ -569,18 +563,9 @@
.mx-auto {
margin-inline: auto;
}
.mt-2 {
margin-top: calc(var(--spacing) * 2);
}
.mt-4 {
margin-top: calc(var(--spacing) * 4);
}
.mr-2 {
margin-right: calc(var(--spacing) * 2);
}
.mr-auto {
margin-right: auto;
}
.mb-0 {
margin-bottom: calc(var(--spacing) * 0);
}
@@ -608,30 +593,9 @@
.hidden {
display: none;
}
.inline {
display: inline;
}
.inline-block {
display: inline-block;
}
.inline-flex {
display: inline-flex;
}
.list-item {
display: list-item;
}
.table {
display: table;
}
.w-3 {
width: calc(var(--spacing) * 3);
}
.w-3\/4 {
width: calc(3/4 * 100%);
}
.w-5 {
width: calc(var(--spacing) * 5);
}
.w-5\/6 {
width: calc(5/6 * 100%);
}
@@ -644,21 +608,6 @@
.w-full {
width: 100%;
}
.flex-1 {
flex: 1;
}
.border-collapse {
border-collapse: collapse;
}
.transform {
transform: var(--tw-rotate-x) var(--tw-rotate-y) var(--tw-rotate-z) var(--tw-skew-x) var(--tw-skew-y);
}
.resize {
resize: both;
}
.list-disc {
list-style-type: disc;
}
.list-none {
list-style-type: none;
}
@@ -694,9 +643,6 @@
margin-inline-end: calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)));
}
}
.overflow-hidden {
overflow: hidden;
}
.rounded {
border-radius: 0.25rem;
}
@@ -707,14 +653,6 @@
border-style: var(--tw-border-style);
border-width: 1px;
}
.border-t {
border-top-style: var(--tw-border-style);
border-top-width: 1px;
}
.border-b {
border-bottom-style: var(--tw-border-style);
border-bottom-width: 1px;
}
.bg-black {
background-color: var(--color-black);
}
@@ -727,9 +665,6 @@
.bg-gray-100 {
background-color: var(--color-gray-100);
}
.bg-gray-300 {
background-color: var(--color-gray-300);
}
.bg-green-500 {
background-color: var(--color-green-500);
}
@@ -739,9 +674,6 @@
.bg-white {
background-color: var(--color-white);
}
.p-1 {
padding: calc(var(--spacing) * 1);
}
.p-2 {
padding: calc(var(--spacing) * 2);
}
@@ -751,9 +683,6 @@
.p-6 {
padding: calc(var(--spacing) * 6);
}
.px-1 {
padding-inline: calc(var(--spacing) * 1);
}
.px-2 {
padding-inline: calc(var(--spacing) * 2);
}
@@ -766,9 +695,6 @@
.py-0 {
padding-block: calc(var(--spacing) * 0);
}
.py-1 {
padding-block: calc(var(--spacing) * 1);
}
.py-2 {
padding-block: calc(var(--spacing) * 2);
}
@@ -778,9 +704,6 @@
.pl-0 {
padding-left: calc(var(--spacing) * 0);
}
.pl-5 {
padding-left: calc(var(--spacing) * 5);
}
.text-2xl {
font-size: var(--text-2xl);
line-height: var(--tw-leading, var(--text-2xl--line-height));
@@ -819,9 +742,6 @@
.text-white {
color: var(--color-white);
}
.underline {
text-decoration-line: underline;
}
.shadow {
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -834,10 +754,6 @@
--tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
}
.outline {
outline-style: var(--tw-outline-style);
outline-width: 1px;
}
.hover\:bg-blue-600 {
&:hover {
@media (hover: hover) {
@@ -845,13 +761,6 @@
}
}
}
.hover\:bg-gray-400 {
&:hover {
@media (hover: hover) {
background-color: var(--color-gray-400);
}
}
}
.hover\:bg-green-600 {
&:hover {
@media (hover: hover) {
@@ -866,23 +775,11 @@
}
}
}
.hover\:text-gray-700 {
&:hover {
@media (hover: hover) {
color: var(--color-gray-700);
}
}
}
.md\:grid-cols-2 {
@media (width >= 48rem) {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
.md\:grid-cols-4 {
@media (width >= 48rem) {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
}
.md\:grid-cols-5 {
@media (width >= 48rem) {
grid-template-columns: repeat(5, minmax(0, 1fr));
@@ -925,31 +822,6 @@
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
}
@property --tw-rotate-x {
syntax: "*";
inherits: false;
initial-value: rotateX(0);
}
@property --tw-rotate-y {
syntax: "*";
inherits: false;
initial-value: rotateY(0);
}
@property --tw-rotate-z {
syntax: "*";
inherits: false;
initial-value: rotateZ(0);
}
@property --tw-skew-x {
syntax: "*";
inherits: false;
initial-value: skewX(0);
}
@property --tw-skew-y {
syntax: "*";
inherits: false;
initial-value: skewY(0);
}
@property --tw-space-y-reverse {
syntax: "*";
inherits: false;
@@ -1024,8 +896,3 @@
inherits: false;
initial-value: 0 0 #0000;
}
@property --tw-outline-style {
syntax: "*";
inherits: false;
initial-value: solid;
}

View File

@@ -179,6 +179,7 @@ try {
ORDER BY payees.name ASC
");
$stmt->execute([$year]);
$payeeAmounts = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch overall YTD amount

View File

@@ -48,12 +48,12 @@
<!-- Chart & Totals -->
<div class="border p-4 rounded shadow bg-gray-100 grid grid-cols-1 lg:grid-cols-2 gap-4">
<div id="chartSection" class="bg-white p-4 rounded shadow mb-6">
<h3 class="text-xl font-bold mb-4">Chart</h3>
<canvas id="chart"></canvas>
<div id="ytdPieChartSection" class="bg-white p-4 rounded shadow">
<h3 class="text-xl font-bold mb-4">YTD Chart</h3>
<canvas id="ytdPieChart"></canvas>
</div>
<div id="ytdSection" class="bg-white p-4 rounded shadow mb-6">
<div id="ytdSection" class="bg-white p-4 rounded shadow">
<h3 class="text-xl font-bold mb-4">Year-to-Date Summary</h3>
<div id="ytdOverall" class="mb-4">

View File

@@ -4,6 +4,7 @@ document.addEventListener('DOMContentLoaded', () => {
const billList = document.getElementById('billList');
const form = document.getElementById('billForm');
const currentYear = new Date().getFullYear();
let ytdPieChart; // To hold the chart instance
// Populate the year dropdown
async function loadYears() {
@@ -140,10 +141,72 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
async function renderYtdPieChart(year) {
const response = await fetch(`/includes/api.php?action=getYtdAmounts&year=${year}`);
const data = await response.json();
// Extract payee amounts from the response
const payeeAmounts = data.payeeAmounts || [];
const overallTotal = data.overallAmount || 0;
if (overallTotal === 0) {
console.warn('Overall total is zero. No data available for the chart.');
return;
}
// Extract labels (payee names) and data (YTD totals)
const labels = payeeAmounts.map(item => item.payeeName);
const totals = payeeAmounts.map(item => item.totalAmount);
// Get the chart canvas
const ctx = document.getElementById('ytdPieChart').getContext('2d');
// Destroy the existing chart if it exists
if (ytdPieChart) {
ytdPieChart.destroy();
}
// Create a new pie chart
ytdPieChart = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
data: totals,
backgroundColor: [
'#003962', '#00607F', '#008B9C', '#00B8B9', '#00E6D6', '#00FFF4'
], // Add more colors if needed
hoverBackgroundColor: [
'#042c4c', '#004968', '#007384', '#009FA1', '#00CCBD', '#00FBDA'
]
}]
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
},
tooltip: {
callbacks: {
label: function (tooltipItem) {
const value = tooltipItem.raw; // Raw data for this item
const percentage = ((value / overallTotal) * 100).toFixed(2); // Calculate percentage
return ` $${value.toFixed(2)} (${percentage}%)`;
}
}
}
}
}
});
}
// Add event listener for year selection
yearSelect.addEventListener('change', (e) => {
const selectedYear = e.target.value;
loadYtdAmounts(selectedYear);
loadYtdAmounts(selectedYear); // Update YTD amounts when the year changes
renderYtdPieChart(selectedYear); // Update the pie chart when the year changes
loadBills(selectedYear, sortSelect.value); // Use the selected sort order
});
@@ -229,7 +292,8 @@ document.addEventListener('DOMContentLoaded', () => {
});
// On page load
loadPayees('payeeId');
loadYears();
loadYtdAmounts(currentYear);
loadPayees('payeeId'); // Load payees
loadYears(); // Load years
loadYtdAmounts(currentYear); // Load YTD amounts for the current year
renderYtdPieChart(currentYear); // Render the pie chart for the current year
});

View File

@@ -2,3 +2,4 @@
@import "tailwindcss";
/* Basic project styles */