v1.6 - Camembert sur Dashboard

This commit is contained in:
h3r7
2026-03-01 08:22:51 +01:00
parent 83a850d520
commit d3b9f1c664

View File

@@ -53,7 +53,11 @@
</div> </div>
<div class="card"> <div class="card">
<h2>📈 Graphique</h2> <h2>📈 Graphiques</h2>
<div class="filter-bar" id="chart-filters" style="margin-bottom:15px; font-size:0.85em">
<div class="filter-chip active" onclick="setChartMode('bar')">Bar chart</div>
<div class="filter-chip" onclick="setChartMode('pie')">Camembert</div>
</div>
<div class="chart-container"> <div class="chart-container">
<canvas id="mainChart"></canvas> <canvas id="mainChart"></canvas>
</div> </div>
@@ -62,6 +66,7 @@
<script> <script>
var depenses = []; var depenses = [];
var currentFilter = { type: 'all', value: null }; var currentFilter = { type: 'all', value: null };
var chartMode = 'bar';
var chart = null; var chart = null;
async function load() { async function load() {
@@ -72,6 +77,12 @@
updateChart(); updateChart();
} }
function setChartMode(mode) {
chartMode = mode;
document.getElementById('chart-filters').innerHTML = '<div class="filter-chip' + (mode === 'bar' ? ' active' : '') + '" onclick="setChartMode('\''+mode+'\'')">Bar chart</div><div class="filter-chip' + (mode === 'pie' ? ' active' : '') + '" onclick="setChartMode('\''+mode+'\'')">Camembert</div>';
updateChart();
}
function renderFilters() { function renderFilters() {
var bars = [ var bars = [
{ id: 'byMonth', label: 'Mois', type: 'month' }, { id: 'byMonth', label: 'Mois', type: 'month' },
@@ -88,7 +99,7 @@
function setFilter(type) { function setFilter(type) {
currentFilter.type = type; currentFilter.type = type;
renderFilters(); renderFilters();
setChartMode('bar');
var values = []; var values = [];
if (type === 'month') { if (type === 'month') {
values = [...new Set(depenses.map(d => d.date.split('-')[0] + '-' + d.date.split('-')[1]))].sort().reverse(); values = [...new Set(depenses.map(d => d.date.split('-')[0] + '-' + d.date.split('-')[1]))].sort().reverse();
@@ -97,7 +108,6 @@
} else if (type === 'category') { } else if (type === 'category') {
values = [...new Set(depenses.map(d => d.category || 'Autre'))].sort(); values = [...new Set(depenses.map(d => d.category || 'Autre'))].sort();
} }
currentFilter.value = values[0] || null; currentFilter.value = values[0] || null;
renderValues(); renderValues();
renderExpenses(); renderExpenses();
@@ -162,7 +172,48 @@
var labels = []; var labels = [];
var data = []; var data = [];
var backgroundColors = []; var backgroundColors = [];
var borderColors = [];
if (chartMode === 'pie') {
if (currentFilter.type === 'person') {
var persons = {};
for (var i = 0; i < filtered.length; i++) {
var d = filtered[i];
var p = d.prenom || 'Inconnu';
if (!persons[p]) persons[p] = 0;
persons[p] += parseFloat(d.montant) || 0;
}
Object.keys(persons).sort().forEach(function(p) {
labels.push(p);
data.push(persons[p]);
backgroundColors.push('rgba(233, 69, 96, 0.7)');
borderColors.push('rgba(233, 69, 96, 1)');
});
} else if (currentFilter.type === 'category') {
var categories = {};
for (var i = 0; i < filtered.length; i++) {
var d = filtered[i];
var c = d.category || 'Autre';
if (!categories[c]) categories[c] = 0;
categories[c] += parseFloat(d.montant) || 0;
}
var colors = [
'rgba(0, 217, 255, 0.7)', 'rgba(233, 69, 96, 0.7)', 'rgba(123, 44, 191, 0.7)',
'rgba(0, 255, 136, 0.7)', 'rgba(255, 200, 0, 0.7)', 'rgba(255, 71, 87, 0.7)', 'rgba(153, 68, 204, 0.7)'
];
Object.keys(categories).sort().forEach(function(c, idx) {
labels.push(c);
data.push(categories[c]);
backgroundColors.push(colors[idx % colors.length]);
borderColors.push(colors[idx % colors.length].replace('0.7', '1'));
});
} else {
labels.push('Mois actuel');
data.push(filtered.reduce(function(s, d) { return s + (parseFloat(d.montant) || 0); }, 0));
backgroundColors.push('rgba(0, 217, 255, 0.7)');
borderColors.push('rgba(0, 217, 255, 1)');
}
} else {
if (currentFilter.type === 'month') { if (currentFilter.type === 'month') {
var months = {}; var months = {};
for (var i = 0; i < filtered.length; i++) { for (var i = 0; i < filtered.length; i++) {
@@ -175,6 +226,7 @@
labels.push(m); labels.push(m);
data.push(months[m]); data.push(months[m]);
backgroundColors.push('rgba(0, 217, 255, 0.7)'); backgroundColors.push('rgba(0, 217, 255, 0.7)');
borderColors.push('rgba(0, 217, 255, 1)');
}); });
} else if (currentFilter.type === 'person') { } else if (currentFilter.type === 'person') {
var persons = {}; var persons = {};
@@ -188,6 +240,7 @@
labels.push(p); labels.push(p);
data.push(persons[p]); data.push(persons[p]);
backgroundColors.push('rgba(233, 69, 96, 0.7)'); backgroundColors.push('rgba(233, 69, 96, 0.7)');
borderColors.push('rgba(233, 69, 96, 1)');
}); });
} else if (currentFilter.type === 'category') { } else if (currentFilter.type === 'category') {
var categories = {}; var categories = {};
@@ -197,23 +250,29 @@
if (!categories[c]) categories[c] = 0; if (!categories[c]) categories[c] = 0;
categories[c] += parseFloat(d.montant) || 0; categories[c] += parseFloat(d.montant) || 0;
} }
Object.keys(categories).sort().forEach(function(c) { var colors = [
'rgba(0, 217, 255, 0.7)', 'rgba(233, 69, 96, 0.7)', 'rgba(123, 44, 191, 0.7)',
'rgba(0, 255, 136, 0.7)', 'rgba(255, 200, 0, 0.7)', 'rgba(255, 71, 87, 0.7)', 'rgba(153, 68, 204, 0.7)'
];
Object.keys(categories).sort().forEach(function(c, idx) {
labels.push(c); labels.push(c);
data.push(categories[c]); data.push(categories[c]);
backgroundColors.push('rgba(123, 44, 191, 0.7)'); backgroundColors.push(colors[idx % colors.length]);
borderColors.push(colors[idx % colors.length].replace('0.7', '1'));
}); });
} }
}
if (chart) chart.destroy(); if (chart) chart.destroy();
chart = new Chart(ctx, { chart = new Chart(ctx, {
type: 'bar', type: chartMode,
data: { data: {
labels: labels, labels: labels,
datasets: [{ datasets: [{
label: 'Montant (€)', label: 'Montant (€)',
data: data, data: data,
backgroundColor: backgroundColors, backgroundColor: backgroundColors,
borderColor: backgroundColors.map(c => c.replace('0.7', '1')), borderColor: borderColors,
borderWidth: 1 borderWidth: 1
}] }]
}, },
@@ -221,14 +280,16 @@
responsive: true, responsive: true,
maintainAspectRatio: false, maintainAspectRatio: false,
plugins: { plugins: {
legend: { display: false }, legend: {
position: 'right',
labels: { color: '#fff', padding: 15, font: { size: 12 } }
},
title: { title: {
display: true, display: true,
text: currentFilter.type === 'month' ? 'Dépenses par mois' : text: chartMode === 'pie' ? 'Répartition par ' + (currentFilter.type === 'month' ? 'Mois' : currentFilter.type === 'person' ? 'Personne' : 'Catégorie') : ''
currentFilter.type === 'person' ? 'Dépenses par personne' : 'Dépenses par catégorie'
} }
}, },
scales: { scales: chartMode === 'pie' ? {} : {
y: { beginAtZero: true, grid: { color: 'rgba(255,255,255,0.1)' }, ticks: { color: '#888' } }, y: { beginAtZero: true, grid: { color: 'rgba(255,255,255,0.1)' }, ticks: { color: '#888' } },
x: { grid: { display: false }, ticks: { color: '#888' } } x: { grid: { display: false }, ticks: { color: '#888' } }
} }