section zoneplaces sur infos générales
This commit is contained in:
parent
5186eb17bb
commit
738f3eeb9d
4 changed files with 455 additions and 5 deletions
|
|
@ -86,6 +86,18 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{# Graphique des créations et suppressions #}
|
||||
{% if chart_data is defined and chart_data.dates|length > 0 %}
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
<h5><i class="bi bi-graph-up"></i> Évolution des créations et suppressions</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<canvas id="changesChart" style="max-height: 400px;"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for date, changes in changesByDate %}
|
||||
<div class="card mb-4 change-date-card" data-date="{{ date }}">
|
||||
<div class="card-header">
|
||||
|
|
@ -281,6 +293,8 @@
|
|||
|
||||
{% block javascripts %}
|
||||
{{ parent() }}
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
let selectedChangeType = 'all';
|
||||
|
|
@ -348,24 +362,33 @@
|
|||
const shouldShowTheme = selectedTheme === 'all' || selectedTheme === theme;
|
||||
|
||||
if (shouldShowTheme) {
|
||||
themeSection.style.display = '';
|
||||
// Filtrer les lignes du tableau
|
||||
const rows = themeSection.querySelectorAll('tbody tr');
|
||||
let hasVisibleRows = false;
|
||||
|
||||
rows.forEach(row => {
|
||||
const rowTheme = row.getAttribute('data-theme');
|
||||
const rowChangeType = row.getAttribute('data-change-type');
|
||||
const rowUser = row.getAttribute('data-user') || '';
|
||||
const shouldShowTheme = selectedTheme === 'all' || selectedTheme === rowTheme;
|
||||
const shouldShowRowTheme = selectedTheme === 'all' || selectedTheme === rowTheme;
|
||||
const shouldShowChangeType = selectedChangeType === 'all' || selectedChangeType === rowChangeType;
|
||||
const shouldShowUser = selectedUser === 'all' || selectedUser === rowUser;
|
||||
|
||||
if (shouldShowTheme && shouldShowChangeType && shouldShowUser) {
|
||||
if (shouldShowRowTheme && shouldShowChangeType && shouldShowUser) {
|
||||
row.style.display = '';
|
||||
hasVisibleRows = true;
|
||||
} else {
|
||||
row.style.display = 'none';
|
||||
}
|
||||
});
|
||||
hasVisibleTheme = true;
|
||||
|
||||
// Afficher ou masquer la section de thème selon qu'elle a des lignes visibles
|
||||
if (hasVisibleRows) {
|
||||
themeSection.style.display = '';
|
||||
hasVisibleTheme = true;
|
||||
} else {
|
||||
themeSection.style.display = 'none';
|
||||
}
|
||||
} else {
|
||||
themeSection.style.display = 'none';
|
||||
}
|
||||
|
|
@ -391,6 +414,126 @@
|
|||
// Initialiser les filtres
|
||||
applyFilters();
|
||||
|
||||
// Créer le graphique des créations et suppressions
|
||||
{% if chart_data is defined and chart_data.dates|length > 0 %}
|
||||
{% set hasCompletionData = false %}
|
||||
{% for comp in chart_data.completion %}
|
||||
{% if comp is not null %}
|
||||
{% set hasCompletionData = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
const chartCanvas = document.getElementById('changesChart');
|
||||
if (chartCanvas) {
|
||||
const chartData = {
|
||||
labels: {{ chart_data.dates|json_encode|raw }},
|
||||
datasets: [
|
||||
{
|
||||
label: 'Suppressions',
|
||||
data: {{ chart_data.deletions|json_encode|raw }},
|
||||
borderColor: 'rgb(220, 53, 69)',
|
||||
backgroundColor: 'rgba(220, 53, 69, 0.1)',
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
},
|
||||
{
|
||||
label: 'Créations',
|
||||
data: {{ chart_data.creations|json_encode|raw }},
|
||||
borderColor: 'rgb(25, 135, 84)',
|
||||
backgroundColor: 'rgba(25, 135, 84, 0.1)',
|
||||
tension: 0.4,
|
||||
fill: true
|
||||
}
|
||||
{% if hasCompletionData %}
|
||||
,{
|
||||
label: 'Complétion générale (%)',
|
||||
data: {{ chart_data.completion|json_encode|raw }},
|
||||
borderColor: 'rgb(13, 110, 253)',
|
||||
backgroundColor: 'rgba(13, 110, 253, 0.1)',
|
||||
tension: 0.4,
|
||||
fill: false,
|
||||
yAxisID: 'y1',
|
||||
borderDash: [5, 5]
|
||||
}
|
||||
{% endif %}
|
||||
]
|
||||
};
|
||||
|
||||
new Chart(chartCanvas, {
|
||||
type: 'line',
|
||||
data: chartData,
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: true,
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top',
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
let label = context.dataset.label || '';
|
||||
if (label) {
|
||||
label += ': ';
|
||||
}
|
||||
if (context.parsed.y !== null) {
|
||||
if (context.dataset.label === 'Complétion générale (%)') {
|
||||
label += context.parsed.y.toFixed(1) + '%';
|
||||
} else {
|
||||
label += context.parsed.y;
|
||||
}
|
||||
} else {
|
||||
label += 'N/A';
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
display: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Date'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
type: 'linear',
|
||||
display: true,
|
||||
position: 'left',
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Nombre d\'objets'
|
||||
},
|
||||
beginAtZero: true
|
||||
}
|
||||
{% if hasCompletionData %}
|
||||
,y1: {
|
||||
type: 'linear',
|
||||
display: true,
|
||||
position: 'right',
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Complétion (%)'
|
||||
},
|
||||
beginAtZero: true,
|
||||
max: 100,
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
// Convertir les dates en format relatif
|
||||
function formatRelativeTime(timestamp) {
|
||||
if (!timestamp) return 'N/A';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue