10.April 2026
This commit is contained in:
parent
a00c42e770
commit
f58c709945
208 changed files with 19280 additions and 2914 deletions
111
resources/views/user/abo/_abo_chart.blade.php
Normal file
111
resources/views/user/abo/_abo_chart.blade.php
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
@php
|
||||
$chartId = 'aboChart_' . str_replace('.', '', microtime(true));
|
||||
$chartDataJson = json_encode(array_values($chartData));
|
||||
$chartLabelsJson = json_encode(array_values($chartMonths));
|
||||
$nonNullValues = array_filter($chartData, fn($v) => $v !== null);
|
||||
$maxVal = count($nonNullValues) ? max($nonNullValues) : 0;
|
||||
|
||||
// Großzügige Schritte für die Y-Achse
|
||||
if ($maxVal <= 5) { $stepSize = 1; }
|
||||
elseif ($maxVal <= 10) { $stepSize = 2; }
|
||||
elseif ($maxVal <= 20) { $stepSize = 5; }
|
||||
elseif ($maxVal <= 50) { $stepSize = 10; }
|
||||
elseif ($maxVal <= 100) { $stepSize = 20; }
|
||||
elseif ($maxVal <= 200) { $stepSize = 50; }
|
||||
elseif ($maxVal <= 500) { $stepSize = 100; }
|
||||
elseif ($maxVal <= 1000) { $stepSize = 200; }
|
||||
else { $stepSize = 500; }
|
||||
|
||||
// Genug Platz nach oben, damit das Label nicht abgeschnitten wird
|
||||
$suggestedMax = $maxVal + $stepSize;
|
||||
@endphp
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-body pb-2">
|
||||
<div class="d-flex justify-content-between align-items-center flex-wrap">
|
||||
<h6 class="font-weight-bold mb-2">
|
||||
{{ __('abo.chart_monthly_abos') }}
|
||||
<span class="text-muted font-weight-normal ml-1">{{ $chartYear }}</span>
|
||||
</h6>
|
||||
<div class="mb-2">
|
||||
@foreach($chartYears as $y)
|
||||
<a href="{{ url()->current() }}?year={{ $y }}"
|
||||
class="btn btn-xs btn-sm {{ $chartYear == $y ? 'btn-secondary' : 'btn-outline-secondary' }} mr-1 mb-1">
|
||||
{{ $y }}
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="m-0">
|
||||
<div class="card-body pt-3 pb-2">
|
||||
<canvas id="{{ $chartId }}" height="80"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/vendor/libs/chartjs/chartjs.js"></script>
|
||||
<script>
|
||||
(function () {
|
||||
// Inline data-labels plugin für Chart.js v2
|
||||
var dataLabelsPlugin = {
|
||||
afterDatasetsDraw: function (chart) {
|
||||
var ctx = chart.ctx;
|
||||
chart.data.datasets.forEach(function (dataset, i) {
|
||||
var meta = chart.getDatasetMeta(i);
|
||||
if (meta.hidden) { return; }
|
||||
meta.data.forEach(function (bar, index) {
|
||||
var value = dataset.data[index];
|
||||
if (value === null || value === undefined || value === 0) { return; }
|
||||
ctx.save();
|
||||
ctx.fillStyle = '#495057';
|
||||
ctx.font = 'bold 11px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'bottom';
|
||||
ctx.fillText(value, bar._model.x, bar._model.y - 3);
|
||||
ctx.restore();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var ctx = document.getElementById('{{ $chartId }}').getContext('2d');
|
||||
new Chart(ctx, {
|
||||
type: 'bar',
|
||||
plugins: [dataLabelsPlugin],
|
||||
data: {
|
||||
labels: {!! $chartLabelsJson !!},
|
||||
datasets: [{
|
||||
label: '{{ __('abo.chart_active_abos') }}',
|
||||
data: {!! $chartDataJson !!},
|
||||
backgroundColor: 'rgba(102, 110, 232, 0.2)',
|
||||
borderColor: 'rgba(102, 110, 232, 0.8)',
|
||||
borderWidth: 1
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
legend: { display: false },
|
||||
tooltips: { enabled: false },
|
||||
layout: {
|
||||
padding: { top: 20 }
|
||||
},
|
||||
scales: {
|
||||
yAxes: [{
|
||||
ticks: {
|
||||
beginAtZero: true,
|
||||
stepSize: {{ $stepSize }},
|
||||
suggestedMax: {{ $suggestedMax }},
|
||||
callback: function (value) {
|
||||
return Number.isInteger(value) ? value : null;
|
||||
}
|
||||
},
|
||||
gridLines: { color: 'rgba(0,0,0,0.05)' }
|
||||
}],
|
||||
xAxes: [{
|
||||
gridLines: { display: false }
|
||||
}]
|
||||
}
|
||||
}
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue