@props(['module']) @php $title = data_get($module, 'title', 'Évolution'); $subtitle = data_get($module, 'description'); $series = collect(data_get($module, 'data.series', []))->values(); $unit = (string) data_get($module, 'data.unit', 'min'); $seriesColors = [ 'var(--dashboard-green)', 'var(--dashboard-blue)', 'var(--dashboard-amber)', 'var(--dashboard-red)', '#b7e06a', '#c79bf2', ]; $formatNumber = fn (mixed $value): string => rtrim(rtrim(number_format((float) $value, 1, ',', ' '), '0'), ','); $formatValue = function (mixed $value) use ($formatNumber, $unit): string { if (in_array($unit, ['min', 'minutes'], true)) { $minutes = max(0, (int) round((float) $value)); $hours = intdiv($minutes, 60); $remaining = $minutes % 60; return $hours > 0 ? $hours . 'h' . str_pad((string) $remaining, 2, '0', STR_PAD_LEFT) : $remaining . ' min'; } return trim($formatNumber($value) . ' ' . $unit); }; $buildAxis = function (float $min, float $max): array { if ($min === $max) { $max = $min + 1; } $rawStep = ($max - $min) / 4; $magnitude = 10 ** floor(log10(max($rawStep, 1))); $normalized = $rawStep / $magnitude; $step = match (true) { $normalized <= 1 => $magnitude, $normalized <= 2 => 2 * $magnitude, $normalized <= 5 => 5 * $magnitude, default => 10 * $magnitude, }; $axisMin = $min < 0 ? floor($min / $step) * $step : 0; $axisMax = max($step, ceil($max / $step) * $step); return [$axisMin, $axisMax, max($step, $axisMax - $axisMin)]; }; $allValues = $series ->flatMap(fn ($item) => collect(data_get($item, 'points', []))->map(fn ($point) => data_get($point, 'value'))) ->filter(fn ($value) => $value !== null) ->map(fn ($value) => (float) $value) ->values(); $actualMinValue = (float) ($allValues->min() ?? 0); $actualMaxValue = (float) ($allValues->max() ?? 0); [$axisMin, $axisMax, $rangeValue] = $buildAxis($actualMinValue, $actualMaxValue); $firstPoints = collect(data_get($series->first(), 'points', [])); $firstLabel = data_get($firstPoints->first(), 'label', ''); $lastLabel = data_get($firstPoints->last(), 'label', ''); $averageValue = $allValues->isNotEmpty() ? (float) $allValues->avg() : 0; $plotLeft = 2; $plotRight = 98; $plotTop = 8; $plotBottom = 88; $plotWidth = $plotRight - $plotLeft; $plotHeight = $plotBottom - $plotTop; $axisTicks = collect([1, 0.75, 0.5, 0.25, 0])->map(function (float $ratio) use ($axisMin, $rangeValue, $plotTop, $plotHeight) { return [ 'value' => $axisMin + ($rangeValue * $ratio), 'y' => $plotTop + ((1 - $ratio) * $plotHeight), ]; }); $averageY = $plotBottom - ((($averageValue - $axisMin) / $rangeValue) * $plotHeight); $labels = $firstPoints->map(fn ($point) => (string) data_get($point, 'label', ''))->values(); $xAxisLabels = $labels ->map(fn (string $label, int $index): array => [ 'label' => $label, 'x' => $labels->count() <= 1 ? 50 : $plotLeft + (($index / max(1, $labels->count() - 1)) * $plotWidth), 'index' => $index, ]) ->values(); @endphp
merge(['class' => 'dashboard-panel module-chart-card']) }}>

{{ $subtitle }}

{{ $title }}

@if (data_get($module, 'meta.period')) {{ trans_choice('ui.common.days', data_get($module, 'meta.period'), ['count' => data_get($module, 'meta.period')]) }} @endif
@if ($series->isNotEmpty())
@foreach ($axisTicks as $tick) @endforeach @foreach ($series as $index => $item) @php $points = collect(data_get($item, 'points', [])); $values = $points->map(fn ($point) => data_get($point, 'value'))->values(); $count = max(1, $values->count()); $segment = []; $color = $seriesColors[$index % count($seriesColors)]; foreach ($values as $pointIndex => $value) { if ($value === null) { continue; } $floatValue = (float) $value; $x = $count === 1 ? $plotLeft + ($plotWidth / 2) : $plotLeft + (($pointIndex / ($count - 1)) * $plotWidth); $y = $plotBottom - ((($floatValue - $axisMin) / $rangeValue) * $plotHeight); $segment[] = number_format($x, 2, '.', '') . ',' . number_format($y, 2, '.', ''); } @endphp @if ($segment !== []) @endif @endforeach
@foreach ($series as $index => $item) @php $points = collect(data_get($item, 'points', [])); $values = $points->map(fn ($point) => data_get($point, 'value'))->values(); $count = max(1, $values->count()); $color = $seriesColors[$index % count($seriesColors)]; @endphp @foreach ($values as $pointIndex => $value) @continue($value === null) @php $floatValue = (float) $value; $x = $count === 1 ? $plotLeft + ($plotWidth / 2) : $plotLeft + (($pointIndex / ($count - 1)) * $plotWidth); $y = $plotBottom - ((($floatValue - $axisMin) / $rangeValue) * $plotHeight); $pointLabel = (string) data_get($points->get($pointIndex), 'label', ''); $pointDate = (string) data_get($points->get($pointIndex), 'date', ''); $seriesName = (string) data_get($item, 'name', ''); @endphp @endforeach @endforeach
{{ $firstLabel }} → {{ $lastLabel }} {{ __('Moy.') }} {{ $formatValue($averageValue) }} {{ __('Max') }} {{ $formatValue($actualMaxValue) }}
@else
{{ __('Aucune donnée disponible sur cette période.') }}
@endif