155 lines
3.1 KiB
JavaScript
155 lines
3.1 KiB
JavaScript
import { isInRange } from '../lib/dateFilter'
|
|
|
|
const getDate = (value) => {
|
|
const d = new Date(value)
|
|
|
|
let month = d.getUTCMonth() + 1
|
|
const year = d.getUTCFullYear()
|
|
|
|
if (month < 10) {
|
|
month = `0${month}`
|
|
}
|
|
|
|
return `${month}/${year}`
|
|
}
|
|
|
|
const computeBar = (transactions, stacked, dateFrom, dateTo, selectedCategories) => {
|
|
const indexes = {}
|
|
const labels = []
|
|
const bars = {}
|
|
const emptyCategory = {
|
|
id: -1,
|
|
label: 'Sans catégorie',
|
|
color: '#cccccc',
|
|
}
|
|
|
|
transactions.forEach((transaction) => {
|
|
if (!isInRange(transaction.date, dateFrom, dateTo)) {
|
|
return
|
|
}
|
|
|
|
let category = transaction.category ?? emptyCategory
|
|
|
|
if (!selectedCategories[category.label]) {
|
|
return
|
|
}
|
|
|
|
let date = getDate(transaction.date)
|
|
|
|
if (!Object.hasOwn(indexes, date)) {
|
|
indexes[date] = labels.length
|
|
labels.push(date)
|
|
}
|
|
|
|
if (!Object.hasOwn(bars, category.label)) {
|
|
bars[category.label] = {
|
|
label: category.label,
|
|
data: [],
|
|
borderColor: category.color,
|
|
backgroundColor: category.color,
|
|
fill: true,
|
|
cubicInterpolationMode: 'monotone',
|
|
}
|
|
}
|
|
})
|
|
|
|
for (let key in bars) {
|
|
labels.forEach(() => {
|
|
bars[key].data.push(0)
|
|
})
|
|
}
|
|
|
|
transactions.forEach((transaction) => {
|
|
if (!isInRange(transaction.date, dateFrom, dateTo)) {
|
|
return
|
|
}
|
|
|
|
let category = transaction.category ?? emptyCategory
|
|
|
|
if (!selectedCategories[category.label]) {
|
|
return
|
|
}
|
|
|
|
let date = getDate(transaction.date)
|
|
|
|
bars[category.label].data[indexes[date]] += transaction.debit - transaction.credit
|
|
})
|
|
|
|
labels.forEach((label, key) => {
|
|
for (let bKey in bars) {
|
|
if (bars[bKey].data[key] < 0) {
|
|
bars[bKey].data[key] = 0
|
|
}
|
|
}
|
|
})
|
|
|
|
if (stacked) {
|
|
labels.forEach((label, key) => {
|
|
let sum = 0
|
|
|
|
for (let bKey in bars) {
|
|
sum += bars[bKey].data[key]
|
|
}
|
|
|
|
for (let bKey in bars) {
|
|
bars[bKey].data[key] = (bars[bKey].data[key] * 100) / sum
|
|
}
|
|
})
|
|
}
|
|
|
|
return {
|
|
labels: labels,
|
|
datasets: Object.values(bars),
|
|
}
|
|
}
|
|
|
|
const computeDoughnut = (transactions, dateFrom, dateTo, selectedCategories) => {
|
|
const indexes = {}
|
|
const labels = []
|
|
const data = []
|
|
const backgroundColor = []
|
|
const emptyCategory = {
|
|
id: -1,
|
|
label: 'Sans catégorie',
|
|
color: '#cccccc',
|
|
}
|
|
|
|
transactions.forEach((transaction) => {
|
|
if (!isInRange(transaction.date, dateFrom, dateTo)) {
|
|
return
|
|
}
|
|
|
|
let category = transaction.category ?? emptyCategory
|
|
|
|
if (!selectedCategories[category.label]) {
|
|
return
|
|
}
|
|
|
|
if (!Object.hasOwn(indexes, category.id)) {
|
|
indexes[category.id] = labels.length
|
|
labels.push(category.label)
|
|
backgroundColor.push(category.color)
|
|
data[indexes[category.id]] = 0
|
|
}
|
|
|
|
data[indexes[category.id]] += transaction.debit - transaction.credit
|
|
})
|
|
|
|
for (let i in data) {
|
|
if (data[i] < 0) {
|
|
data[i] = 0
|
|
}
|
|
}
|
|
|
|
return {
|
|
labels: labels,
|
|
datasets: [
|
|
{
|
|
data: Object.values(data),
|
|
backgroundColor: backgroundColor,
|
|
},
|
|
],
|
|
}
|
|
}
|
|
|
|
export { computeDoughnut, computeBar }
|