filter; $selectedPlant = session('selected_plant'); $selectedLine = session('selected_line'); if (!$selectedPlant || !$selectedLine) { return [ 'datasets' => [], 'labels' => [], ]; } // Set time range based on active filter if ($activeFilter === 'yesterday') { $startDate = now()->subDay()->setTime(8, 0, 0); $endDate = now()->setTime(8, 0, 0); } elseif ($activeFilter === 'this_week') { $startDate = now()->startOfWeek()->setTime(8, 0, 0); $endDate = now()->endOfWeek()->addDay()->setTime(8, 0, 0); } elseif ($activeFilter === 'this_month') { $startDate = now()->startOfMonth(); $endDate = now()->endOfMonth(); } else { $startDate = now()->setTime(8, 0, 0); $endDate = now()->copy()->addDay()->setTime(8, 0, 0); } // Fetch stop reason data // treats minutes as a visual decimal (e.g., 15 mins = 0.15) $query = \DB::table('production_line_stops') ->join('line_stops as ls', 'production_line_stops.linestop_id', '=', 'ls.id') ->join('lines', 'production_line_stops.line_id', '=', 'lines.id') ->join('plants', 'production_line_stops.plant_id', '=', 'plants.id') ->select( 'ls.code', 'ls.reason', \DB::raw(" SUM(production_line_stops.stop_hour) as total_stop_hours, SUM(production_line_stops.stop_min) as total_stop_minutes ") ) ->when($selectedPlant, fn($q) => $q->where('plants.id', $selectedPlant)) ->when($selectedLine, fn($q) => $q->where('lines.id', $selectedLine)) ->whereBetween('production_line_stops.created_at', [$startDate, $endDate]) ->groupBy('ls.code', 'ls.reason') //->orderByDesc('total_hours') ->get(); // Handle empty data gracefully if ($query->isEmpty()) { return [ 'datasets' => [[ 'label' => 'Line Stop Reasons', 'data' => [1], 'backgroundColor' => ['rgba(200, 200, 200, 0.4)'], 'borderColor' => ['rgba(200, 200, 200, 1)'], 'borderWidth' => 1, ]], 'labels' => ['No Data'], ]; } $labels = []; $data = []; $backgroundColors = []; $borderColors = []; function generateColor(string $key, float $opacity): string { // Use a stable hash of the key, no randomness $hash = md5($key); // Get the RGB components from the hash $r = hexdec(substr($hash, 0, 2)); // Red component $g = hexdec(substr($hash, 2, 2)); // Green component $b = hexdec(substr($hash, 4, 2)); // Blue component // Avoid deep green colors for the `code` if ($g > 150 && $g < 255) { // Adjust green component if it's in the deep green range $g = 150; // Assign a fixed, safe value for green } // Return the color as rgba with the specified opacity return "rgba($r, $g, $b, $opacity)"; } $totalStopMinutes = 0; foreach ($query as $row) { $code = $row->code; $reason = $row->reason; $stopHours = $row->total_stop_hours; $stopMinutes = $row->total_stop_minutes; $visualTotal = $stopHours + ($stopMinutes / 100); $codeLabel = "$code - $reason"; $labels[] = $codeLabel; $data[] = $visualTotal; $backgroundColors[] = generateColor($code, 0.7); // Unique color for each stop code $borderColors[] = generateColor($code, 1.0); // Accumulate total stop time (in minutes) $totalStopMinutes += ($stopHours * 60) + $stopMinutes; } // Calculate remaining time (1440 minutes = 24 hours) $remainingMinutes = 1440 - $totalStopMinutes; $runtimeHours = floor($remainingMinutes / 60); $runtimeMinutes = $remainingMinutes % 60; $runtimeVisual = $runtimeHours + ($runtimeMinutes / 100); // Add runtime slice with green color (either light or dark green) $labels[] = 'Available Runtime'; $data[] = $runtimeVisual; $backgroundColors[] = 'rgba(47, 218, 47, 0.94)'; // Green for runtime $borderColors[] = 'rgba(75, 192, 75, 1)'; return [ 'datasets' => [[ 'label' => 'Line Stop Durations (hrs)', 'data' => $data, 'backgroundColor' => $backgroundColors, 'borderColor' => $borderColors, 'borderWidth' => 1, ]], 'labels' => $labels, ]; } protected function getType(): string { return 'pie'; } protected function getFilters(): ?array { return [ 'today' => 'Today', 'yesterday' => 'Yesterday', ]; } protected function getOptions(): array { return [ 'responsive' => true, 'plugins' => [ 'legend' => [ 'position' => 'bottom', ], 'tooltip' => [ 'enabled' => true, // Tooltips enabled on hover ], ], 'scales' => [ 'x' => [ 'display' => false, // Disable x-axis ], 'y' => [ 'display' => false, // Disable y-axis ], ], ]; } public static function canView(): bool { // Only show on HourlyProduction page return request()->routeIs('filament.pages.production-line-stop-count'); } }