chg: moved sharing group outside of the distribution progressbar (as it is a special case), distribution range is displayed when clicking on the pb labels and lots of minor improvements.

pull/3214/head
Sami Mokaddem 2018-05-02 13:37:48 +00:00
parent 3a42fbfba9
commit f4e4c7b335
5 changed files with 227 additions and 55 deletions

View File

@ -4366,6 +4366,7 @@ class EventsController extends AppController {
$validTools = array('event');
if (!in_array($type, $validTools)) throw new MethodNotAllowedException('Invalid type.');
$this->loadModel('Server');
$this->loadModel('Organisation');
App::uses('DistributionGraphTool', 'Tools');
$grapher = new DistributionGraphTool();
$data = $this->request->is('post') ? $this->request->data : array();
@ -4376,7 +4377,7 @@ class EventsController extends AppController {
$extended = 0;
}
$grapher->construct($this->Event, $this->Server, $this->Auth->user(), $extended);
$grapher->construct($this->Event, $this->Server, $this->Organisation, $this->Auth->user(), $extended);
$json = $grapher->get_distributions_graph($id);
array_walk_recursive($json, function(&$item, $key){

View File

@ -10,9 +10,10 @@
private $__related_events = array();
private $__related_attributes = array();
public function construct($eventModel, $serverModel, $user, $extended_view=0) {
public function construct($eventModel, $serverModel, $orgModel, $user, $extended_view=0) {
$this->__eventModel = $eventModel;
$this->__serverModel = $serverModel;
$this->__organisationModel = $orgModel;
$this->__user = $user;
$this->__json = array();
$this->__extended_view = $extended_view;
@ -20,10 +21,11 @@
// construct distribution info
$this->__json['distributionInfo'] = array();
$sgs = $this->__eventModel->SharingGroup->fetchAllAuthorised($this->__user, 'name', 1);
$this->__json['allSharingGroup'] = array_values($sgs);
$distributionLevels = $this->__eventModel->distributionLevels;
if (empty($sgs)) unset($distributionLevels[4]);
foreach ($distributionLevels as $key => $value) {
$this->__json['distributionInfo'][$key] = array('key' => $value, 'desc' => $this->__eventModel->distributionDescriptions[$key]['formdesc']);
$this->__json['distributionInfo'][$key] = array('key' => $value, 'desc' => $this->__eventModel->distributionDescriptions[$key]['formdesc'], 'value' => $key);
}
$this->__json['distributionInfo'][5] = ""; // inherit event. Will be deleted afterward
@ -44,18 +46,56 @@
if ($distributionLevel == 4) { // sharing group
$sg_name = $this->__extract_sharing_groups_names($elem['SharingGroup']);
$this->__addAdditionalDistributionInfo($distributionLevel, $sg_name);
} else if ($distributionLevel == 3) { // all
if (empty($this->__json['additionalDistributionInfo'][$distributionLevel])) {
$servers = $this->__serverModel->find('list', array(
'fields' => array('name'),
));
$this->__addAdditionalDistributionInfo($distributionLevel, "This community"); // add current community
$this->__addAdditionalDistributionInfo($distributionLevel, "All other communities"); // add current community
} else {
return false;
}
} else if ($distributionLevel == 2) { // connected
// fetch connected communities
if (empty($this->__json['additionalDistributionInfo'][$distributionLevel])) {
$servers = $this->__serverModel->find('list', array(
'fields' => array('name'),
));
$this->__addAdditionalDistributionInfo($distributionLevel, "This community"); // add current community
foreach ($servers as $server) {
$this->__addAdditionalDistributionInfo($distributionLevel, $server);
}
} else {
return false;
}
} else if ($distributionLevel == 1) { // community
if (empty($this->__json['additionalDistributionInfo'][$distributionLevel])) {
$orgs = $this->__organisationModel->find('list', array(
'fields' => array('name'),
));
$thisOrg = $this->__user['Organisation']['name'];
$this->__addAdditionalDistributionInfo($distributionLevel, $thisOrg); // add current community
foreach ($orgs as $org) {
if ($thisOrg != $org) {
$this->__addAdditionalDistributionInfo($distributionLevel, $org);
}
}
} else {
return false;
}
} else if ($distributionLevel == 0) { // org only
if (empty($this->__json['additionalDistributionInfo'][$distributionLevel])) {
$thisOrg = $this->__user['Organisation']['name'];
$this->__addAdditionalDistributionInfo($distributionLevel, $thisOrg); // add current community
} else {
return false;
}
} else {
return false;
}

View File

@ -12,10 +12,16 @@
<canvas id="distribution_graph_canvas" height="360px"width="400px"></canvas>
</div>
<div id="eventdistri_pb_container">
<div id="eventdistri_pb_background" class="progress useCursorPointer">
<div id="eventdistri_pb_min" class="progress useCursorPointer" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="left" data-container="body" title="<?php echo __('Elements having lower distribution level than the event distribution'); ?>"></div>
<div id="eventdistri_pb" class="progress useCursorPointer" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="top" data-container="body" title="<?php echo __('Event distribution'); ?>"></div>
<div id="eventdistri_pb_invalid" class="progress" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="right" data-container="body" title="<?php echo __('Maximum level of non distributed elements'); ?>"></div>
<div id="eventdistri_pb_background" class="customProgress useCursorPointer">
<div id="eventdistri_pb_min" class="customProgress useCursorPointer animatedPB" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="left" data-container="body" title="<?php echo __('Elements having lower distribution level than the event distribution'); ?>"></div>
<div id="eventdistri_pb" class="customProgress useCursorPointer animatedPB" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="top" data-container="body" title="<?php echo __('Event distribution'); ?>"></div>
<div id="eventdistri_pb_invalid" class="customProgress useCursorPointer animatedPB" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="right" data-container="body" title="<?php echo __('Maximum level of non distributed elements'); ?>"></div>
</div>
</div>
<div id="eventdistri_sg_pb_container">
<span class="sharingGroup_pb_text useCursorPointer badge"><?php echo __("Sharing group"); ?></span>
<div id="eventdistri_sg_pb_background" class="customProgress useCursorPointer">
<div id="eventdistri_sg_pb" class="customProgress useCursorPointer animatedPB" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" data-toggle="tooltip" data-placement="top" data-container="body" title="<?php echo __('Sharing group'); ?>"></div>
</div>
</div>
</div>

View File

@ -18,7 +18,8 @@
}
#eventdistri_pb_container {
margin-top: 40px;
margin-top: 20px;
margin-bottom: 50px;
}
#eventdistri_pb_background {
@ -26,12 +27,28 @@
display: flex;
}
#eventdistri_pb {
.animatedPB {
width: 0%;
transition: width 0.5s;
box-shadow: inset 0px 7px 5px -6px rgba(0, 0, 0, 0.5);
}
#eventdistri_pb_invalid {
width: 0%;
#eventdistri_pb_min {
box-shadow: 2px 2px 3px 1px rgba(0,0,0,0.3);
position: absolute;
height: 14px;
margin-top: 2px;
margin-left: 2px;
}
#eventdistri_sg_pb {
color: white;
text-align: center;
}
.sharingGroup_pb_text {
float: left;
margin-right: 5px;
}
.pbDistributionText {
@ -47,3 +64,20 @@
background: black;
border-radius: 4px;
}
.customProgress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f7f7f7;
background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
background-repeat: repeat-x;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
}

View File

@ -14,7 +14,7 @@ function clickHandlerGraph(evt) {
document.getElementById('attributesFilterField').value = "";
filterAttributes('all', scope_id);
} else {
distribution_id = distribution_chart.data.distribution[firstPoint._index].num;
distribution_id = distribution_chart.data.distribution[firstPoint._index].value;
var value_to_set = String(distribution_id);
value_to_set += distribution_id == event_distribution ? '|' + '5' : '';
document.getElementById('attributesFilterField').value = value_to_set;
@ -27,11 +27,16 @@ function generate_additional_info(info) {
if (info.length == 0) {
return "";
} else {
var to_ret = "\n---------------------------------\n";
var to_ret = "\n\nInvolved:\n";
var sel = document.createElement('select');
sel.classList.add('distributionInfo');
for (var i of info) {
to_ret += i + "\n";
var opt = document.createElement('option');
opt.val = i;
opt.innerHTML = i;
sel.appendChild(opt);
}
return to_ret;
return to_ret += sel.outerHTML;
}
}
@ -51,13 +56,12 @@ function clickHandlerPb(evt) {
}
function fill_distri_for_search(start_distri, end_distri) {
console.log(start_distri, end_distri);
var to_ret = "";
for (var i=start_distri; i<end_distri; i++) {
to_ret += String(get_adjusted_from_pb(i)) + "|";
to_ret += String(i) + "|";
to_ret += i==event_distribution ? "5|" : "";
}
to_ret += String(get_adjusted_from_pb(end_distri));
to_ret += String(end_distri);
to_ret += end_distri==event_distribution ? "|5" : "";
return to_ret;
}
@ -105,10 +109,8 @@ function get_maximum_distribution(array) {
var all = array[3];
var sharing = array[4];
if (all != 0) {
return 4;
} else if (connected != 0) {
return 3;
} else if (sharing != 0) {
} else if (connected != 0) {
return 2;
} else if (community != 0) {
return 1;
@ -124,8 +126,6 @@ function get_minimum_distribution(array, event_dist) {
var all = array[3];
var sharing = array[4];
if (connected != 0 && 3 < event_distribution) {
return 3;
} else if (sharing != 0 && 2 < event_distribution) {
return 2;
} else if (community != 0 && 1 < event_distribution) {
return 1;
@ -154,40 +154,53 @@ function add_level_to_pb(distribution, additionalInfo, maxLevel) {
var pb_container = document.getElementById('eventdistri_pb_container');
var pb = document.getElementById('eventdistri_pb_background');
document.getElementById('eventdistri_graph').style.left = spanOffset_orig + 'px'; // center graph inside the popover
var pbStep = pb.clientWidth / 5.0;
var pbStep = pb.clientWidth / 4.0;
var pb_top = pb.offsetTop;
// we get 2:connected_comm, 3:all_comm, 4:sharing_group
// we want 2:sharing_group, 3:connected_comm, 4:all_comm
distribution = swap_distribution(distribution);
var spanOffset = spanOffset_orig;
distribution = jQuery.extend({}, distribution); // deep clone distribution object
for (var d in distribution) {
d = parseInt(d);
if (d == 4) { // skip sharing group
continue;
}
// text
var span = document.createElement('span');
span.classList.add('useCursorPointer', 'pbDistributionText');
span.classList.add('useCursorPointer', 'pbDistributionText', 'badge');
span.onclick = clickHandlerPbText;
span.style.bottom = d % 2 == 0 ? '59px' : '7px';
span.innerHTML = distribution[d].key;
span.setAttribute('data-distribution', distribution[d].num);
if (maxLevel == d+1) {
span.setAttribute('data-distribution', d);
span.style.whiteSpace = 'pre-wrap';
if (maxLevel == d+1) { // current event distribution
span.style.fontSize = 'larger';
span.style.top = d % 2 == 0 ? pb_top-37+'px' : pb_top+30+'px';
} else {
span.style.opacity = '0.5';
span.style.top = d % 2 == 0 ? pb_top-37+'px' : pb_top+30+'px';
}
pb_container.appendChild(span);
span.style.left = (pbStep*(d+1))+spanOffset-span.clientWidth/2 + 'px';
$(span).tooltip({
if (d == Object.keys(distribution).length-2) { // last one, move a bit to the left. (-2 because sharing is not considered)
span.style.left = (pbStep*(d+1))+spanOffset-span.clientWidth/2-35 + 'px';
} else {
span.style.left = (pbStep*(d+1))+spanOffset-span.clientWidth/2 + 'px';
}
var pop = $(span).popover({
placement: d % 2 == 0 ? 'top' : 'bottom',
title: distribution[d].desc + generate_additional_info(additionalInfo[distribution[d].num]),
template: '<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner" style="white-space: pre-wrap;"></div></div>'
trigger: 'click',
content: distribution[d].desc + generate_additional_info(additionalInfo[d]),
title: distribution[d].key,
container: 'body',
html: true,
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title distributionInfo"></h3><div class="popover-content distributionInfo" style="white-space: pre-wrap"></div></div>'
});
// tick
var span = document.createElement('span');
span.classList.add('pbDistributionTick');
spanOffset += (pbStep*(d+1))+spanOffset > pb_container.clientWidth ? -3 : 0; // avoid the tick width to go further than the pb
span.style.left = (pbStep*(d+1))+spanOffset + 'px';
span.style.bottom = d % 2 == 0 ? '32px' : '25px';
//span.style.bottom = d % 2 == 0 ? '32px' : '25px';
span.style.top = d % 2 == 0 ? pb_top-15+'px' : pb_top+0+'px';
if (maxLevel == d+1) {
span.style.opacity = '0.6';
} else {
@ -198,11 +211,18 @@ function add_level_to_pb(distribution, additionalInfo, maxLevel) {
}
$(document).ready(function() {
$('.distribution_graph').popover({
"title": "<b>Distribution graph</b> [atomic event]",
"html": true,
"content": function() { return $('#distribution_graph_container').html(); },
"template" : '<div class="popover" role="tooltip" style="z-index: 1;"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content" style="padding-left: '+spanOffset_orig+'px; padding-right: '+spanOffset_orig*2+'px;"></div></div>'
var pop = $('.distribution_graph').popover({
title: "<b>Distribution graph</b> [atomic event]",
html: true,
content: function() { return $('#distribution_graph_container').html(); },
template : '<div class="popover" role="tooltip" style="z-index: 1;"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content" style="padding-left: '+spanOffset_orig+'px; padding-right: '+spanOffset_orig*2+'px;"></div></div>'
});
$('body').on('mouseup', function(e) {
if(!$(e.target).hasClass('distributionInfo') && !($(e.target).hasClass('pbDistributionText') || $(e.target).hasClass('sharingGroup_pb_text'))) {
$('.pbDistributionText').popover('hide');
$('.sharingGroup_pb_text').popover('hide');
}
});
$('.distribution_graph').click(function() {
@ -224,6 +244,8 @@ $(document).ready(function() {
},
success: function( data, textStatus, jQxhr ){
$(".loadingPopover").hide();
// DISTRIBUTION PROGRESSBAR
$('#eventdistri_pb_invalid').tooltip();
$('#eventdistri_pb').tooltip();
$('#eventdistri_pb_min').tooltip();
@ -231,34 +253,99 @@ $(document).ready(function() {
$('#eventdistri_pb_invalid').click(function(evt) { clickHandlerPb(evt); });
$('#eventdistri_pb').click(function(evt) { clickHandlerPb(evt); });
$('#eventdistri_pb_min').click(function(evt) { clickHandlerPb(evt); });
$('#eventdistri_sg_pb').click(function(evt) { clickHandlerPb(evt); });
// pb
var event_dist = get_adjusted_from_true_distri(event_distribution)+1; // +1 to reach the first level
var event_dist = event_distribution+1; // +1 to reach the first level
var min_distri = get_minimum_distribution(data.event, event_dist)+1; // +1 to reach the first level
var max_distri = get_maximum_distribution(data.event)+1; // +1 to reach the first level
console.log(min_distri, event_dist, max_distri);
add_level_to_pb(data.distributionInfo, data.additionalDistributionInfo, event_dist);
$('#eventdistri_pb_min').width(min_distri*20+'%');
var bg_width_step = $('#eventdistri_pb_background').width()/4.0;
$('#eventdistri_pb_min').width(bg_width_step*min_distri + 'px');
$('#eventdistri_pb_min').data("distribution", fill_distri_for_search(0, min_distri-1));
$('#eventdistri_pb_min').attr('aria-valuenow', min_distri*20);
$('#eventdistri_pb_min').css("transition", "width 0.5s");
$('#eventdistri_pb_min').attr('aria-valuenow', min_distri*25);
$('#eventdistri_pb_min').css("background", "#ffc107");
$('#eventdistri_pb').width((event_dist-Math.max(0, min_distri))*20+'%');
$('#eventdistri_pb').width((event_dist)*25+'%');
$('#eventdistri_pb').data("distribution", fill_distri_for_search(0, event_dist-1));
$('#eventdistri_pb').attr('aria-valuenow', (event_dist-min_distri)*20);
$('#eventdistri_pb').css("transition", "width 0.5s");
$('#eventdistri_pb').attr('aria-valuenow', (event_dist-min_distri)*25);
$('#eventdistri_pb').css("background", "#28a745");
$('#eventdistri_pb_invalid').width((max_distri-event_dist)*20+'%');
$('#eventdistri_pb_invalid').width((max_distri-event_dist)*25+'%');
$('#eventdistri_pb_invalid').data("distribution", fill_distri_for_search(event_dist, max_distri-1));
$('#eventdistri_pb_invalid').attr('aria-valuenow', (max_distri-event_dist)*20);
$('#eventdistri_pb_invalid').css("transition", "width 0.5s");
$('#eventdistri_pb_invalid').attr('aria-valuenow', (max_distri-event_dist)*25);
$('#eventdistri_pb_invalid').css("background", "#dc3545");
// radar
// SHARING GROUPS
var sgNum = data.event[4];
var sgPerc = (sgNum/data.allSharingGroup.length)*100;
if (sgPerc > 0) {
$('#eventdistri_sg_pb').width(sgPerc+'%');
$('#eventdistri_sg_pb').text(sgNum +' / '+ data.allSharingGroup.length);
$('#eventdistri_sg_pb').data("distribution", '4');
$('#eventdistri_sg_pb').attr('aria-valuenow', sgPerc);
$('#eventdistri_sg_pb').css("background", "#7a86e0");
} else { // no sg, hide it and display
$('#eventdistri_sg_pb_background').text("Event not distributed to any sharing group");
}
$('.sharingGroup_pb_text').popover({
placement: 'bottom',
trigger: 'click',
title: 'Sharing group',
content: data.distributionInfo[4].desc + generate_additional_info(data.additionalDistributionInfo[4]),
container: 'body',
html: true,
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title distributionInfo"></h3><div class="popover-content distributionInfo" style="white-space: pre-wrap"></div></div>'
});
// RADAR
var ctx = document.getElementById("distribution_graph_canvas");
ctx.onclick = function(evt) { clickHandlerGraph(evt); };
//distribution_chart = new Chart(ctx, {
// type: 'bar',
// data: {
// labels: data.distributionInfo.map(function(elem, index) { return [elem.key]; }),
// distribution: data.distributionInfo,
// datasets: [
// {
// label: "Attributes",
// data: data.attribute,
// backgroundColor: "rgba(255, 0, 0, 0.1)",
// borderColor: "rgba(255, 0, 0, 0.6)",
// pointBackgroundColor: "rgba(255, 0, 0, 1)",
// pointRadius: 4,
// //fill: false
// },
// {
// label: "Object attributes",
// data: data.obj_attr,
// backgroundColor: "rgba(0, 0, 255, 0.1)",
// borderColor: "rgba(0, 0, 255, 0.6)",
// pointBackgroundColor: "rgba(0, 0, 255, 1)",
// pointRadius: 4,
// //fill: false
// },
//
// ],
// },
// options: {
// title: {
// display: false,
// text: 'Distribution'
// },
// scales: {
// xAxes: [{
// stacked: true
// }],
// yAxes: [{
// stacked: true
// }]
// }
// }
//});
distribution_chart = new Chart(ctx, {
type: 'radar',
data: {
@ -271,6 +358,8 @@ $(document).ready(function() {
backgroundColor: "rgba(255, 0, 0, 0.1)",
borderColor: "rgba(255, 0, 0, 0.6)",
pointBackgroundColor: "rgba(255, 0, 0, 1)",
pointRadius: 4,
//fill: false
},
{
label: "Object attributes",
@ -278,6 +367,8 @@ $(document).ready(function() {
backgroundColor: "rgba(0, 0, 255, 0.1)",
borderColor: "rgba(0, 0, 255, 0.6)",
pointBackgroundColor: "rgba(0, 0, 255, 1)",
pointRadius: 4,
//fill: false
},
],
@ -290,7 +381,7 @@ $(document).ready(function() {
scale: {
ticks: {
beginAtZero: true,
maxTicksLimit: 4
maxTicksLimit: 5
}
}
}