NxTIC/build/api/module/chart.php

832 lines
20 KiB
PHP

<?php
namespace api\module;
use \manager\sessionManager;
use \manager\ManagerError;
use \lightdb\core\lightdb;
class chart{
/* CHARGE LE CONTENU DU DICTIONNAIRE
*
* @return dictionary<Array> Contenu du dictionnaire, ou FALSE si erreur
*
*/
private static function loadDictionary(){
$dict = file_get_contents(__BUILD__.'/src/dynamic/dictionary.json');
$dict = json_decode( $dict, true );
// Si erreur, on retourne false
if( is_null($dict) )
return false;
return $dict;
}
/* RETOURNE UN JEU DE DONNEES POUR LE SENS DE COMMUNICATION (MANQUE/ENTRANT/SORTANT)
*
*/
public static function direction($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les compteurs
=========================================================*/
$labels = ['ENTRANT', 'SORTANT', 'MANQUÉ'];
$MISSED = 0;
$OUTGOING = 0;
$INCOMING = 0;
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (1) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (2) Si ce n'est pas un appel, on passe au suivant */
if( $log['type'] != 0 )
continue;
/* (3) On incrémente les types */
$MISSED += ($log['direction']==2) ? 1 : 0;
$OUTGOING += ($log['direction']==1) ? 1 : 0;
$INCOMING += ($log['direction']==0) ? 1 : 0;
}
}
/* [4] On construit l'objet
=========================================================*/
return [
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des appels',
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => [[
'colorByPoint' => true,
'data' => [
[ 'name' => 'Entrant', 'y' => $INCOMING ],
[ 'name' => 'Sortant', 'y' => $OUTGOING ],
[ 'name' => 'Manqué', 'y' => $MISSED ],
]
]]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LE TYPE DE COMMUNICATION (APPEL/SMS)
*
*/
public static function type($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les compteurs
=========================================================*/
$PHONE = 0;
$SMS = 0;
/* [2] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (1) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (2) On incrémente les compteurs */
$PHONE += ($log['type']==0) ? 1 : 0;
$SMS += ($log['type']==1) ? 1 : 0;
}
}
return [
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des types de communication',
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => [[
'colorByPoint' => true,
'data' => [
[ 'name' => 'Appels', 'y' => $PHONE ],
[ 'name' => 'SMS', 'y' => $SMS ]
]
]]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LE SEXE DES COMMUNICATIONS (HOMME/FEMME)
*
*/
public static function sexe($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les compteurs
=========================================================*/
$H = 0;
$F = 0;
$I = 0;
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (1) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (2) On récupère le contact associé */
$associatedContact = null;
foreach($data['contacts'] as $contact)
if( $log['id'] == $contact['id'] )
$associatedContact = $contact;
// Si on ne trouve pas, on passe au suivant
if( is_null($associatedContact) )
continue;
/* (3) On incrémente les compteurs */
$H += ($associatedContact['sexe']==0) ? 1 : 0;
$F += ($associatedContact['sexe']==1) ? 1 : 0;
$I += ($associatedContact['sexe']==2) ? 1 : 0;
}
}
return [
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des genres',
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => [[
'colorByPoint' => true,
'data' => [
[ 'name' => 'Homme', 'y' => $H ],
[ 'name' => 'Femme', 'y' => $F ],
[ 'name' => 'Indéterminé', 'y' => $I ]
]
]]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LES AGES DES COMMUNICATIONS
*
*/
public static function ages($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* (2) On initialise les compteurs et les labels */
$age_classes = [];
$age_classesByContact = [];
$labels = [];
foreach($dict['contacts']['age'] as $i=>$label){
array_push($labels, $label);
$age_classes[$i] = 0;
$age_classesByContact[$i] = 0;
}
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
$tot = 0;
if( isset($data['logs']) && is_array($data['logs']) ){
/* (2) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (3) On récupère le contact associé */
$associatedContact = null;
foreach($data['contacts'] as $contact)
if( $log['id'] == $contact['id'] )
$associatedContact = $contact;
// Si on ne trouve pas, on passe au suivant
if( is_null($associatedContact) )
continue;
/* (4) On incrémente le compteur de la classe d'age en question */
if( isset($age_classes[ $associatedContact['age'] ]) ){
$age_classes[ $associatedContact['age'] ]++;
$tot++;
}
}
foreach($age_classes as $i=>$class)
$age_classes[$i] = 100 * $class / $tot;
}
/* [4] On récupère les ages pour répartition des CONTACTS
=========================================================*/
/* (1) On incrémente les compteurs */
$tot = 0;
foreach($data['contacts'] as $c=>$contact){
/* (2) On incrémente le compteur de la classe d'age en question */
if( isset($age_classesByContact[ $contact['age'] ]) ){
$age_classesByContact[$contact['age']]++;
$tot++;
}
}
foreach($age_classesByContact as $i=>$class)
$age_classesByContact[$i] = 100 * $class / $tot;
return [
'ModuleError' => ManagerError::Success,
'type' => 'column',
'xlabels' => $labels,
'title' => 'Répartition des ages',
'zoom' => 'x',
'pointFormat' => '{series.name}: <b>{point.y:.1f}%</b>',
'ytitle' => "apparitition (%)",
'series' => [
[
'name' => 'communications',
'data' => array_values($age_classes)
],
[
'name' => 'contacts',
'data' => array_values($age_classesByContact)
]
]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LES TYPES DE RELATION DES COMMUNICATIONS
*
*/
public static function relations($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* (2) On initialise les compteurs et labels */
$relations = []; // relations en fonction du log
$relationsByContact = []; // relations en fonction de la répartition des contacts
$labels = [];
foreach($dict['contacts']['reltype'] as $i=>$label){
array_push($labels, $label);
$relations[$i] = 0;
$relationsByContact[$i] = 0;
}
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (2) On incrémente les compteurs */
$tot = 0;
foreach($data['logs'] as $log){
/* (3) On récupère le contact associé */
$associatedContact = null;
foreach($data['contacts'] as $contact)
if( $log['id'] == $contact['id'] )
$associatedContact = $contact;
// Si on ne trouve pas, on passe au suivant
if( is_null($associatedContact) )
continue;
/* (4) On incrémente le compteur de la classe d'age en question */
if( isset($relations[ $associatedContact['reltype'] ]) ){
$relations[ $associatedContact['reltype'] ]++;
$tot++;
}
}
foreach($relations as $r=>$rel)
$relations[$r] = 100 * $relations[$r] / $tot;
}
/* [4] On récupère les données par CONTACT
=========================================================*/
/* (1) On incrémente les compteurs */
$tot = 0;
foreach($data['contacts'] as $contact){
/* (2) On incrémente le compteur de la classe d'age en question */
if( isset($relationsByContact[ $contact['reltype'] ]) ){
$relationsByContact[ $contact['reltype'] ]++;
$tot++;
}
}
foreach($relationsByContact as $r=>$rel)
$relationsByContact[$r] = 100 * $relationsByContact[$r] / $tot;
return [
'ModuleError' => ManagerError::Success,
'type' => 'bar',
'title' => 'Répartition des relations',
'xlabels' => $labels,
'ytitle' => "apparitition (%)",
'pointFormat' => '{series.name}: <b>{point.y:.1f}%</b>',
'series' => [
[ // En fonction du log
'name' => 'communications',
'data' => $relations
],
[ // contacts
'name' => 'contacts',
'data' => $relationsByContact
]
]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LES JOURS DE LA SEMAINE DES COMMUNICATIONS
*
*/
public static function weekdays($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* (2) On initialise les compteurs et labels */
$weekdays = [ // jours de la semaine en fonction du log
'phone' => [], // pour les appels
'sms' => [] // pour les sms
];
$labels = ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche'];
for( $i = 0 ; $i < 7 ; $i++ ){
$weekdays['phone'][$i] = 0;
$weekdays['sms'][$i] = 0;
}
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (2) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (3) On récupére le jour de la semaine */
$weekday = date('N', $log['date']) - 1;
/* (4) On incrémente le compteur de la classe d'age en question */
$weekdays['phone'][ $weekday ] += ($log['type']==0) ? 1 : 0;
$weekdays['sms'][ $weekday ] += ($log['type']==1) ? 1 : 0;
}
}
return [
'ModuleError' => ManagerError::Success,
'type' => 'column',
'title' => 'Répartition dans la semaine',
'xlabels' => $labels,
'ytitle' => "apparititions",
'pointFormat' => '{series.name}: {point.y}<br/>Total: {point.stackTotal}',
'series' => [
[ // En fonction des appels
'name' => 'appels',
'data' => $weekdays['phone']
],
[ // En fonction des sms
'name' => 'sms',
'data' => $weekdays['sms']
]
]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LES HEURES DE COMMUNICATIONS
*
*/
public static function timeofday($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* (2) On initialise les compteurs et labels et compteurs*/
$labels = []; // labels des heures
$times = []; // heure en fonction du log
for( $h = 0 ; $h < 24 ; $h++ ){
array_push($labels, $h.'h00');
$times[ $h*60 ] = 0; // xx H 00
array_push($labels, $h.'h30');
$times[ $h*60+30 ] = 0; // xx H 30
}
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (2) On incrémente les compteurs */
foreach($data['logs'] as $log){
/* (3) On récupére le jour de la semaine */
$timeofday = (int) strtotime( date('1970-01-01 H:i:s', $log['date']) );
$timearray = getdate($log['date']);
$timeofday = $timearray['hours']*60 + 30*round($timearray['minutes']/30);
/* (4) On incrémente le compteur de la classe d'age en question */
if( isset($times[$timeofday]))
$times[ $timeofday ]++;
}
}
return [
'ModuleError' => ManagerError::Success,
'type' => 'column',
'title' => 'Répartition dans la journée',
'xlabels' => $labels,
'zoom' => 'x',
'series' => [
[ // En fonction des appels
'name' => 'communications',
'data' => array_values($times)
]
]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LES DUREES DE COMMUNICATIONS
*
*/
public static function duration($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return [ 'ModuleError' => ManagerError::ParsingFailed ];
/* (2) On initialise les compteurs et labels et compteurs*/
$times = []; // heure en fonction du log
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
if( isset($data['logs']) && is_array($data['logs']) ){
/* (2) On incrémente les compteurs */
foreach($data['logs'] as $log){ if( $log['type'] == 0 ){ // Pour chaque appel
/* (3) On récupére la durée de la communication */
$duration = $log['duration'];
// On arondit à 1 min
$duration = 30 * round($duration/60);
/* (4) On incrémente le compteur de la classe d'age en question */
if( !isset($times[$duration]) )
$times[$duration] = 0;
$times[ $duration ]++;
}}
}
/* [4] On formatte les données
=========================================================*/
$formattedData = [];
$sortedData = [];
// 1. Mise au bon format
foreach($times as $duration=>$count){
array_push($formattedData, [ $duration, $count ]);
}
// 2. tri des données
while( count($formattedData) > 0 ){
$min = null;
foreach($formattedData as $d=>$data)
if( $min == null || $data[0] < $formattedData[$min][0] )
$min = $d;
if( $min == null )
break;
array_push($sortedData, $formattedData[$min]);
unset($formattedData[$min]);
}
return [
'ModuleError' => ManagerError::Success,
'type' => 'spline',
'title' => 'Durée des appels',
'xaxis' => [ 'type' => 'datetime', 'labels' => ['format' => '{value:%X}'] ],
'ytitle' => 'appels',
'zoom' => 'x',
'series' => [
[ // En fonction des appels
'name' => 'communications',
'data' => $sortedData
]
]
];
}
/* RETOURNE UN JEU DE DONNEES POUR LE GRAPHIQUE DU RESEAU
*
*/
public static function network($params){
extract($params);
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
/* (1) On récupère les données téléphoniques */
$db = new lightdb('phone_db');
$phone = $db->fetch($subject);
$db->close();
// Si erreur
if( $phone === false )
$phone = [];
/* (2) On récupère les données facebook */
$db = new lightdb('facebook_db');
$facebook = $db->fetch($subject);
$db->close();
// Si erreur
if( $facebook === false )
$facebook = [];
/* (3) Si aucune donnée, erreur */
if( count($phone) + count($facebook) == 0 )
return [ 'ModuleError' => ManagerError::ModuleError ];
/* [2] On récupère les top20 de chaque jeu (les contacts intéressants)
=========================================================*/
$nodes = [];
/* (1) Contacts parmi les données téléphoniques */
if( isset($phone['contacts']) )
foreach($phone['contacts'] as $contact)
if( isset($contact['studies2']) )
array_push( $nodes, [
'id' => $contact['id'],
'label' => $contact['name'],
'type' => 'phone'
] );
/* (2) Contacts parmi les données facebook */
if( isset($facebook['contacts']) )
foreach($facebook['contacts'] as $contact)
if( isset($contact['studies2']) )
array_push( $nodes, [
'id' => $contact['id'],
'label' => $contact['name'],
'type' => 'facebook'
] );
/* [3] On récupère toutes les relations
=========================================================*/
$edges = [];
/* (1) Parmi les relations des données téléphoniques */
if( isset($phone['relations']) )
foreach($phone['relations'] as $relation)
array_push($edges, [$relation['idA'], $relation['idB']] );
/* (2) Parmi les relations des données facebook */
if( isset($facebook['relations']) )
foreach($facebook['relations'] as $relation)
array_push($edges, [$relation['idA'], $relation['idB']] );
return [
'ModuleError' => ManagerError::Success,
'nodes' => $nodes,
'edges' => $edges
];
}
}
?>