start ? Carbon::parse($request->start) : null; $end = $request->end ? Carbon::parse($request->end) : null; $period = $request->period; if ($request->post()) { $periodInterval = CarbonPeriod::create($start, $end); $chart = $this->getChart($request); } //end if return view('bo.pages.stats', compact('brandModels', 'chart', 'start', 'end')); } /** * Get a chart from ChartJs. * * @param \Illuminate\Http\Request $request * @return object */ private function getChart(Request $request) { $period = $request->period; $periodInterval = $this->getDateInterval($request->start, $request->end, $request->period); foreach ($periodInterval as $date) { $labels[] = $this->getChartLabels($date, $request->period); } if (!$request->brand) { $datasets = $this->getGlobalDatas($periodInterval, Brand::all(), $period); } elseif (!$request->url) { $datasets = $this->getBrandDatas($periodInterval, Brand::find($request->brand), $period); } else { $datasets = $this->getUrlDatas($periodInterval, Url::find($request->url), $period); } if (count(Arr::first($datasets)['data']) > 1) { $type = 'line'; } else { $type = 'bar'; } return app()->chartjs ->name('stats') ->type($type) ->labels($labels) ->datasets($datasets) ->optionsRaw($options ?? "{}"); } /** * Get datas for all brands. * * @param \Carbon\CarbonPeriod $periodInterval * @param \Illuminate\Database\Eloquent\Collection $brandModels * @param string $period * @return array */ private function getGlobalDatas( CarbonPeriod $periodInterval, \Illuminate\Database\Eloquent\Collection $brandModels, string $period = "day" ) { foreach ($brandModels as $brand) { foreach ($periodInterval as $date) { switch ($period) { case 'day': $dailyStats = UrlStats::where('date', $date) ->whereIn('url_id', $brand->urls->pluck('id')) ->get(); break; case 'week': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfWeek()->format('Y-m-d'), $date->endOfWeek()->format('Y-m-d') )->toArray() )->whereIn('url_id', $brand->urls->pluck('id')) ->get(); break; case 'month': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfMonth()->format('Y-m-d'), $date->endOfMonth()->format('Y-m-d') )->toArray() )->whereIn('url_id', $brand->urls->pluck('id')) ->get(); break; } //end switch $data[$brand->id][] = $dailyStats->sum('calls'); } //end foreach $color = $this->getUniqueColor(); $datasets[] = [ 'label' => $brand->name, 'backgroundColor' => $color, 'borderColor' => $color, "pointBorderColor" => $color, "pointBackgroundColor" => $color, 'data' => $data[$brand->id], 'lineTension' => 0.4, ]; } //end foreach return $datasets; } /** * Get a chart for all urls of a given brand. * * @param \Carbon\CarbonPeriod $periodInterval * @param \App\Models\Brand $brand * @param string $period * @return object */ private function getBrandDatas( CarbonPeriod $periodInterval, \App\Models\Brand $brand, string $period = "day" ) { foreach ($brand->urls as $url) { foreach ($periodInterval as $date) { switch ($period) { case 'day': $dailyStats = UrlStats::where('date', $date) ->where('url_id', $url->id) ->get(); break; case 'week': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfWeek()->format('Y-m-d'), $date->endOfWeek()->format('Y-m-d') )->toArray() )->where('url_id', $url->id) ->get(); break; case 'month': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfMonth()->format('Y-m-d'), $date->endOfMonth()->format('Y-m-d') )->toArray() )->where('url_id', $url->id) ->get(); break; } //end switch $data[$url->id][] = $dailyStats->sum('calls'); } //end foreach $color = $this->getUniqueColor(); $datasets[] = [ 'label' => $url->value, 'backgroundColor' => $color, 'borderColor' => $color, "pointBorderColor" => $color, "pointBackgroundColor" => $color, 'data' => $data[$url->id], 'lineTension' => 0.4, ]; } //end foreach return $datasets; } /** * Get a chart for a given url. * * @param \Carbon\CarbonPeriod $periodInterval * @param \App\Models\Url $url * @param string $period * @return object */ private function getUrlDatas( CarbonPeriod $periodInterval, \App\Models\Url $url, string $period = 'day' ) { foreach ($periodInterval as $date) { switch ($period) { case 'day': $dailyStats = UrlStats::where('date', $date) ->where('url_id', $url->id) ->get(); break; case 'week': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfWeek()->format('Y-m-d'), $date->endOfWeek()->format('Y-m-d') )->toArray() )->where('url_id', $url->id) ->get(); break; case 'month': $dailyStats = UrlStats::whereIn( 'date', CarbonPeriod::create( $date->startOfMonth()->format('Y-m-d'), $date->endOfMonth()->format('Y-m-d') )->toArray() )->where('url_id', $url->id) ->get(); break; } //end switch $data[$url->id][] = $dailyStats->sum('calls'); } //end foreach $color = $this->getUniqueColor(); $datasets[] = [ 'label' => $url->value, 'backgroundColor' => $color, 'borderColor' => $color, "pointBorderColor" => $color, "pointBackgroundColor" => $color, 'data' => $data[$url->id], 'lineTension' => 0.4, ]; return $datasets; } /** * Get the CarbonPeriod for the given period. * * @param string $start * @param string $end * @param string $period Can be day|week|month. * @return \Carbon\CarbonPeriod */ private function getDateInterval(string $start, string $end, string $period) { switch ($period) { case 'day': $periodInterval = CarbonPeriod::create($start, $end); break; case 'week': $periodInterval = CarbonPeriod::create( Carbon::parse($start)->startOfWeek(), Carbon::parse($end)->endOfWeek(), '1 week' ); break; case 'month': $periodInterval = CarbonPeriod::create( Carbon::parse($start)->startOfMonth(), Carbon::parse($end)->endOfMonth(), '1 month' ); break; default: $periodInterval = CarbonPeriod::create($start, $end); } //end switch return $periodInterval; } /** * Get labels for charts. * * @param Carbon\Carbon $date * @param string $period Can be day|week|month. * @return string */ private function getChartLabels(Carbon $date, string $period) { $labels = []; if ($period === "day") { $labels = array_merge($labels, [$date->format('d-m-Y')]); } if ($period === "week") { $labels = array_unique(array_merge($labels, [sprintf( 'Du %s au %s', $date->startOfWeek()->format('Y-m-d'), $date->endOfWeek()->format('Y-m-d') )])); } if ($period === "month") { $labels = array_unique(array_merge($labels, [Str::ucfirst($date->monthName)])); } return $labels; } /** * getUniqueColor * * @return string */ private function getUniqueColor() { $color = RandomColor::one(); if (in_array($color, $this->colors)) { return $this->getUniqueColor(); } $this->colors[] = $color; return $color; } }