#14; Graphique de la répartition horaire dans la journée (zoomable)
This commit is contained in:
parent
ee055569f2
commit
d14b0495f6
|
@ -96,7 +96,7 @@
|
|||
$db = new lightdb('facebook_db', __ROOT__.'/src/dynamic/');
|
||||
var_dump( array_keys($db->index()));
|
||||
$db->close();
|
||||
$req = new ModuleRequest('chart/weekdays', array( 'subject' => 273 ));
|
||||
$req = new ModuleRequest('chart/timeofday', array( 'subject' => 273 ));
|
||||
|
||||
$res = $req->dispatch();
|
||||
|
||||
|
|
|
@ -152,6 +152,22 @@
|
|||
"parameters": {
|
||||
"subject": { "description": "Identifiant du sujet à étudier,", "type": "id" }
|
||||
}
|
||||
},
|
||||
|
||||
"duration": {
|
||||
"description": "Renvoie les données pour un graphique sur les temps de communication",
|
||||
"permissions": ["admin"],
|
||||
"parameters": {
|
||||
"subject": { "description": "Identifiant du sujet à étudier,", "type": "id" }
|
||||
}
|
||||
},
|
||||
|
||||
"timeofday": {
|
||||
"description": "Renvoie les données pour un graphique sur les heures de communication",
|
||||
"permissions": ["admin"],
|
||||
"parameters": {
|
||||
"subject": { "description": "Identifiant du sujet à étudier,", "type": "id" }
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -29,41 +29,6 @@
|
|||
return $dict;
|
||||
}
|
||||
|
||||
|
||||
/* MODIFIE LES COULEURS DONNEES
|
||||
*
|
||||
* @colors<Array> Tableau de couleurs au format hsla
|
||||
* @tint<int> Valeur a ajouter à tint
|
||||
* @constract<int> Valeur a ajouter à constract
|
||||
* @lightness<int> Valeur a ajouter à lightness
|
||||
* @opacity<int> Valeur a ajouter à opacity
|
||||
*
|
||||
* @return darken<Array> Copie du tableau d'entrée, mais en plus foncé
|
||||
*
|
||||
*/
|
||||
private static function cFilter($colors, $tint=0, $contrast=0, $lightness=0, $opacity=0){
|
||||
$darken = $colors;
|
||||
|
||||
/* [1] Pour chaque couleur
|
||||
=========================================================*/
|
||||
foreach($colors as $i=>$color){
|
||||
|
||||
/* (1) On vérifie que c'est bien au format hsl(tint, saturation%, lightness%, ) */
|
||||
if( !preg_match('/^hsl\((\d+) ?, ?(\d+)% ?, ?(\d+)%\ ?, ?(\d+?.\d*)\)$/i', $color, $matches) )
|
||||
continue;
|
||||
|
||||
$newTint = intval($matches[1]) + $tint;
|
||||
$newContrast = intval($matches[2]) + $contrast;
|
||||
$newLightness = intval($matches[3]) + $lightness;
|
||||
$newOpacity = floatval($matches[4]) + $opacity;
|
||||
|
||||
$darken[$i] = "hsl($newTint,$newContrast%, $newLightness%, $newOpacity)";
|
||||
}
|
||||
|
||||
return $darken;
|
||||
}
|
||||
|
||||
|
||||
/* RETOURNE UN JEU DE DONNEES POUR LE SENS DE COMMUNICATION (MANQUE/ENTRANT/SORTANT)
|
||||
*
|
||||
*/
|
||||
|
@ -177,14 +142,6 @@
|
|||
}
|
||||
|
||||
|
||||
/* [4] Gestion des couleurs
|
||||
=========================================================*/
|
||||
$colors = array();
|
||||
|
||||
$colors['default'] = array( 'hsla(347,100%,69%,1)', 'hsla(204,82%,57%,1)' );
|
||||
$colors['hover'] = self::cFilter($colors['default'], 0, 0, -2);
|
||||
|
||||
|
||||
return array(
|
||||
'ModuleError' => ManagerError::Success,
|
||||
'title' => 'Répartition des types de communication',
|
||||
|
@ -575,6 +532,90 @@
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* RETOURNE UN JEU DE DONNEES POUR LES TEMPS 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 < 23 ; $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,
|
||||
'xlabels' => $labels,
|
||||
'zoom' => 'x',
|
||||
'title' => 'Répartition dans la journée',
|
||||
'series' => array(
|
||||
array( // En fonction des appels
|
||||
'name' => 'communications',
|
||||
'data' => array_values($times)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var subPhone=$('section[data-sublink="phone"]');subPhone.style.display="flex";subPhone.style.flexWrap="wrap";subPhone.style.justifyContent="space-around";Chart.defaults.global.responsive=!1;Chart.defaults.global.title.display=!1;Chart.defaults.global.tooltips.footerFontSize=0;Chart.defaults.global.onClick=function(a,d){console.log(a);null!=d[0]&&console.log(d[0]._datasetIndex,d[0]._index)};subject=273;
|
||||
var charts="sexe direction type ages relations weekdays".split(" "),types="pie pie pie column bar column".split(" "),canvas=[],instances=[],plotOptions=[{pie:{innerSize:"50%",allowPointSelect:!0,cursor:"pointer",startAngle:-90,endAngle:90,dataLabels:{enabled:!0,distance:-45,format:"<b>{point.name}</b>: {point.percentage:.1f} %",style:{color:"white",textShadow:"0 0 2px black"}}}}];plotOptions[1]=plotOptions[0];plotOptions[2]=plotOptions[0];plotOptions[3]={column:{shadow:!1,borderWidth:0}};
|
||||
plotOptions[5]={column:{shadow:!1,borderWidth:0}};plotOptions[5].column.stacking="normal";plotOptions[4]={bar:{allowPointSelect:!0,cursor:"pointer"}};for(var c in charts)canvas[c]=document.createElement("div"),canvas[c].id=charts[c],canvas[c].style.width=canvas[c].style.height="pie"!=types[c]?"40em":"30em",canvas[c].style.margin="2em",subPhone.appendChild(canvas[c]);
|
||||
for(c=0;c<charts.length;c++){var request={path:"chart/"+charts[c],subject:subject};api.send(request,function(a,d){console.log(api.buffer);var e=d[0];if(0!=a.ModuleError)return!1;var b={chart:{renderTo:canvas[e],type:types[e]},series:a.series,plotOptions:plotOptions[e]};null!=a.xlabels&&(b.xAxis={categories:a.xlabels});null!=a.ylabels&&(b.yAxis={categories:a.ylabels});null!=a.title&&(b.title={text:a.title});null!=a.pointFormat&&(b.tooltip={pointFormat:a.pointFormat});console.log(b);instances[e]=new Highcharts.Chart(b)},
|
||||
null,c)};
|
||||
var charts="sexe direction type ages relations weekdays timeofday".split(" "),types="pie pie pie column bar column column".split(" "),canvas=[],instances=[],plotOptions=[{pie:{innerSize:"50%",allowPointSelect:!0,cursor:"pointer",startAngle:-90,endAngle:90,dataLabels:{enabled:!0,distance:10,format:"<b>{point.name}</b>: {point.percentage:.1f} %",style:{color:"black",textShadow:"0 0 2px white"}}}}];plotOptions[1]=plotOptions[0];plotOptions[2]=plotOptions[0];plotOptions[3]={column:{shadow:!1,borderWidth:0}};
|
||||
plotOptions[5]={column:{shadow:!1,borderWidth:0}};plotOptions[5].column.stacking="normal";plotOptions[4]={bar:{allowPointSelect:!0,cursor:"pointer"}};plotOptions[6]={};for(var c in charts)canvas[c]=document.createElement("div"),canvas[c].id=charts[c],canvas[c].style.width=canvas[c].style.height="pie"!=types[c]?"40em":"30em",canvas[c].style.margin="2em",subPhone.appendChild(canvas[c]);
|
||||
for(c=0;c<charts.length;c++){var request={path:"chart/"+charts[c],subject:subject};api.send(request,function(a,d){console.log(api.buffer);var e=d[0];if(0!=a.ModuleError)return!1;var b={chart:{renderTo:canvas[e],type:types[e]},series:a.series,plotOptions:plotOptions[e],xAxis:{},yAxis:{}};null!=a.xaxis&&(b.xAxis=a.xaxis);null!=a.yaxis&&(b.yAxis=a.yaxis);null!=a.xlabels&&(b.xAxis.categories=a.xlabels);null!=a.ylabels&&(b.yAxis.categories=a.ylabels);null!=a.zoom&&(b.chart.zoomType=a.zoom);null!=a.title&&
|
||||
(b.title={text:a.title});null!=a.pointFormat&&(b.tooltip={pointFormat:a.pointFormat});console.log(b);instances[e]=new Highcharts.Chart(b)},null,c)};
|
||||
|
|
|
@ -22,8 +22,8 @@ Chart.defaults.global.onClick = function(e, c){
|
|||
subject = 273;
|
||||
|
||||
|
||||
var charts = ['sexe','direction', 'type', 'ages', 'relations', 'weekdays'];
|
||||
var types = ['pie', 'pie', 'pie', 'column', 'bar', 'column'];
|
||||
var charts = ['sexe','direction', 'type', 'ages', 'relations', 'weekdays', 'timeofday'];
|
||||
var types = ['pie', 'pie', 'pie', 'column', 'bar', 'column', 'column'];
|
||||
var canvas = []; // Contiendra les canvas
|
||||
var instances = []; // Contiendra les charts
|
||||
|
||||
|
@ -35,9 +35,9 @@ var plotOptions = [ { pie: { // pie
|
|||
endAngle: 90,
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
distance: -45,
|
||||
distance: 10,
|
||||
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
|
||||
style: { color: 'white', textShadow: '0 0 2px black' }
|
||||
style: { color: 'black', textShadow: '0 0 2px white' }
|
||||
}
|
||||
} } ];
|
||||
|
||||
|
@ -52,6 +52,9 @@ plotOptions[5].column.stacking = 'normal';
|
|||
// RELATIONS
|
||||
plotOptions[4] = { bar: { allowPointSelect: true, cursor: 'pointer' } };
|
||||
|
||||
// TIMEOFDAY
|
||||
plotOptions[6] = {};
|
||||
|
||||
|
||||
/* [1] On crée les conteneurs
|
||||
=========================================================*/
|
||||
|
@ -100,23 +103,26 @@ for( var c = 0 ; c < charts.length ; c++ ){
|
|||
var options = {
|
||||
chart: { renderTo: canvas[c], type: types[c] },
|
||||
series: response.series,
|
||||
plotOptions: plotOptions[c]
|
||||
plotOptions: plotOptions[c],
|
||||
xAxis: {}, yAxis: {}
|
||||
};
|
||||
|
||||
// labels
|
||||
if( response.xlabels != null )
|
||||
options.xAxis = { categories: response.xlabels };
|
||||
// types de données
|
||||
if( response.xaxis != null ) options.xAxis = response.xaxis;
|
||||
if( response.yaxis != null ) options.yAxis = response.yaxis;
|
||||
|
||||
if( response.ylabels != null )
|
||||
options.yAxis = { categories: response.ylabels };
|
||||
// labels
|
||||
if( response.xlabels != null ) options.xAxis.categories = response.xlabels;
|
||||
if( response.ylabels != null ) options.yAxis.categories = response.ylabels;
|
||||
|
||||
// zoom
|
||||
if( response.zoom != null ) options.chart.zoomType = response.zoom;
|
||||
|
||||
// titre
|
||||
if( response.title != null )
|
||||
options.title = { text: response.title };
|
||||
if( response.title != null ) options.title = { text: response.title };
|
||||
|
||||
// pointFormat
|
||||
if( response.pointFormat != null )
|
||||
options.tooltip = { pointFormat: response.pointFormat };
|
||||
if( response.pointFormat != null ) options.tooltip = { pointFormat: response.pointFormat };
|
||||
|
||||
console.log(options);
|
||||
/* (2) On crée le graphique */
|
||||
|
|
Loading…
Reference in New Issue