NxTIC/manager/module/chart.php

834 lines
21 KiB
PHP
Raw Permalink Normal View History

<?php
namespace manager\module;
use \manager\sessionManager;
use \manager\ManagerError;
2016-05-24 07:01:16 +00:00
use \manager\lightdb;
2016-05-24 07:01:16 +00:00
class chart{
2016-05-24 07:01:16 +00:00
/* CHARGE LE CONTENU DU DICTIONNAIRE
*
* @return dictionary<Array> Contenu du dictionnaire, ou FALSE si erreur
*
*/
private static function loadDictionary(){
$dict = file_get_contents(__ROOT__.'/src/dynamic/dictionary.json');
2016-05-24 07:01:16 +00:00
$dict = json_decode( $dict, true );
2016-05-24 07:01:16 +00:00
// 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)
*
2016-05-24 07:01:16 +00:00
*/
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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les compteurs
=========================================================*/
$labels = array('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;
}
}
2016-05-24 16:59:19 +00:00
/* [4] On construit l'objet
2016-05-24 07:01:16 +00:00
=========================================================*/
return array(
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des appels',
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => array(array(
'colorByPoint' => true,
'data' => array(
array( 'name' => 'Entrant', 'y' => $INCOMING ),
array( 'name' => 'Sortant', 'y' => $OUTGOING ),
array( 'name' => 'Manqué', 'y' => $MISSED ),
)
))
2016-05-24 07:01:16 +00:00
);
}
/* RETOURNE UN JEU DE DONNEES POUR LE TYPE DE COMMUNICATION (APPEL/SMS)
*
2016-05-24 07:01:16 +00:00
*/
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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( '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 array(
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des types de communication',
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => array(array(
'colorByPoint' => true,
'data' => array(
array( 'name' => 'Appels', 'y' => $PHONE ),
array( 'name' => 'SMS', 'y' => $SMS )
)
2016-05-24 07:01:16 +00:00
))
);
}
/* 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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les compteurs
=========================================================*/
$H = 0;
$F = 0;
$I = 0;
2016-05-24 07:01:16 +00:00
/* [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;
2016-05-24 07:01:16 +00:00
}
}
return array(
'ModuleError' => ManagerError::Success,
'type' => 'pie',
'title' => 'Répartition des genres',
2016-05-24 16:59:19 +00:00
'pointFormat' => '{series.name}: <b>{point.percentage:.1f}%</b>',
'series' => array(array(
2016-05-24 16:59:19 +00:00
'colorByPoint' => true,
'data' => array(
array( 'name' => 'Homme', 'y' => $H ),
array( 'name' => 'Femme', 'y' => $F ),
array( 'name' => 'Indéterminé', 'y' => $I )
2016-05-24 16:59:19 +00:00
)
2016-05-24 07:01:16 +00:00
))
);
}
/* RETOURNE UN JEU DE DONNEES POUR LES AGES DES COMMUNICATIONS
*
*/
2016-05-24 07:01:16 +00:00
public static function ages($params){
extract($params);
2016-05-24 07:01:16 +00:00
$subject = intval($subject);
/* [1] On récupère les données de ce sujet
=========================================================*/
$db = new lightdb('phone_db', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return array( 'ModuleError' => ManagerError::ParsingFailed );
/* (2) On initialise les compteurs et les labels */
2016-05-24 16:59:19 +00:00
$age_classes = array();
$age_classesByContact = array();
2016-05-24 07:01:16 +00:00
$labels = array();
foreach($dict['contacts']['age'] as $i=>$label){
array_push($labels, $label);
$age_classes[$i] = 0;
2016-05-24 16:59:19 +00:00
$age_classesByContact[$i] = 0;
2016-05-24 07:01:16 +00:00
}
/* [3] S'il a un journal d'appel, on renvoie les données
=========================================================*/
2016-05-24 16:59:19 +00:00
$tot = 0;
2016-05-24 07:01:16 +00:00
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 */
2016-05-24 16:59:19 +00:00
if( isset($age_classes[ $associatedContact['age'] ]) ){
2016-05-24 07:01:16 +00:00
$age_classes[ $associatedContact['age'] ]++;
2016-05-24 16:59:19 +00:00
$tot++;
}
2016-05-24 07:01:16 +00:00
}
2016-05-24 16:59:19 +00:00
foreach($age_classes as $i=>$class)
$age_classes[$i] = 100 * $class / $tot;
2016-05-24 07:01:16 +00:00
}
2016-05-24 16:59:19 +00:00
/* [4] On récupère les ages pour répartition des CONTACTS
2016-05-24 07:01:16 +00:00
=========================================================*/
2016-05-24 16:59:19 +00:00
/* (1) On incrémente les compteurs */
$tot = 0;
foreach($data['contacts'] as $c=>$contact){
2016-05-24 07:01:16 +00:00
2016-05-24 16:59:19 +00:00
/* (2) On incrémente le compteur de la classe d'age en question */
if( isset($age_classesByContact[ $contact['age'] ]) ){
$age_classesByContact[$contact['age']]++;
$tot++;
}
2016-05-24 07:01:16 +00:00
2016-05-24 16:59:19 +00:00
}
2016-05-24 07:01:16 +00:00
2016-05-24 16:59:19 +00:00
foreach($age_classesByContact as $i=>$class)
$age_classesByContact[$i] = 100 * $class / $tot;
2016-05-24 07:01:16 +00:00
return array(
'ModuleError' => ManagerError::Success,
'type' => 'column',
'xlabels' => $labels,
2016-05-24 16:59:19 +00:00
'title' => 'Répartition des ages',
2016-05-25 10:39:46 +00:00
'zoom' => 'x',
'pointFormat' => '{series.name}: <b>{point.y:.1f}%</b>',
2016-05-25 15:27:18 +00:00
'ytitle' => "apparitition (%)",
2016-05-24 16:59:19 +00:00
'series' => array(
array(
'name' => 'communications',
2016-05-24 16:59:19 +00:00
'data' => array_values($age_classes)
),
array(
'name' => 'contacts',
2016-05-24 16:59:19 +00:00
'data' => array_values($age_classesByContact)
)
)
2016-05-24 07:01:16 +00:00
);
}
2016-05-24 07:01:16 +00:00
/* 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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return array( 'ModuleError' => ManagerError::ParsingFailed );
/* (2) On initialise les compteurs et labels */
$relations = array(); // relations en fonction du log
$relationsByContact = array(); // relations en fonction de la répartition des contacts
$labels = array();
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;
2016-05-24 07:01:16 +00:00
// Si on ne trouve pas, on passe au suivant
if( is_null($associatedContact) )
continue;
2016-05-24 07:01:16 +00:00
/* (4) On incrémente le compteur de la classe d'age en question */
if( isset($relations[ $associatedContact['reltype'] ]) ){
$relations[ $associatedContact['reltype'] ]++;
$tot++;
}
2016-05-24 07:01:16 +00:00
}
2016-05-24 07:01:16 +00:00
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 array(
'ModuleError' => ManagerError::Success,
'type' => 'bar',
2016-05-24 16:59:19 +00:00
'title' => 'Répartition des relations',
'xlabels' => $labels,
'ytitle' => "apparitition (%)",
'pointFormat' => '{series.name}: <b>{point.y:.1f}%</b>',
2016-05-24 16:59:19 +00:00
'series' => array(
2016-05-24 07:01:16 +00:00
array( // En fonction du log
'name' => 'communications',
2016-05-24 16:59:19 +00:00
'data' => $relations
2016-05-24 07:01:16 +00:00
),
array( // contacts
'name' => 'contacts',
2016-05-24 16:59:19 +00:00
'data' => $relationsByContact
2016-05-24 07:01:16 +00:00
)
)
);
}
/* 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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return array( 'ModuleError' => ManagerError::ParsingFailed );
/* (2) On initialise les compteurs et labels */
$weekdays = array( // jours de la semaine en fonction du log
'phone' => array(), // pour les appels
'sms' => array() // pour les sms
);
$labels = array('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 array(
2016-05-25 15:27:18 +00:00
'ModuleError' => ManagerError::Success,
'type' => 'column',
'title' => 'Répartition dans la semaine',
'xlabels' => $labels,
'ytitle' => "apparititions",
2016-05-25 15:27:18 +00:00
'pointFormat' => '{series.name}: {point.y}<br/>Total: {point.stackTotal}',
'series' => array(
array( // En fonction des appels
'name' => 'appels',
'data' => $weekdays['phone']
),
array( // 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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return array( 'ModuleError' => ManagerError::ParsingFailed );
/* (2) On initialise les compteurs et labels et compteurs*/
$labels = array(); // labels des heures
$times = array(); // 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 array(
'ModuleError' => ManagerError::Success,
'type' => 'column',
'title' => 'Répartition dans la journée',
'xlabels' => $labels,
'zoom' => 'x',
'series' => array(
array( // En fonction des appels
'name' => 'communications',
'data' => array_values($times)
)
)
);
}
2016-05-25 17:03:13 +00:00
/* 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', __ROOT__.'/src/dynamic/');
$data = $db->fetch($subject);
$db->close();
// Si erreur
if( $data === false )
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On initialise les valeurs
=========================================================*/
/* (1) On charge le dictionnaire */
$dict = self::loadDictionary();
if( $dict === false )
return array( 'ModuleError' => ManagerError::ParsingFailed );
/* (2) On initialise les compteurs et labels et compteurs*/
$times = array(); // 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 = array();
$sortedData = array();
// 1. Mise au bon format
foreach($times as $duration=>$count){
array_push($formattedData, array(
$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 array(
'ModuleError' => ManagerError::Success,
'type' => 'spline',
'title' => 'Durée des appels',
'xaxis' => array( 'type' => 'datetime', 'labels' => array('format' => '{value:%X}') ),
'ytitle' => 'appels',
'zoom' => 'x',
'series' => array(
array( // En fonction des appels
'name' => 'communications',
'data' => $sortedData
)
)
);
}
2016-05-25 17:03:13 +00:00
/* 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', __ROOT__.'/src/dynamic/');
$phone = $db->fetch($subject);
$db->close();
// Si erreur
if( $phone === false )
$phone = array();
2016-05-25 17:03:13 +00:00
/* (2) On récupère les données facebook */
$db = new lightdb('facebook_db', __ROOT__.'/src/dynamic/');
$facebook = $db->fetch($subject);
$db->close();
// Si erreur
if( $facebook === false )
$facebook = array();
/* (3) Si aucune donnée, erreur */
if( count($phone) + count($facebook) == 0 )
2016-05-25 17:03:13 +00:00
return array( 'ModuleError' => ManagerError::ModuleError );
/* [2] On récupère les top20 de chaque jeu (les contacts intéressants)
=========================================================*/
$nodes = array();
/* (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, array(
'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, array(
'id' => $contact['id'],
'label' => $contact['name'],
'type' => 'facebook'
) );
/* [3] On récupère toutes les relations
=========================================================*/
$edges = array();
/* (1) Parmi les relations des données téléphoniques */
if( isset($phone['relations']) )
foreach($phone['relations'] as $relation)
array_push($edges, array($relation['idA'], $relation['idB']) );
/* (2) Parmi les relations des données facebook */
if( isset($facebook['relations']) )
foreach($facebook['relations'] as $relation)
array_push($edges, array($relation['idA'], $relation['idB']) );
2016-05-25 17:03:13 +00:00
return array(
'ModuleError' => ManagerError::Success,
'nodes' => $nodes,
'edges' => $edges
);
}
}
?>