76
common/Database/Metrics/Partition.php
Executable file
76
common/Database/Metrics/Partition.php
Executable file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Database\Metrics;
|
||||
|
||||
use Illuminate\Contracts\Database\Query\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class Partition extends BaseMetric
|
||||
{
|
||||
public function __construct(
|
||||
Model|Builder|string $model,
|
||||
public string $groupBy,
|
||||
MetricDateRange $dateRange,
|
||||
string|Expression|null $column = null,
|
||||
?string $dateColumn = null,
|
||||
int $limit = 50,
|
||||
protected array $additionalColumns = [],
|
||||
) {
|
||||
parent::__construct($model, $dateRange, $column, $dateColumn, $limit);
|
||||
}
|
||||
|
||||
protected function aggregate(string $function): array
|
||||
{
|
||||
$select = [
|
||||
$this->groupBy,
|
||||
DB::raw("{$function}({$this->getWrappedColumn()}) as aggregate"),
|
||||
...$this->additionalColumns,
|
||||
];
|
||||
|
||||
$results = $this->query
|
||||
->select($select)
|
||||
->groupBy($this->groupBy, ...$this->additionalColumns)
|
||||
->when(
|
||||
$this->dateRange,
|
||||
fn($query) => $query->whereBetween($this->dateColumn, [
|
||||
$this->dateRange->start,
|
||||
$this->dateRange->end,
|
||||
]),
|
||||
)
|
||||
->limit($this->limit)
|
||||
->get();
|
||||
|
||||
$data = $results->map(function ($result) {
|
||||
$finalResult = [
|
||||
'label' => $this->getLabel($result),
|
||||
'value' => $this->round($result->aggregate),
|
||||
];
|
||||
foreach ($this->additionalColumns as $column) {
|
||||
$finalResult[$column] = $result->{$column};
|
||||
}
|
||||
return $finalResult;
|
||||
});
|
||||
$total = $data->sum('value');
|
||||
$data = $data
|
||||
->map(function ($item) use ($total) {
|
||||
$item['percentage'] = round((100 * $item['value']) / $total, 1);
|
||||
return $item;
|
||||
})
|
||||
->sortByDesc('value')
|
||||
->values();
|
||||
|
||||
return $data->all();
|
||||
}
|
||||
|
||||
protected function getLabel(Model $result): string
|
||||
{
|
||||
$label = with(
|
||||
$result->{last(explode('.', $this->groupBy))},
|
||||
fn($key) => $key,
|
||||
);
|
||||
|
||||
return __(ucfirst($label));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user