From bc12dd8d747516ffce7e751596b594a69d0fb821 Mon Sep 17 00:00:00 2001 From: Salah Kanjo Date: Tue, 6 Aug 2024 19:51:02 +0300 Subject: [PATCH] feat: auto-detect enums + getLabel method --- README.md | 32 ++++++++++++++++++++++------- src/Metrics/Doughnut.php | 31 ++++++++++++++++++++++++++-- tests/src/Doughnut/DoughnutTest.php | 15 ++------------ 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 3176e39..400dac5 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ > ✨ Help support the maintenance of this package by [sponsoring me](https://github.com/sponsors/sakanjo). -> Designed to work with **Laravel**, **Filament**, and more. +> Designed to work with **Laravel**, **Filament**, [Easy enum](https://github.com/sakanjo/laravel-easy-enum), and more. ![Preview](./art/preview.png) @@ -42,6 +42,8 @@ Table of contents * [Using trend metric](#using-trend-metric) * [Using doughnut metric](#using-doughnut-metric) * [Available growth rate types](#available-growth-rate-types) +* [Tips](#-tips) + * [using getLabel](#using-getLabel) * [Practical examples](#-practical-examples) * [Filamentphp v3 widgets](#filamentphp-v3-widgets) * [Support the development](#-support-the-development) @@ -110,15 +112,11 @@ Value::make(User::class) ```php use SaKanjo\EasyMetrics\Metrics\Doughnut; use App\Models\User; -use App\Enums\Gender; [$labels, $data] = Doughnut::make(User::class) - ->options(Gender::class) ->count('gender'); ``` -> It's always better to use the `options` method even though it's optional, since the retrieved data may not include all enum options. - #### Query types The currently supported aggregate functions to calculate a given column compared to the previous time interval / range @@ -295,10 +293,8 @@ use App\Models\User; ```php use SaKanjo\EasyMetrics\Metrics\Doughnut; use App\Models\User; -use App\Enums\Gender; [$labels, $data, $growth] = Doughnut::make(User::class) - ->options(Gender::class) ->withGrowthRate() ->count('gender'); ``` @@ -309,6 +305,28 @@ use App\Enums\Gender; - `GrowthRateType::Value` - `GrowthRateType::Percentage` +## 🔥 Tips + +#### Using getLabel + +You can use the `getLabel` method to customize the retreived data labels, for example: + +```php +options) { + return $this->options; + } + + $cast = $this->query->getModel()->getCasts()[$this->groupBy] ?? null; + + if ($cast && (new ReflectionEnum($cast))->isBacked()) { + return Arr::pluck($cast::cases(), 'value'); + } + + return []; + } + public function min(string $column, string $groupBy) { return $this->setType('min', $groupBy, $column); @@ -87,10 +103,21 @@ public function resolveValue(?array $range): array }) ->toArray(); - $options = array_fill_keys($this->options ?? [], 0); - + $options = array_fill_keys($this->getOptions(), 0); $data = array_replace($options, $results); + $cast = $this->query->getModel()->getCasts()[$this->groupBy] ?? null; + + if ( + $cast && + (new ReflectionEnum($cast))->isBacked() && + method_exists($cast, 'getLabel') + ) { + $data = Arr::mapWithKeys($data, fn (float $value, mixed $key) => [ + $cast::from($key)->getLabel() => $value, // @phpstan-ignore-line + ]); + } + return $data; } diff --git a/tests/src/Doughnut/DoughnutTest.php b/tests/src/Doughnut/DoughnutTest.php index 7590006..2926674 100644 --- a/tests/src/Doughnut/DoughnutTest.php +++ b/tests/src/Doughnut/DoughnutTest.php @@ -36,7 +36,7 @@ ]); }); -it('shows limited options when using `options` method', function () { +it('shows all options when not using `options` method', function () { $sequence = [ // ['gender' => Gender::Male], // ['gender' => Gender::Male], @@ -54,6 +54,7 @@ ->count('gender'); assertEquals($doughnut->getLabels(), [ + Gender::Male->value, Gender::Female->value, ]); }); @@ -174,7 +175,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::ALL) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -183,7 +183,6 @@ assertEquals($doughnut->getGrowthRate(), [2, 3]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::ALL) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage) @@ -206,7 +205,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -215,7 +213,6 @@ assertEquals($doughnut->getGrowthRate(), [-1, -1]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage) @@ -238,7 +235,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -247,7 +243,6 @@ assertEquals($doughnut->getGrowthRate(), [-35, -30]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage) @@ -270,7 +265,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -279,7 +273,6 @@ assertEquals($doughnut->getGrowthRate(), [-70, -30]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage) @@ -302,7 +295,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -311,7 +303,6 @@ assertEquals($doughnut->getGrowthRate(), [-50, -30]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage) @@ -334,7 +325,6 @@ ->create(); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Value) @@ -343,7 +333,6 @@ assertEquals($doughnut->getGrowthRate(), [-20, -30]); $doughnut = Doughnut::make(User::class) - ->options(Gender::class) ->range(Range::TODAY) ->withGrowthRate() ->growthRateType(GrowthRateType::Percentage)