getRepository(Project::class)->findOneBySlug($projectSlug); if (!$project) { throw new NotFoundHttpException('Project not found'); } $stats = $taskLifecycleManager->getProjectStats($project); if (!isset($stats[$status])) { throw new NotFoundHttpException('Status not found'); } $stats = $stats[$status]; $response = new StreamedResponse(); $response->headers->set('Content-Type', 'image/svg+xml'); $response->headers->set('Cache-Control', 'public, max-age=300'); $response->setCallback(function () use ($stats): void { $colors = [ 'primary' => '#0d6efd', // $blue; 'secondary' => '#6c757d', // $gray-600; 'success' => '#198754', // $green; 'info' => '#0dcaf0', // $cyan; 'warning' => '#ffc107', // $yellow; 'danger' => '#dc3545', // $red; ]; $xml = new \DOMDocument(); $left = $stats['title']; $leftColor = $colors['secondary']; $right = sprintf(' % 3.0f%%', $stats['percentage']); $rightColor = $colors[$stats['color']]; $charWidth = 7; $fontSize = 11; $totalHeight = 20; $radius = ceil($totalHeight / $charWidth); $verticalMargin = round(($totalHeight - $fontSize) / 2); $horizontalMargin = round($fontSize / 3); $totalWidth = round(strlen($left.$right) * $charWidth + 2 * $horizontalMargin); $middle = floor(strlen($left) * $charWidth); $svg = $xml->createElement('svg'); $svg->setAttributeNS('http://www.w3.org/2000/xmlns/','xmlns', 'http://www.w3.org/2000/svg'); $svg->setAttribute('width', $totalWidth); $svg->setAttribute('height', $totalHeight); $defs = $xml->createElement('defs'); $gradientId = 'a'; $gradient = $xml->createElement('linearGradient'); $gradient->setAttribute('id', $gradientId); $stop = $xml->createElement('stop'); $stop->setAttribute('offset', ($middle * 100 / $totalWidth).'%'); $stop->setAttribute('stop-color', $leftColor); $gradient->appendChild($stop); $stop = $xml->createElement('stop'); $stop->setAttribute('offset', ($middle * 100 / $totalWidth).'%'); $stop->setAttribute('stop-color', $rightColor); $gradient->appendChild($stop); $defs->appendChild($gradient); $svg->appendChild($defs); $rect = $xml->createElement('rect'); $rect->setAttribute('width', $totalWidth); $rect->setAttribute('height', $totalHeight); $rect->setAttribute('rx', $radius); $rect->setAttribute('style', sprintf('fill:url(#%s)', $gradientId)); $svg->appendChild($rect); $fontG = $xml->createElement('g'); $fontG->setAttribute('font-family', implode(',', ['DejaVu Sans', 'Verdana', 'Geneva', 'sans-serif'])); $fontG->setAttribute('font-size', $fontSize); $leftText = $xml->createElement('text', $left); $leftText->setAttribute('x', $horizontalMargin); $leftText->setAttribute('y', $totalHeight - $verticalMargin); $leftText->setAttribute('fill', '#000'); $fontG->appendChild($leftText); $leftText = $xml->createElement('text', $left); $leftText->setAttribute('x', $horizontalMargin); $leftText->setAttribute('y', $totalHeight - $verticalMargin - 1); $leftText->setAttribute('fill', '#fff'); $fontG->appendChild($leftText); $rightText = $xml->createElement('text', $right); $rightText->setAttribute('x', $totalWidth - $horizontalMargin); $rightText->setAttribute('y', $totalHeight - $verticalMargin); $rightText->setAttribute('style', 'text-anchor:end;fill:#000'); $fontG->appendChild($rightText); $rightText = $xml->createElement('text', $right); $rightText->setAttribute('x', $totalWidth - $horizontalMargin); $rightText->setAttribute('y', $totalHeight - $verticalMargin - 1); $rightText->setAttribute('style', 'text-anchor:end;fill:#fff'); $fontG->appendChild($rightText); $svg->appendChild($fontG); $xml->appendChild($svg); echo $xml->saveXML(); }); return $response; } }