Просмотр исходного кода

add user and employee charts

3.x
Andrew Wallo 2 лет назад
Родитель
Сommit
345752c9d8

+ 1
- 0
app/Filament/Pages/Employees.php Просмотреть файл

25
     protected function getHeaderWidgets(): array
25
     protected function getHeaderWidgets(): array
26
     {
26
     {
27
         return [
27
         return [
28
+            Widgets\CumulativeEmployeeData::class,
28
             Widgets\Employees::class,
29
             Widgets\Employees::class,
29
         ];
30
         ];
30
     }
31
     }

+ 1
- 0
app/Filament/Pages/Users.php Просмотреть файл

25
     protected function getHeaderWidgets(): array
25
     protected function getHeaderWidgets(): array
26
     {
26
     {
27
         return [
27
         return [
28
+            Widgets\CumulativeUserData::class,
28
             Widgets\Users::class,
29
             Widgets\Users::class,
29
         ];
30
         ];
30
     }
31
     }

+ 6
- 2
app/Filament/Pages/Widgets/CumulativeCompanyData.php Просмотреть файл

68
             $year = substr($week, 0, 4);
68
             $year = substr($week, 0, 4);
69
             $weekNumber = substr($week, 4);
69
             $weekNumber = substr($week, 4);
70
 
70
 
71
-            return now()->setISODate($year, $weekNumber)->format('Y-m-d');
71
+            return today()->setISODate($year, $weekNumber)->format('M d');
72
         });
72
         });
73
 
73
 
74
         return [
74
         return [
98
                 ],
98
                 ],
99
             ],
99
             ],
100
             'xaxis' => [
100
             'xaxis' => [
101
-                'type' => 'datetime',
102
                 'categories' => $labels,
101
                 'categories' => $labels,
102
+                'position' => 'bottom',
103
                 'labels' => [
103
                 'labels' => [
104
                     'style' => [
104
                     'style' => [
105
                         'colors' => '#9ca3af',
105
                         'colors' => '#9ca3af',
119
                 ],
119
                 ],
120
                 [
120
                 [
121
                     'seriesName' => 'New Companies',
121
                     'seriesName' => 'New Companies',
122
+                    'decimalsInFloat' => 0,
122
                     'opposite' => true,
123
                     'opposite' => true,
123
                     'labels' => [
124
                     'labels' => [
124
                         'style' => [
125
                         'style' => [
129
                 ],
130
                 ],
130
                 [
131
                 [
131
                     'seriesName' => 'Total Companies',
132
                     'seriesName' => 'Total Companies',
133
+                    'decimalsInFloat' => 0,
132
                     'opposite' => true,
134
                     'opposite' => true,
133
                     'labels' => [
135
                     'labels' => [
134
                         'style' => [
136
                         'style' => [
139
                 ],
141
                 ],
140
             ],
142
             ],
141
             'legend' => [
143
             'legend' => [
144
+                'position' => 'top',
145
+                'horizontalAlign' => 'center',
142
                 'labels' => [
146
                 'labels' => [
143
                     'colors' => '#9ca3af',
147
                     'colors' => '#9ca3af',
144
                     'fontWeight' => 600,
148
                     'fontWeight' => 600,

+ 179
- 0
app/Filament/Pages/Widgets/CumulativeEmployeeData.php Просмотреть файл

1
+<?php
2
+
3
+namespace App\Filament\Pages\Widgets;
4
+
5
+use App\Models\Company;
6
+use App\Models\Employeeship;
7
+use App\Models\User;
8
+use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;
9
+
10
+class CumulativeEmployeeData extends ApexChartWidget
11
+{
12
+    protected int|string|array $columnSpan = [
13
+        'md' => 2,
14
+        'xl' => 3,
15
+    ];
16
+
17
+    /**
18
+     * Chart Id
19
+     *
20
+     * @var string
21
+     */
22
+    protected static string $chartId = 'cumulative-employee-data';
23
+
24
+    /**
25
+     * Widget Title
26
+     *
27
+     * @var string|null
28
+     */
29
+    protected static ?string $heading = 'Cumulative Employee Data';
30
+
31
+    protected function getOptions(): array
32
+    {
33
+        $startOfYear = today()->startOfYear();
34
+        $today = today();
35
+
36
+        // Company data
37
+        $employeeData = Employeeship::selectRaw("COUNT(*) as aggregate, role, YEARWEEK(created_at, 3) as week")
38
+            ->whereBetween('created_at', [$startOfYear, $today])
39
+            ->groupByRaw('week, role')
40
+            ->get();
41
+
42
+        $weeks = [];
43
+        for ($week = $startOfYear->copy(); $week->lte($today); $week->addWeek()) {
44
+            $weeks[$week->format('oW')] = 0;
45
+        }
46
+
47
+        $weeklyRoleData = collect($weeks)->mapWithKeys(static function ($value, $week) use ($employeeData) {
48
+            $editors = $employeeData->where('role', 'editor')->where('week', $week)->first();
49
+            $admins = $employeeData->where('role', 'admin')->where('week', $week)->first();
50
+
51
+            return [
52
+                $week => [
53
+                    'editors' => $editors ? $editors->aggregate : 0,
54
+                    'admins' => $admins ? $admins->aggregate : 0,
55
+                ]
56
+            ];
57
+        });
58
+
59
+        $cumulativeEditors = $weeklyRoleData->reduce(function ($carry, $value) {
60
+            $carry[] = ($carry ? end($carry) : 0) + $value['editors'];
61
+            return $carry;
62
+        }, []);
63
+
64
+        $cumulativeAdmins = $weeklyRoleData->reduce(function ($carry, $value) {
65
+            $carry[] = ($carry ? end($carry) : 0) + $value['admins'];
66
+            return $carry;
67
+        }, []);
68
+
69
+        $totalEmployees = [];
70
+        for ($i = 0; $i < count($cumulativeEditors); $i++) {
71
+            $totalEmployees[] = $cumulativeEditors[$i] + $cumulativeAdmins[$i];
72
+        }
73
+
74
+        $weeklyGrowthRate = [0];
75
+        for ($i = 1; $i < count($totalEmployees); $i++) {
76
+            $growth = (($totalEmployees[$i] - $totalEmployees[$i - 1]) / $totalEmployees[$i - 1]) * 100;
77
+            $weeklyGrowthRate[] = round($growth, 2);
78
+        }
79
+
80
+        $labels = collect($weeks)->keys()->map(static function ($week) {
81
+            $year = substr($week, 0, 4);
82
+            $weekNumber = substr($week, 4);
83
+
84
+            return today()->setISODate($year, $weekNumber)->format('M d');
85
+        });
86
+
87
+
88
+        return [
89
+            'chart' => [
90
+                'type' => 'line',
91
+                'height' => 350,
92
+                'stacked' => true,
93
+                'toolbar' => [
94
+                    'show' => false,
95
+                ],
96
+            ],
97
+            'series' => [
98
+                [
99
+                    'name' => 'Editors',
100
+                    'type' => 'bar',
101
+                    'data' => $cumulativeEditors,
102
+                ],
103
+                [
104
+                    'name' => 'Admins',
105
+                    'type' => 'bar',
106
+                    'data' => $cumulativeAdmins,
107
+                ],
108
+                [
109
+                    'name' => 'Weekly Growth Rate',
110
+                    'type' => 'area',
111
+                    'data' => $weeklyGrowthRate,
112
+                ],
113
+            ],
114
+            'stroke' => [
115
+                'width' => [0, 0, 2],
116
+                'curve' => 'smooth',
117
+            ],
118
+            'xaxis' => [
119
+                'categories' => $labels,
120
+                'position' => 'bottom',
121
+                'labels' => [
122
+                    'style' => [
123
+                        'colors' => '#9ca3af',
124
+                        'fontWeight' => 600,
125
+                    ],
126
+                ],
127
+            ],
128
+            'yaxis' => [
129
+                'labels' => [
130
+                    'style' => [
131
+                        'colors' => '#9ca3af',
132
+                        'fontWeight' => 600,
133
+                    ],
134
+                ],
135
+            ],
136
+            'legend' => [
137
+                'labels' => [
138
+                    'colors' => '#9ca3af',
139
+                    'fontWeight' => 600,
140
+                ],
141
+            ],
142
+            'colors' => ['#d946ef', '#6d28d9', '#3b82f6'],
143
+            'fill' => [
144
+                'type' => 'gradient',
145
+                'gradient' => [
146
+                    'shade' => 'dark',
147
+                    'type' => 'vertical',
148
+                    'shadeIntensity' => 0.2,
149
+                    'gradientToColors' => ['#ec4899', '#8b5cf6', '#0ea5e9'],
150
+                    'inverseColors' => true,
151
+                    'opacityFrom' => [0.85, 0.85, 0.85],
152
+                    'opacityTo' => [0.85, 0.85, 0.4],
153
+                    'stops' => [0, 100, 100],
154
+                ],
155
+            ],
156
+            'plotOptions' => [
157
+                'bar' => [
158
+                    'horizontal' => false,
159
+                    'borderRadius' => 5,
160
+                    'borderRadiusApplication' => 'end',
161
+                    'columnWidth' => '60%',
162
+                    'dataLabels' => [
163
+                        'total' => [
164
+                            'enabled' => true,
165
+                            'style' => [
166
+                                'color' => '#9ca3af',
167
+                                'fontSize' => '14px',
168
+                                'fontWeight' => 600,
169
+                            ],
170
+                        ]
171
+                    ],
172
+                ],
173
+            ],
174
+            'dataLabels' => [
175
+                'enabled' => false,
176
+            ],
177
+        ];
178
+    }
179
+}

+ 182
- 0
app/Filament/Pages/Widgets/CumulativeUserData.php Просмотреть файл

1
+<?php
2
+
3
+namespace App\Filament\Pages\Widgets;
4
+
5
+use App\Models\Company;
6
+use App\Models\User;
7
+use Leandrocfe\FilamentApexCharts\Widgets\ApexChartWidget;
8
+
9
+class CumulativeUserData extends ApexChartWidget
10
+{
11
+    protected int|string|array $columnSpan = [
12
+        'md' => 2,
13
+        'xl' => 3,
14
+    ];
15
+
16
+    /**
17
+     * Chart Id
18
+     *
19
+     * @var string
20
+     */
21
+    protected static string $chartId = 'cumulative-user-data';
22
+
23
+    /**
24
+     * Widget Title
25
+     *
26
+     * @var string|null
27
+     */
28
+    protected static ?string $heading = 'Cumulative User Data';
29
+
30
+    protected function getOptions(): array
31
+    {
32
+        $startOfYear = today()->startOfYear();
33
+        $today = today();
34
+
35
+        // Company data
36
+        $userData = User::selectRaw("COUNT(*) as aggregate, YEARWEEK(created_at, 3) as week")
37
+            ->whereBetween('created_at', [$startOfYear, $today])
38
+            ->groupByRaw('week')
39
+            ->get();
40
+
41
+        $weeks = [];
42
+        for ($week = $startOfYear->copy(); $week->lte($today); $week->addWeek()) {
43
+            $weeks[$week->format('oW')] = 0;
44
+        }
45
+
46
+        $weeklyData = collect($weeks)->mapWithKeys(static function ($value, $week) use ($userData) {
47
+            $matchingData = $userData->firstWhere('week', $week);
48
+            return [$week => $matchingData ? $matchingData->aggregate : 0];
49
+        });
50
+
51
+        $totalUsers = $weeklyData->reduce(static function ($carry, $value) {
52
+            $carry[] = ($carry ? end($carry) : 0) + $value;
53
+            return $carry;
54
+        }, []);
55
+
56
+        // Calculate percentage increase and increase in companies per week
57
+        $newUsers = [0];
58
+        $weeklyGrowthRate = [0];
59
+
60
+        $cumulativeDataLength = count($totalUsers);
61
+        for ($key = 1; $key < $cumulativeDataLength; $key++) {
62
+            $value = $totalUsers[$key];
63
+            $previousWeekValue = $totalUsers[$key - 1];
64
+            $newUsers[] = $value - $previousWeekValue;
65
+            $weeklyGrowthRate[] = round((($value - $previousWeekValue) / $previousWeekValue) * 100, 2);
66
+        }
67
+
68
+        $labels = collect($weeks)->keys()->map(static function ($week) {
69
+            $year = substr($week, 0, 4);
70
+            $weekNumber = substr($week, 4);
71
+
72
+            return today()->setISODate($year, $weekNumber)->format('M d');
73
+        });
74
+
75
+        return [
76
+            'chart' => [
77
+                'type' => 'line',
78
+                'height' => 350,
79
+                'stacked' => false,
80
+                'toolbar' => [
81
+                    'show' => false,
82
+                ],
83
+            ],
84
+            'series' => [
85
+                [
86
+                    'name' => 'Weekly Growth Rate',
87
+                    'type' => 'area',
88
+                    'data' => $weeklyGrowthRate,
89
+                ],
90
+                [
91
+                    'name' => 'New Users',
92
+                    'type' => 'line',
93
+                    'data' => $newUsers,
94
+                ],
95
+                [
96
+                    'name' => 'Total Users',
97
+                    'type' => 'column',
98
+                    'data' => $totalUsers,
99
+                ],
100
+            ],
101
+            'xaxis' => [
102
+                'categories' => $labels,
103
+                'position' => 'bottom',
104
+                'labels' => [
105
+                    'style' => [
106
+                        'colors' => '#9ca3af',
107
+                        'fontWeight' => 600,
108
+                    ],
109
+                ],
110
+            ],
111
+            'yaxis' => [
112
+                [
113
+                    'seriesName' => 'Weekly Growth Rate',
114
+                    'labels' => [
115
+                        'style' => [
116
+                            'colors' => '#9ca3af',
117
+                            'fontWeight' => 600,
118
+                        ],
119
+                    ],
120
+                ],
121
+                [
122
+                    'seriesName' => 'New Users',
123
+                    'decimalsInFloat' => 0,
124
+                    'opposite' => true,
125
+                    'labels' => [
126
+                        'style' => [
127
+                            'colors' => '#9ca3af',
128
+                            'fontWeight' => 600,
129
+                        ],
130
+                    ],
131
+                ],
132
+                [
133
+                    'seriesName' => 'Total Users',
134
+                    'decimalsInFloat' => 0,
135
+                    'opposite' => true,
136
+                    'labels' => [
137
+                        'style' => [
138
+                            'colors' => '#9ca3af',
139
+                            'fontWeight' => 600,
140
+                        ],
141
+                    ],
142
+                ],
143
+            ],
144
+            'legend' => [
145
+                'position' => 'top',
146
+                'horizontalAlign' => 'center',
147
+                'labels' => [
148
+                    'colors' => '#9ca3af',
149
+                    'fontWeight' => 600,
150
+                ],
151
+            ],
152
+            'markers' => [
153
+                'size' => 0,
154
+            ],
155
+            'colors' => ['#6d28d9', '#3b82f6', '#d946ef'],
156
+            'fill' => [
157
+                'type' => 'gradient',
158
+                'gradient' => [
159
+                    'shade' => 'dark',
160
+                    'type' => 'vertical',
161
+                    'shadeIntensity' => 0.5,
162
+                    'gradientToColors' => ['#6d28d9', '#0ea5e9', '#d946ef'],
163
+                    'inverseColors' => false,
164
+                    'opacityFrom' => [0.85, 1, 0.75],
165
+                    'opacityTo' => [0.4, 0.85, 1],
166
+                    'stops' => [0, 20, 80, 100],
167
+                ],
168
+            ],
169
+            'stroke' => [
170
+                'width' => [2, 5, 0],
171
+                'curve' => 'smooth',
172
+            ],
173
+            'plotOptions' => [
174
+                'bar' => [
175
+                    'borderRadius' => 5,
176
+                    'borderRadiusApplication' => 'end',
177
+                    'columnWidth' => '60%',
178
+                ],
179
+            ],
180
+        ];
181
+    }
182
+}

+ 7
- 6
composer.lock Просмотреть файл

8379
         },
8379
         },
8380
         {
8380
         {
8381
             "name": "phpunit/php-file-iterator",
8381
             "name": "phpunit/php-file-iterator",
8382
-            "version": "4.0.1",
8382
+            "version": "4.0.2",
8383
             "source": {
8383
             "source": {
8384
                 "type": "git",
8384
                 "type": "git",
8385
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
8385
                 "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
8386
-                "reference": "fd9329ab3368f59fe1fe808a189c51086bd4b6bd"
8386
+                "reference": "5647d65443818959172645e7ed999217360654b6"
8387
             },
8387
             },
8388
             "dist": {
8388
             "dist": {
8389
                 "type": "zip",
8389
                 "type": "zip",
8390
-                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/fd9329ab3368f59fe1fe808a189c51086bd4b6bd",
8391
-                "reference": "fd9329ab3368f59fe1fe808a189c51086bd4b6bd",
8390
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/5647d65443818959172645e7ed999217360654b6",
8391
+                "reference": "5647d65443818959172645e7ed999217360654b6",
8392
                 "shasum": ""
8392
                 "shasum": ""
8393
             },
8393
             },
8394
             "require": {
8394
             "require": {
8427
             ],
8427
             ],
8428
             "support": {
8428
             "support": {
8429
                 "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
8429
                 "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
8430
-                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.0.1"
8430
+                "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy",
8431
+                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.0.2"
8431
             },
8432
             },
8432
             "funding": [
8433
             "funding": [
8433
                 {
8434
                 {
8435
                     "type": "github"
8436
                     "type": "github"
8436
                 }
8437
                 }
8437
             ],
8438
             ],
8438
-            "time": "2023-02-10T16:53:14+00:00"
8439
+            "time": "2023-05-07T09:13:23+00:00"
8439
         },
8440
         },
8440
         {
8441
         {
8441
             "name": "phpunit/php-invoker",
8442
             "name": "phpunit/php-invoker",

Загрузка…
Отмена
Сохранить