added production lines stop count chart
This commit is contained in:
@@ -23,8 +23,11 @@ class ProductionLineStopCount extends Page
|
|||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
{
|
{
|
||||||
|
session()->forget(['selected_plant', 'selected_line']);
|
||||||
$this->filtersForm->fill([
|
$this->filtersForm->fill([
|
||||||
'plant' => Plant::first()?->id // Default to first plant
|
//'plant' => Plant::first()?->id // Default to first plant
|
||||||
|
'plant' => null,
|
||||||
|
'line' => null,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,10 +55,7 @@ class ProductionLineStopCount extends Page
|
|||||||
->reactive()
|
->reactive()
|
||||||
->afterStateUpdated(function ($state) {
|
->afterStateUpdated(function ($state) {
|
||||||
session(['selected_line' => $state]);
|
session(['selected_line' => $state]);
|
||||||
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
])
|
])
|
||||||
->columns(2);
|
->columns(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,29 +11,137 @@ class ProductionLineStopChart extends ChartWidget
|
|||||||
protected static ?string $maxHeight = '250px';
|
protected static ?string $maxHeight = '250px';
|
||||||
|
|
||||||
protected function getData(): array
|
protected function getData(): array
|
||||||
|
{
|
||||||
|
$activeFilter = $this->filter;
|
||||||
|
$selectedPlant = session('selected_plant');
|
||||||
|
$selectedLine = session('selected_line');
|
||||||
|
|
||||||
|
if (!$selectedPlant || !$selectedLine)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'datasets' => [
|
'datasets' => [],
|
||||||
[
|
'labels' => [],
|
||||||
'label' => 'Production by Category',
|
|
||||||
'data' => [25, 40, 20, 15],
|
|
||||||
'backgroundColor' => [
|
|
||||||
'#f87171', // Red
|
|
||||||
'#60a5fa', // Blue
|
|
||||||
'#34d399', // Green
|
|
||||||
'#fbbf24', // Yellow
|
|
||||||
],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'labels' => ['Line A', 'Line B', 'Line C', 'Line D'],
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 = [];
|
||||||
|
|
||||||
|
foreach ($query as $row) {
|
||||||
|
// --- STOP TIME (HH.MM format) ---
|
||||||
|
$stopHours = $row->total_stop_hours;
|
||||||
|
$stopMinutes = $row->total_stop_minutes;
|
||||||
|
$visualTotal = $stopHours + ($stopMinutes / 100); // e.g., 0.15 (15 mins), 1.30 (1h 30m)
|
||||||
|
|
||||||
|
// --- RUNTIME (HH.MM format) ---
|
||||||
|
// 1. Convert stop time to total minutes
|
||||||
|
$totalStopMinutes = ($stopHours * 60) + $stopMinutes;// Using 60 for minutes conversion
|
||||||
|
|
||||||
|
// Calculate remaining minutes (1440 = 24 hours)
|
||||||
|
$remainingMinutes = 1440 - $totalStopMinutes;
|
||||||
|
|
||||||
|
// Convert back to "HH.MM" format (e.g., 22.59 = 22 hours 59 minutes)
|
||||||
|
$runtimeHours = floor($remainingMinutes / 60);
|
||||||
|
$runtimeMinutes = $remainingMinutes % 60;
|
||||||
|
$runtime = $runtimeHours + ($runtimeMinutes / 100); // Remaining hours correctly calculated
|
||||||
|
|
||||||
|
// Labels for stop and runtime
|
||||||
|
$stopLabel = $row->code . ' - ' . $row->reason . ' (Stop)';
|
||||||
|
$runtimeLabel = $row->code . ' - ' . $row->reason . ' (Runtime)';
|
||||||
|
|
||||||
|
// Red bar = visual format using stop time
|
||||||
|
$labels[] = $stopLabel;
|
||||||
|
$data[] = $visualTotal;
|
||||||
|
$backgroundColors[] = 'rgba(255, 99, 132, 0.7)';
|
||||||
|
$borderColors[] = 'rgba(255, 99, 132, 1)';
|
||||||
|
|
||||||
|
// Green bar = correct runtime math
|
||||||
|
$labels[] = $runtimeLabel;
|
||||||
|
$data[] = $runtime;
|
||||||
|
$backgroundColors[] = 'rgba(75, 192, 75, 0.4)';
|
||||||
|
$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
|
protected function getType(): string
|
||||||
{
|
{
|
||||||
return 'doughnut';
|
return 'doughnut';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function getFilters(): ?array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'today' => 'Today',
|
||||||
|
'yesterday' => 'Yesterday',
|
||||||
|
'this_week'=> 'This Week',
|
||||||
|
'this_month'=> 'This Month',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
public static function canView(): bool
|
public static function canView(): bool
|
||||||
{
|
{
|
||||||
// Only show on HourlyProduction page
|
// Only show on HourlyProduction page
|
||||||
|
|||||||
Reference in New Issue
Block a user