filters['startDate'] ?? Carbon::now()->subDays(30); $endDate = $this->filters['endDate'] ?? Carbon::now(); $startDate = Carbon::parse($startDate)->startOfDay(); $endDate = Carbon::parse($endDate)->endOfDay(); $query = IssueManagement::query() ->select( DB::raw('DATE(created_at) as date'), 'issue', DB::raw('count(*) as total') ) ->whereBetween('created_at', [$startDate, $endDate]) ->groupBy('date', 'issue') ->orderBy('date') ->get(); $labels = []; $current = clone $startDate; while ($current <= $endDate) { $labels[] = $current->translatedFormat('d M'); $current->addDay(); } $datasets = []; foreach (IssueSentiment::cases() as $sentiment) { $data = []; $current = clone $startDate; while ($current <= $endDate) { $dateStr = $current->toDateString(); $count = $query->where('date', $dateStr) ->where('issue', $sentiment->value) ->first(); $data[] = $count ? $count->total : 0; $current->addDay(); } $datasets[] = [ 'label' => $sentiment->getLabel(), 'data' => $data, 'fill' => 'origin', 'backgroundColor' => $this->getHexColorRGBA($sentiment, 0.2), 'borderColor' => $this->getHexColor($sentiment), 'tension' => 0.4, ]; } return [ 'datasets' => $datasets, 'labels' => $labels, ]; } private function getHexColor(IssueSentiment $sentiment): string { return match ($sentiment) { IssueSentiment::POSITIVE => '#10B981', IssueSentiment::NEGATIVE => '#EF4444', IssueSentiment::NEUTRAL => '#6B7280', IssueSentiment::CRISIS => '#F97316', }; } private function getHexColorRGBA(IssueSentiment $sentiment, float $opacity): string { return match ($sentiment) { IssueSentiment::POSITIVE => "rgba(16, 185, 129, {$opacity})", IssueSentiment::NEGATIVE => "rgba(239, 68, 68, {$opacity})", IssueSentiment::NEUTRAL => "rgba(107, 114, 128, {$opacity})", IssueSentiment::CRISIS => "rgba(249, 115, 22, {$opacity})", }; } protected function getType(): string { return 'line'; } protected function getOptions(): array { return [ 'plugins' => [ 'legend' => [ 'display' => true, ], ], 'scales' => [ 'y' => [ 'beginAtZero' => true, 'ticks' => [ 'stepSize' => 1, ], ], ], ]; } }