up details theme graph page

This commit is contained in:
Tykayn 2025-08-12 11:39:05 +02:00 committed by tykayn
parent af1233c246
commit b959c695ae
3 changed files with 90 additions and 181 deletions

View file

@ -2,8 +2,8 @@
namespace App\Service;
use App\Entity\Stats;
use App\Entity\CityFollowUp;
use App\Entity\Stats;
use Doctrine\ORM\EntityManagerInterface;
class FollowUpService
@ -38,7 +38,7 @@ class FollowUpService
} elseif ($type === 'police') {
$objects = array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'police') ?? [];
} elseif ($type === 'healthcare') {
$objects = array_filter($elements, function($el) {
$objects = array_filter($elements, function ($el) {
return isset($el['tags']['healthcare'])
|| ($el['tags']['amenity'] ?? null) === 'doctors'
|| ($el['tags']['amenity'] ?? null) === 'pharmacy'
@ -74,7 +74,7 @@ class FollowUpService
$objects = array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'public_bookcase') ?? [];
} elseif ($type === 'playground') {
$objects = array_filter($elements, fn($el) => ($el['tags']['leisure'] ?? null) === 'playground') ?? [];
}elseif ($type === 'restaurant') {
} elseif ($type === 'restaurant') {
$objects = array_filter($elements, fn($el) => ($el['tags']['amenity'] ?? null) === 'restaurant') ?? [];
} else {
$objects = [];
@ -133,8 +133,7 @@ class FollowUpService
$completed[] = $el;
}
}
}
// ... fallback pour les types sans tags attendus
} // ... fallback pour les types sans tags attendus
else {
$completed = [];
$partialCompletions = array_fill(0, count($data['objects']), 0);
@ -377,11 +376,11 @@ class FollowUpService
$now = new \DateTime();
$refDate = clone $now;
$refDate->modify('-7 days');
// Récupérer toutes les mesures pour ce type
$countData = [];
$completionData = [];
foreach ($followups as $fu) {
if ($fu->getName() === $type . '_count') {
$countData[] = [
@ -396,20 +395,20 @@ class FollowUpService
];
}
}
// Trier par date
usort($countData, fn($a, $b) => $a['date'] <=> $b['date']);
usort($completionData, fn($a, $b) => $a['date'] <=> $b['date']);
$countDelta = self::calculateDelta($countData, $refDate);
$completionDelta = self::calculateDelta($completionData, $refDate);
return [
'count' => $countDelta,
'completion' => $completionDelta
];
}
/**
* Calcule le delta pour une série de données
*/
@ -418,9 +417,9 @@ class FollowUpService
if (empty($data)) {
return null;
}
$last = end($data)['value'];
// Chercher la mesure exacte à la date de référence
$exactRef = null;
foreach (array_reverse($data) as $point) {
@ -429,18 +428,18 @@ class FollowUpService
break;
}
}
// Si on a trouvé une mesure exacte, l'utiliser
if ($exactRef !== null) {
return $last - $exactRef;
}
// Sinon, chercher les deux mesures les plus proches pour faire une interpolation
$beforeRef = null;
$afterRef = null;
$beforeDate = null;
$afterDate = null;
// Chercher la mesure juste avant la date de référence
foreach (array_reverse($data) as $point) {
if ($point['date'] < $refDate) {
@ -449,7 +448,7 @@ class FollowUpService
break;
}
}
// Chercher la mesure juste après la date de référence
foreach ($data as $point) {
if ($point['date'] > $refDate) {
@ -458,7 +457,7 @@ class FollowUpService
break;
}
}
// Si on a les deux mesures, faire une interpolation linéaire
if ($beforeRef !== null && $afterRef !== null && $beforeDate !== null && $afterDate !== null) {
$timeDiff = $afterDate->getTimestamp() - $beforeDate->getTimestamp();
@ -467,17 +466,17 @@ class FollowUpService
$interpolatedRef = $beforeRef + ($afterRef - $beforeRef) * $ratio;
return $last - $interpolatedRef;
}
// Si on n'a qu'une mesure avant, l'utiliser
if ($beforeRef !== null) {
return $last - $beforeRef;
}
// Si on n'a qu'une mesure après, l'utiliser
if ($afterRef !== null) {
return $last - $afterRef;
}
// Si aucune mesure n'est disponible, retourner null
return null;
}
@ -501,7 +500,7 @@ class FollowUpService
'police' => ['phone', 'website'],
'healthcare' => ['name', 'contact:phone', 'phone', 'email', 'contact:email'],
'bicycle_parking' => ['capacity', 'covered'],
'advertising_board' => ['operator', 'contact:phone'],
'advertising_board' => ['operator'],
'building' => ['building'],
'rnb' => ['building', 'ref:FR:RNB'],
'email' => ['name', 'phone'],