[], 'datasets' => [], ]; } $fromDateTime = Carbon::parse($fromDatetime); $toDateTime = Carbon::parse($toDatetime); if ($fromDateTime->gt($toDateTime) || $fromDateTime->gt(now()) || $toDateTime->gt(now())) { return [ 'labels' => [], 'datasets' => [], ]; } $durationHours = $fromDateTime->diffInHours($toDateTime); //dd($durationHours); if ($durationHours < 1 || $durationHours > 24) { return [ 'labels' => [], 'datasets' => [], ]; } $intervalCount = $durationHours > 12 ? 12 : 10; $intervalMinutes = $durationHours > 12 ? 120 : floor(($durationHours * 60) / $intervalCount); $labels = []; if ($parameter == 'Phase Voltage') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $voltageRYSummary = $dataAggregation('voltage_ry'); $voltageYBSummary = $dataAggregation('voltage_yb'); $voltageBRSummary = $dataAggregation('voltage_br'); $frequencySummary = $dataAggregation('frequency'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'Voltage RY Min', 'Voltage RY Max', 'Voltage RY Avg', 'Voltage YB Min', 'Voltage YB Max', 'Voltage YB Avg', 'Voltage BR Min', 'Voltage BR Max', 'Voltage BR Avg', 'Frequency Min', 'Frequency Max', 'Frequency Avg', ]; // Ordered data values matching labels above $dataValues = [ $voltageRYSummary['min'], $voltageRYSummary['max'], $voltageRYSummary['avg'], $voltageYBSummary['min'], $voltageYBSummary['max'], $voltageYBSummary['avg'], $voltageBRSummary['min'], $voltageBRSummary['max'], $voltageBRSummary['avg'], $frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else if ($parameter == 'Line Voltage') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $voltageRNSummary = $dataAggregation('voltage_r_n'); $voltageYNSummary = $dataAggregation('voltage_y_n'); $voltageBNSummary = $dataAggregation('voltage_b_n'); $frequencySummary = $dataAggregation('frequency'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'Voltage RN Min', 'Voltage RN Max', 'Voltage RN Avg', 'Voltage YN Min', 'Voltage YN Max', 'Voltage YN Avg', 'Voltage BN Min', 'Voltage BN Max', 'Voltage BN Avg', 'Frequency Min', 'Frequency Max', 'Frequency Avg', ]; // Ordered data values matching labels above $dataValues = [ $voltageRNSummary['min'], $voltageRNSummary['max'], $voltageRNSummary['avg'], $voltageYNSummary['min'], $voltageYNSummary['max'], $voltageYNSummary['avg'], $voltageBNSummary['min'], $voltageBNSummary['max'], $voltageBNSummary['avg'], $frequencySummary['min'], $frequencySummary['max'], $frequencySummary['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else if ($parameter == 'Current') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $curR = $dataAggregation('current_r'); $curY = $dataAggregation('current_y'); $curB = $dataAggregation('current_b'); $curN = $dataAggregation('current_n'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'Current R Min', 'Current R Max', 'Current R Avg', 'Current Y Min', 'Current Y Max', 'Current Y Avg', 'Current B Min', 'Current B Max', 'Current B Avg', 'Current N Min', 'Current N Max', 'Current N Avg', ]; // Ordered data values matching labels above $dataValues = [ $curR['min'], $curR['max'], $curR['avg'], $curY['min'], $curY['max'], $curY['avg'], $curB['min'], $curB['max'], $curB['avg'], $curN['min'], $curN['max'], $curN['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else if ($parameter == 'Active Power') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $activePowR = $dataAggregation('active_power_r'); $activePowY = $dataAggregation('active_power_y'); $activePowB = $dataAggregation('active_power_b'); $activePowTot = $dataAggregation('active_power_total'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'ActivePow R Min', 'ActivePow R Max', 'ActivePow R Avg', 'ActivePow Y Min', 'ActivePow Y Max', 'ActivePow Y Avg', 'ActivePow B Min', 'ActivePow B Max', 'ActivePow B Avg', 'ActivePow Tot Min', 'ActivePow Tot Max', 'ActivePow Tot Avg', ]; // Ordered data values matching labels above $dataValues = [ $activePowR['min'], $activePowR['max'], $activePowR['avg'], $activePowY['min'], $activePowY['max'], $activePowY['avg'], $activePowB['min'], $activePowB['max'], $activePowB['avg'], $activePowTot['min'], $activePowTot['max'], $activePowTot['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else if ($parameter == 'Power Factor') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $powFacR = $dataAggregation('power_factor_r'); $powFacY = $dataAggregation('power_factor_y'); $powFacB = $dataAggregation('power_factor_b'); $powFacTot = $dataAggregation('power_factor_total'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'PowerFac R Min', 'PowerFac R Max', 'PowerFac R Avg', 'PowerFac Y Min', 'PowerFac Y Max', 'PowerFac Y Avg', 'PowerFac B Min', 'PowerFac B Max', 'PowerFac B Avg', 'PowerFac Tot Min', 'PowerFac Tot Max', 'PowerFac Tot Avg', ]; // Ordered data values matching labels above $dataValues = [ $powFacR['min'], $powFacR['max'], $powFacR['avg'], $powFacY['min'], $powFacY['max'], $powFacY['avg'], $powFacB['min'], $powFacB['max'], $powFacB['avg'], $powFacTot['min'], $powFacTot['max'], $powFacTot['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else if ($parameter == 'Units') { // Helper function to get min, max, avg for a column with PostgreSQL casting $dataAggregation = function (string $column) use ($fromDateTime, $toDateTime, $meterId) { $min = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->min(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $max = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->max(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); $avg = MfmReading::whereBetween('created_at', [$fromDateTime, $toDateTime]) ->where('mfm_meter_id', $meterId) ->avg(\Illuminate\Support\Facades\DB::raw("{$column}::double precision")); return [ 'min' => round($min ?? 0, 2), 'max' => round($max ?? 0, 2), 'avg' => round($avg ?? 0, 2), ]; }; // Get aggregated data for all relevant columns $appEneRec = $dataAggregation('apparent_energy_received'); $reaEneRec = $dataAggregation('reactive_energy_received'); $actEneRec = $dataAggregation('active_energy_received'); // Labels for each bar on X-axis (min, max, avg per column) $labels = [ 'AppEneRec Min', 'AppEneRec Max', 'AppEneRec Avg', 'ReaEneRec Min', 'ReaEneRec Max', 'ReaEneRec Avg', 'ActEneRec Min', 'ActEneRec Max', 'ActEneRec Avg', ]; // Ordered data values matching labels above $dataValues = [ $appEneRec['min'], $appEneRec['max'], $appEneRec['avg'], $reaEneRec['min'], $reaEneRec['max'], $reaEneRec['avg'], $actEneRec['min'], $actEneRec['max'], $actEneRec['avg'], ]; // Colors by aggregation type: Min - yellow, Max - green, Avg - blue $aggregationColors = [ 'rgba(204, 163, 0, 0.8)', // Darker yellow (Min) 'rgba(30, 120, 120, 0.8)', // Darker teal/green (Max) 'rgba(30, 90, 140, 0.8)', // Darker blue (Avg) ]; // Each set of 3 bars per column repeats the colors: min, max, avg $backgroundColorArray = []; foreach (range(1, 4) as $group) { // 4 column groups foreach ($aggregationColors as $color) { $backgroundColorArray[] = $color; } } // Construct chart data structure return [ 'labels' => $labels, 'datasets' => [ [ 'label' => 'Phase Voltage & Frequency Stats', // Bar values array: 12 bars total (4 groups × 3 stats each) 'data' => $dataValues, 'backgroundColor' => $backgroundColorArray, 'borderColor' => array_map(fn ($clr) => str_replace('0.6', '1', $clr), $backgroundColorArray), 'borderWidth' => 1, ], ], ]; } else { $data = []; $labels = []; $currentStart = $fromDateTime->copy(); return [ 'labels' => $labels, 'datasets' => [ [ 'label' => ucfirst(str_replace('_', ' ', $parameter)), 'data' => $data, 'backgroundColor' => 'rgba(75, 192, 192, 0.2)', 'borderColor' => 'rgba(75, 192, 192, 1)', 'fill' => false, 'tension' => 0.3, 'pointRadius' => 5, 'pointHoverRadius' => 7, ], ], ]; } } protected function getOptions(): array { return [ 'plugins' => [ 'datalabels' => [ 'anchor' => 'start', 'align' => 'start', 'offset' => -15, 'color' => '#000', 'font' => [ 'weight' => 'bold', ], 'formatter' => RawJs::make('function(value) { return value; }'), ], ], 'scales' => [ 'y' => [ 'beginAtZero' => true, 'ticks' => [ 'stepSize' => 1, ], ], ], ]; } protected function getType(): string { return 'bar'; } }