Added rfq chart and rfq rank chart widgets page
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 2m23s
Laravel Pint / pint (pull_request) Failing after 2m30s
Some checks failed
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (push) Successful in 10s
Scan for leaked secrets using Kingfisher / kingfisher-secrets-scan (pull_request) Successful in 11s
Gemini PR Review / Gemini PR Review (pull_request) Successful in 14s
Laravel Larastan / larastan (pull_request) Failing after 2m23s
Laravel Pint / pint (pull_request) Failing after 2m30s
This commit is contained in:
205
app/Filament/Widgets/RfqRankChart.php
Normal file
205
app/Filament/Widgets/RfqRankChart.php
Normal file
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\RfqTransporterBid;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Illuminate\Support\Js;
|
||||
|
||||
class RfqRankChart extends ChartWidget
|
||||
{
|
||||
protected static ?string $heading = 'Chart';
|
||||
|
||||
// protected function getData(): array
|
||||
// {
|
||||
// $rfqId = session('rfq_id');
|
||||
|
||||
// if (!$rfqId) {
|
||||
// return [
|
||||
// 'datasets' => [],
|
||||
// 'labels' => [],
|
||||
// ];
|
||||
// }
|
||||
|
||||
// // Get bids ordered by lowest freight charge
|
||||
// $bids = RfqTransporterBid::query()
|
||||
// ->where('request_quotation_id', $rfqId)
|
||||
// ->orderByRaw('CAST(total_freight_charge AS DECIMAL(10,2)) ASC')
|
||||
// ->get();
|
||||
|
||||
// // $labels = [];
|
||||
// // $ranks = [];
|
||||
|
||||
// // $rank = 1;
|
||||
// // foreach ($bids as $bid) {
|
||||
// // $labels[] = $bid->transporter_name;
|
||||
// // $ranks[] = $rank++;
|
||||
// // }
|
||||
|
||||
// // return [
|
||||
// // 'datasets' => [
|
||||
// // [
|
||||
// // 'label' => 'Rank (Lower is Better)',
|
||||
// // 'data' => $ranks,
|
||||
// // 'fill' => false,
|
||||
// // 'tension' => 0.3,
|
||||
// // ],
|
||||
// // ],
|
||||
// // 'labels' => $labels,
|
||||
// // ];
|
||||
// $labels = [];
|
||||
// $ranks = [];
|
||||
// $colors = [];
|
||||
|
||||
// $rank = 1;
|
||||
// foreach ($bids as $bid) {
|
||||
// $labels[] = $bid->transporter_name;
|
||||
// $ranks[] = $rank;
|
||||
|
||||
// // Rank-based colors
|
||||
// $colors[] = match ($rank) {
|
||||
// 1 => '#FFD700', // Gold
|
||||
// 2 => '#C0C0C0', // Silver
|
||||
// 3 => '#CD7F32', // Bronze
|
||||
// default => '#3B82F6', // Blue
|
||||
// };
|
||||
|
||||
// $rank++;
|
||||
// }
|
||||
|
||||
// return [
|
||||
// 'datasets' => [
|
||||
// [
|
||||
// 'label' => 'Rank (1 = Best)',
|
||||
// 'data' => $ranks,
|
||||
|
||||
// // 🎨 Styling
|
||||
// 'borderColor' => '#3B82F6',
|
||||
// 'backgroundColor' => $colors,
|
||||
// 'pointBackgroundColor' => $colors,
|
||||
// 'pointBorderColor' => '#000',
|
||||
// 'pointRadius' => 7,
|
||||
// 'pointHoverRadius' => 10,
|
||||
// 'borderWidth' => 3,
|
||||
// 'tension' => 0.4,
|
||||
// 'fill' => false,
|
||||
// ],
|
||||
// ],
|
||||
// 'labels' => $labels,
|
||||
// ];
|
||||
// }
|
||||
|
||||
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$rfqId = session('rfq_id');
|
||||
|
||||
if (!$rfqId) {
|
||||
return [
|
||||
'datasets' => [],
|
||||
'labels' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 1: Get bids sorted by freight charge (for ranking)
|
||||
*/
|
||||
$rankedBids = RfqTransporterBid::query()
|
||||
->where('request_quotation_id', $rfqId)
|
||||
->orderByRaw('CAST(total_freight_charge AS DECIMAL(10,2)) ASC')
|
||||
->get();
|
||||
|
||||
$rankMap = [];
|
||||
$rank = 1;
|
||||
|
||||
foreach ($rankedBids as $bid) {
|
||||
$rankMap[$bid->id] = $rank++;
|
||||
}
|
||||
|
||||
/**
|
||||
* STEP 2: Get bids in natural order (for wave effect)
|
||||
* You can change orderBy to:
|
||||
* - created_at
|
||||
* - transporter_name
|
||||
*/
|
||||
$chartBids = RfqTransporterBid::query()
|
||||
->where('request_quotation_id', $rfqId)
|
||||
->orderBy('id')
|
||||
->get();
|
||||
|
||||
$labels = [];
|
||||
$amounts = [];
|
||||
$colors = [];
|
||||
|
||||
$ranks = [];
|
||||
|
||||
foreach ($chartBids as $bid) {
|
||||
$labels[] = $bid->transporter_name;
|
||||
$amounts[] = (float) $bid->total_freight_charge;
|
||||
|
||||
$rank = $rankMap[$bid->id];
|
||||
$ranks[] = $rank;
|
||||
|
||||
$colors[] = match ($rank) {
|
||||
1 => '#FFD700',
|
||||
2 => '#C0C0C0',
|
||||
3 => '#CD7F32',
|
||||
default => '#2563EB',
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => 'Freight Charge',
|
||||
'data' => $amounts,
|
||||
'rankData' => $ranks,
|
||||
|
||||
'borderColor' => '#2563EB',
|
||||
'backgroundColor' => $colors,
|
||||
'pointBackgroundColor' => $colors,
|
||||
'pointBorderColor' => '#000',
|
||||
'pointRadius' => 7,
|
||||
'pointHoverRadius' => 11,
|
||||
'borderWidth' => 3,
|
||||
'tension' => 0.45,
|
||||
'fill' => false,
|
||||
],
|
||||
],
|
||||
'labels' => $labels,
|
||||
];
|
||||
}
|
||||
|
||||
protected function getOptions(): array
|
||||
{
|
||||
return [
|
||||
'plugins' => [
|
||||
'datalabels' => [
|
||||
'anchor' => 'start',
|
||||
'align' => 'start',
|
||||
'offset' => -15,
|
||||
'color' => '#000',
|
||||
'font' => [
|
||||
'weight' => 'bold',
|
||||
],
|
||||
'formatter' => Js::from("function(value) { return Number(value); }"),
|
||||
],
|
||||
],
|
||||
'scales' => [
|
||||
'y' => [
|
||||
'beginAtZero' => true,
|
||||
'ticks' => [
|
||||
'stepSize' => 0.5,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'bar';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user