{{-- Server-rendered line/area chart (inline SVG, no JS). @include('partials.charts.line', ['data' => [['label'=>'Jan','value'=>10], …], 'height' => 180, 'format' => 'money'|'int'|'pct', 'title' => 'Enrollments']) Optional: 'area' => false to drop the soft fill, 'empty' => 'text'. --}} @php $rows = collect($data ?? [])->values(); $height = (int) ($height ?? 180); $format = $format ?? 'int'; $title = $title ?? 'Line chart'; $area = $area ?? true; $n = max(1, $rows->count()); $max = (float) $rows->max(fn ($r) => (float) ($r['value'] ?? 0)); // four even intervals: pick a "nice" step so the axis reads 0 · s · 2s · 3s · 4s $steps = $format === 'int' ? [1, 2, 3, 4, 5, 6, 8, 10] : [1, 2, 2.5, 3, 4, 5, 6, 8, 10]; if ($max <= 0) { $niceMax = 1; } elseif ($format === 'int' && $max <= 4) { $niceMax = 4; } else { $k = 10 ** floor(log10($max / 4)); $niceMax = 4 * $k * (collect($steps)->first(fn ($st) => 4 * $st * $k >= $max - 1e-9) ?? 10); } $compact = function ($v) use ($format) { $v = (float) $v; if ($format === 'pct') { return round($v).'%'; } $a = abs($v); if ($a >= 1e6) { return rtrim(rtrim(number_format($v / 1e6, 1), '0'), '.').'M'; } if ($a >= 1e3) { return rtrim(rtrim(number_format($v / 1e3, 1), '0'), '.').'K'; } return (string) round($v, 1); }; $full = fn ($v) => match ($format) { 'money' => money($v), 'pct' => round((float) $v, 1).'%', default => number_format((float) $v) }; $pts = $rows->map(fn ($r, $i) => [round(($i + .5) / $n * 100, 3), round(100 - ((float) ($r['value'] ?? 0)) / $niceMax * 100, 3)]); $line = $pts->map(fn ($p, $i) => ($i ? 'L' : 'M').$p[0].' '.$p[1])->implode(' '); $fill = $pts->isNotEmpty() ? $line.' L'.$pts->last()[0].' 100 L'.$pts->first()[0].' 100 Z' : ''; @endphp @if($rows->isEmpty() || $max <= 0)
| {{ $r['label'] ?? '' }} | {{ $full($r['value'] ?? 0) }} |
|---|