Added trend chart analysis chart file
This commit is contained in:
553
app/Filament/Widgets/TrendChartAnalysis.php
Normal file
553
app/Filament/Widgets/TrendChartAnalysis.php
Normal file
@@ -0,0 +1,553 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
|
use App\Models\MfmReading;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Filament\Widgets\ChartWidget;
|
||||||
|
use Filament\Support\RawJs;
|
||||||
|
|
||||||
|
class TrendChartAnalysis extends ChartWidget
|
||||||
|
{
|
||||||
|
protected static ?string $heading = 'Trend Chart Analysis';
|
||||||
|
|
||||||
|
|
||||||
|
protected static ?string $maxHeight = '420px';
|
||||||
|
|
||||||
|
|
||||||
|
protected int|string|array $columnSpan = 12;
|
||||||
|
|
||||||
|
// Add a property to receive filters from parent or externally
|
||||||
|
|
||||||
|
protected function getData(): array
|
||||||
|
{
|
||||||
|
$fromDatetime = session('from_datetime');
|
||||||
|
$toDatetime = session('to_datetime');
|
||||||
|
$selectedPlant = session('selected_plant');
|
||||||
|
$meterId = session('selected_meter');
|
||||||
|
$parameter = session('parameter');
|
||||||
|
|
||||||
|
if (empty($fromDatetime) || empty($toDatetime) || empty($selectedPlant) || empty($meterId) || empty($parameter)) {
|
||||||
|
return [
|
||||||
|
'labels' => [],
|
||||||
|
'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';
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user