Skip to content

Instantly share code, notes, and snippets.

@diogogpinto
Created April 3, 2025 00:11
Show Gist options
  • Save diogogpinto/d70a795e0e1ba705d82102cefb6331f1 to your computer and use it in GitHub Desktop.
Save diogogpinto/d70a795e0e1ba705d82102cefb6331f1 to your computer and use it in GitHub Desktop.
Show CPU Load chart with Filament
<?php
namespace App\Filament\Widgets;
use Carbon\Carbon;
use Filament\Widgets\ChartWidget;
use Spatie\Health\Models\HealthCheckResultHistoryItem;
class CpuLoadChart extends ChartWidget
{
protected static ?string $heading = 'Server Load History';
protected static ?string $maxHeight = '250px';
protected static ?string $pollingInterval = '30s';
protected static string $color = 'info';
protected function getData(): array
{
// Get data from the health check results table
// Moved from custom to Spatie, Spatie does it better
$cpuLoadResults = HealthCheckResultHistoryItem::where('check_name', 'CPU Load')
->orderBy('created_at', 'desc')
->limit(20)
->get();
$history = [];
foreach ($cpuLoadResults as $result) {
// I suck at regex, a LLM did this because the notification is stored as a long string
preg_match('/CPU Load: ([\d.]+)%/', $result->notification_message, $matches);
if (! empty($matches)) {
$loadPercentage = (float) $matches[1];
$time = Carbon::parse($result->created_at)->format('H:i:s');
// Need to reverse later
$history[] = [
'time' => $time,
'load' => $loadPercentage,
];
}
}
$history = array_reverse($history);
$labels = [];
$data = [];
foreach ($history as $item) {
$labels[] = $item['time'];
$data[] = $item['load'];
}
// If we have no data, add a placeholder
if (empty($data)) {
$labels = [Carbon::now()->format('H:i:s')];
$data = [0];
}
return [
'datasets' => [
[
'label' => 'Server Load (%)',
'data' => $data,
'borderColor' => 'rgb(22, 184, 167)',
'backgroundColor' => 'rgba(22, 184, 167, 0.1)',
'borderWidth' => 2,
'tension' => 0.3,
'fill' => true,
'pointRadius' => 3,
'pointBackgroundColor' => 'rgb(59, 130, 246)',
'pointBorderColor' => '#fff',
'pointBorderWidth' => 1,
],
],
'labels' => $labels,
];
}
protected function getOptions(): array
{
return [
'scales' => [
'y' => [
'min' => 0,
'max' => 400,
'ticks' => [
'stepSize' => 20,
],
'title' => [
'display' => true,
'text' => 'Load (%)',
],
'grid' => [
'color' => 'rgba(0, 0, 0, 0.05)',
],
],
'x' => [
'title' => [
'display' => true,
'text' => 'Time',
],
'grid' => [
'display' => false,
],
],
],
'plugins' => [
'legend' => [
'display' => false,
],
'tooltip' => [
'mode' => 'index',
'intersect' => false,
'backgroundColor' => 'rgba(0, 0, 0, 0.7)',
],
],
'animation' => [
'duration' => 0,
],
'responsive' => true,
'maintainAspectRatio' => false,
'interaction' => [
'mode' => 'index',
'intersect' => false,
],
'elements' => [
'line' => [
'tension' => 0.3,
],
],
];
}
public function getType(): string
{
return 'line';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment