Created
July 11, 2024 05:07
-
-
Save maan-singh/db75b6cf59f56b2418ea28918fc15117 to your computer and use it in GitHub Desktop.
chart library to handle logic for render chart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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