1👍
I would suggest creating a table or view calculating the number of users by the end of the day. That way you don’t have to run the same query and calculations every time the chart is loaded.
- Make a command
php artisan make:command GenerateUserCounts
, the command should generate the users count for an input of$date
, by default istoday()
- Schedule command to run by end of the day
$schedule->command('users:log-count')->dailyAt('00:00');
- Run command manually for the days before
- Chartjs-TS how can I use a class variable inside method?
- Chartjs-ChartJS plotting x/y in a line chart
0👍
foreach ($records as $record) {
$date = Carbon::parse($record->created_at)->format('M d');
$prevDate = Carbon::parse($record->created_at)->subDay()->format('M d');
$days[$date] = $days[$date] + ($days[$prevDate] ?? 0);
if($allUsers != 0){
$days[$date] += $record->deleted_at ? -1 : 1;
}
}
- Chartjs-Why is pan (and zoom) not working on my Chart.js graph?
- Chartjs-How to add label for each data from dataset in chartjs 2.9.4?
0👍
From your code, it seems you were trying to achieve something on the lines of:
- Pre-populate an array of days with the count on users on the beginning of the period (there is a bug here);
- Iterate through days adding the count of created users and removing the count of deleted users.
The bug I see is that you started your count at the end of the period instead of the beginning. You should not pre-populate all days with $allUsers
but only the users at the beginning, $usersAtBeginning = User::where('created_at', '<' $startDate)
.
Nonetheless, as I’ve mentioned, your code can be more straightforward (and faster) by making better use of Laravel feature. In this case, Collection’s methods. Your function could look like this:
$startDate = now()->subDays(30)->startOfDay();
$endDate = now()->endOfDay();
/** @var Collection<int, User> */
$users = User::query()
->withTrashed()
->whereBetween('created_at', [$startDate, $endDate])
->get(['created_at', 'deleted_at']);
$totalAtTime = User::query()
->where('created_at', '<', $startDate)
->whereNull('deleted_at')
->count();
$current = $startDate;
while ($current <= $endDate) {
$next = (clone $current)->endOfDay();
$created = $users->whereBetween('created_at', [
$current,
$next,
])
->count();
$deleted = $users->whereBetween('deleted_at', [
$current,
$next,
])
->count();
$totalAtTime += $created - $deleted;
$data[$current->format('M d')] = $totalAtTime;
$current->addDay();
}
Source:stackexchange.com