Skip to content

Instantly share code, notes, and snippets.

@maan-singh
Created July 11, 2024 05:07
Show Gist options
  • Save maan-singh/db75b6cf59f56b2418ea28918fc15117 to your computer and use it in GitHub Desktop.
Save maan-singh/db75b6cf59f56b2418ea28918fc15117 to your computer and use it in GitHub Desktop.
chart library to handle logic for render chart
class ChartManager {
constructor(chartElementId, data, rangeLinksSelector, filterFunction) {
this.chartElementId = chartElementId;
this.rangeLinksSelector = rangeLinksSelector;
this.chart = null;
this.range = '30';
this.data = data;
this.filterFunction = filterFunction;
this.init();
}
init() {
this.setupRangeLinks();
this.updateChart();
}
setupRangeLinks() {
document.querySelectorAll(this.rangeLinksSelector).forEach(link => {
link.addEventListener('click', (event) => {
event.preventDefault();
document.querySelector(this.rangeLinksSelector + '.active').classList.remove('active');
link.classList.add('active');
this.range = link.getAttribute('data-range');
this.updateChart();
});
});
}
updateChart() {
const filteredData = this.filterFunction(this.data);
const labels = Object.keys(filteredData);
const counts = Object.values(filteredData);
const data = {
labels: labels,
datasets: [
{
label: this.chartElementId === 'myChart1' ? 'Number of Transactions' : this.chartElementId === 'myChart2' ? 'Income Gained' : 'Expenses',
data: counts,
fill: true,
backgroundColor: this.chartElementId === 'myChart1' ? 'rgba(76, 175, 80, 0.2)' : this.chartElementId === 'myChart2' ? 'rgba(54, 162, 235, 0.2)' : 'rgba(255, 99, 132, 0.2)',
borderColor: this.chartElementId === 'myChart1' ? 'rgba(76, 175, 80, 1)' : this.chartElementId === 'myChart2' ? 'rgba(54, 162, 235, 1)' : 'rgba(255, 99, 132, 1)',
tension: 0.1,
},
],
};
if (this.chart) {
this.chart.data = this.getFilteredData(data);
this.chart.update();
} else {
this.chart = new Chart(document.getElementById(this.chartElementId), {
type: 'line',
data: this.getFilteredData(data),
options: {
maintainAspectRatio: true,
responsive: true,
scales: {
x: {
title: {
display: true,
text: 'Date',
},
grid: {
display: false,
}
},
y: {
title: {
display: true,
text: this.chartElementId === 'myChart1' ? 'Number of Transactions' : this.chartElementId === 'myChart2' ? 'Income' : 'Expenses',
},
grid: {
display: false,
}
},
},
plugins: {
legend: {
display: true,
position: 'bottom',
},
},
},
});
}
}
getFilteredData(data) {
const filteredData = structuredClone(data);
const dates = filteredData.labels.map(dateStr => new Date(dateStr.split('/').reverse().join('-')));
const endDate = new Date(Math.max(...dates));
const startDate = new Date(endDate);
startDate.setDate(endDate.getDate() - parseInt(this.range));
filteredData.labels = data.labels.filter((label) => {
const date = new Date(label.split('/').reverse().join('-'));
return date >= startDate && date <= endDate;
});
const startIndex = data.labels.indexOf(filteredData.labels[0]);
const endIndex = data.labels.indexOf(filteredData.labels[filteredData.labels.length - 1]) + 1;
filteredData.datasets[0].data = data.datasets[0].data.slice(startIndex, endIndex);
return filteredData;
}
}
const filterTransactions = (data) => {
return data.reduce((acc, transaction) => {
const date = new Date(transaction.date).toLocaleDateString();
if (!acc[date]) {
acc[date] = 0;
}
acc[date]++;
return acc;
}, {});
};
const filterIncome = (data) => {
const incomeTransactions = data.filter((transaction) => transaction.amount > 0);
return incomeTransactions.reduce((acc, transaction) => {
const date = transaction.date.split('T')[0]; // Normalize to 'YYYY-MM-DD' format
const amount = parseFloat(transaction.amount);
if (acc[date]) {
acc[date] += amount;
} else {
acc[date] = amount;
}
return acc;
}, {});
};
const filterExpenses = (data) => {
const expenseTransactions = data.filter((transaction) => transaction.amount < 0);
return expenseTransactions.reduce((acc, transaction) => {
const date = transaction.date.split('T')[0]; // Normalize to 'YYYY-MM-DD' format
const amount = parseFloat(transaction.amount);
if (acc[date]) {
acc[date] += Math.abs(amount);
} else {
acc[date] = Math.abs(amount);
}
return acc;
}, {});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment