Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

CumulativeUserData.php 5.7KB

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