Add IBAN and Verwendungszweck columns to support list and fix chart growing bug

- Enhanced 'Alle Unterstützungen' view with IBAN and Verwendungszweck columns for better payment tracking
- Updated export functions to handle both legacy 'selected_fields' and new 'fields' parameters
- Added IBAN and Verwendungszweck to default export field selections
- Improved destinataer list UI by adding Status column and removing obsolete study proof field
- Fixed infinite growing animation bug in 'Größen der Grundstücke (Top 30)' chart by replacing Chart.js with CSS-based implementation
- Removed Bootstrap h-100 class conflicts that caused chart resize loops
This commit is contained in:
2025-09-24 22:13:27 +02:00
parent d3ed13dda0
commit b00cf62d87
4 changed files with 106 additions and 53 deletions

View File

@@ -99,14 +99,18 @@
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="card shadow h-100">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-bar me-2"></i>Größen der Grundstücke (Top 30)
</h6>
</div>
<div class="card-body">
<canvas id="sizesChart" height="140"></canvas>
<div style="height: 140px; overflow: hidden;">
<div id="sizesChart" style="display: flex; align-items: end; height: 100%; gap: 2px; padding: 5px;">
<!-- Simple CSS bar chart will be populated by JavaScript -->
</div>
</div>
</div>
</div>
</div>
@@ -395,42 +399,50 @@
console.log('usageChart canvas not found');
}
// Bar chart for sizes
const ctx = document.getElementById('sizesChart');
if (ctx) {
console.log('Found sizesChart canvas');
// Simple CSS bar chart for sizes (no Chart.js)
const chartContainer = document.getElementById('sizesChart');
if (chartContainer) {
console.log('Found sizesChart container');
const labels = JSON.parse('{{ size_chart_labels_json|escapejs }}');
const dataVals = JSON.parse('{{ size_chart_values_json|escapejs }}');
console.log('Bar chart data:', {labels: labels.length, values: dataVals.length});
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Größe (qm)',
data: dataVals,
backgroundColor: 'rgba(0, 104, 55, 0.6)',
borderColor: '#006837',
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { ticks: { autoSkip: true, maxTicksLimit: 10 } },
y: { beginAtZero: true }
},
plugins: {
legend: { display: false },
tooltip: { callbacks: { label: function(ctx) { return ctx.parsed.y.toLocaleString() + ' qm'; } } }
}
}
});
console.log('Bar chart created successfully');
if (dataVals.length > 0) {
const maxValue = Math.max(...dataVals);
chartContainer.innerHTML = ''; // Clear container
// Create bars
dataVals.forEach((value, index) => {
const barHeight = (value / maxValue) * 120; // Max height 120px
const bar = document.createElement('div');
bar.style.cssText = `
background-color: rgba(0, 104, 55, 0.8);
border: 1px solid #006837;
width: ${Math.max(100 / dataVals.length - 1, 8)}%;
height: ${barHeight}px;
min-height: 2px;
display: flex;
align-items: end;
justify-content: center;
font-size: 10px;
color: white;
text-shadow: 1px 1px 1px rgba(0,0,0,0.5);
cursor: pointer;
`;
// Add tooltip on hover
bar.title = `${labels[index] || 'N/A'}: ${value.toLocaleString()} qm`;
chartContainer.appendChild(bar);
});
console.log('CSS bar chart created successfully');
} else {
chartContainer.innerHTML = '<div style="text-align: center; color: #666; padding: 20px;">Keine Daten verfügbar</div>';
}
} else {
console.log('sizesChart canvas not found');
console.log('sizesChart container not found');
}
} catch (e) {
console.error('Chart initialization error:', e);