mirror of https://github.com/MISP/MISP
chg: [distributionGraph] Added bar chart and deferred distribution data
fetching processpull/4309/head
parent
f2c2ade76b
commit
6a7efb92c5
|
@ -145,15 +145,25 @@
|
|||
'key' => __('Distribution'),
|
||||
'value_class' => ($event['Event']['distribution'] == 0) ? 'privateRedText' : '',
|
||||
'html' => sprintf(
|
||||
'%s %s',
|
||||
'%s %s %s %s',
|
||||
($event['Event']['distribution'] == 4) ?
|
||||
sprintf('<a href="%s%s">%s</a>', $baseurl . '/sharing_groups/view/', h($event['SharingGroup']['id']), h($event['SharingGroup']['name'])) :
|
||||
h($distributionLevels[$event['Event']['distribution']]),
|
||||
sprintf(
|
||||
'<span class="%s" data-object-id="%s" data-object-context="event" data-shown="false"></span><div style="display: none">%s</div>',
|
||||
'<span id="distribution_graph_bar" style="margin-left: 5px;" data-object-id="%s" data-object-context="event"></span>',
|
||||
h($event['Event']['id'])
|
||||
),
|
||||
sprintf(
|
||||
'<it class="%s" data-object-id="%s" data-object-context="event" data-shown="false"></it><div style="display: none">%s</div>',
|
||||
'useCursorPointer fa fa-info-circle distribution_graph',
|
||||
h($event['Event']['id']),
|
||||
$this->element('view_event_distribution_graph')
|
||||
),
|
||||
sprintf(
|
||||
'<it type="button" id="showAdvancedSharingButton" title="%s" class="%s" aria-hidden="true" style="margin-left: 5px;" onclick="%s"></it>',
|
||||
'Toggle advanced sharing network viewer',
|
||||
'fa fa-share-alt useCursorPointer',
|
||||
'showAdvancedSharing(this)'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
|
|
@ -181,7 +181,7 @@ function add_level_to_pb(distribution, additionalInfo, maxLevel) {
|
|||
}
|
||||
// text
|
||||
var span = document.createElement('span');
|
||||
span.classList.add('useCursorPointer', 'pbDistributionText', 'badge');
|
||||
span.classList.add('useCursorPointer', 'pbDistributionText', 'badge', 'toBeCleared');
|
||||
span.onclick = clickHandlerPbText;
|
||||
span.innerHTML = distribution[d].key;
|
||||
span.setAttribute('data-distribution', d);
|
||||
|
@ -212,7 +212,7 @@ function add_level_to_pb(distribution, additionalInfo, maxLevel) {
|
|||
|
||||
// tick
|
||||
var span = document.createElement('span');
|
||||
span.classList.add('pbDistributionTick');
|
||||
span.classList.add('pbDistributionTick', 'toBeCleared');
|
||||
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.top = d % 2 == 0 ? pb_top-15+'px' : pb_top+0+'px';
|
||||
|
@ -258,6 +258,170 @@ function showAdvancedSharing(clicked) {
|
|||
construct_network();
|
||||
}
|
||||
|
||||
function construct_piechart(data) {
|
||||
$('.toBeCleared').remove();
|
||||
|
||||
$(".loadingPopover").hide();
|
||||
|
||||
// DISTRIBUTION PROGRESSBAR
|
||||
$('#eventdistri_pb_invalid').tooltip();
|
||||
$('#eventdistri_pb').tooltip();
|
||||
$('#eventdistri_pb_min').tooltip();
|
||||
|
||||
$('#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, min_distri, max_distri;
|
||||
if (event_distribution == 4) { // if distribution is sharing group, overwrite default behavior
|
||||
var event_dist = 1;
|
||||
var min_distri = 0;
|
||||
var max_distri = 0;
|
||||
} else {
|
||||
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
|
||||
}
|
||||
add_level_to_pb(data.distributionInfo, data.additionalDistributionInfo, event_dist);
|
||||
|
||||
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*25);
|
||||
$('#eventdistri_pb_min').css("background", "#ffc107");
|
||||
|
||||
$('#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)*25);
|
||||
$('#eventdistri_pb').css("background", "#28a745");
|
||||
|
||||
$('#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)*25);
|
||||
$('#eventdistri_pb_invalid').css("background", "#dc3545");
|
||||
|
||||
// SHARING GROUPS
|
||||
var sgNum = data.additionalDistributionInfo[4].length;
|
||||
var sgPerc = (sgNum/data.allSharingGroup.length)*100;
|
||||
if (sgPerc > 0) {
|
||||
$('#eventdistri_sg_pb').width(sgPerc+'%');
|
||||
$('#eventdistri_sg_pb').tooltip({
|
||||
title: "Distribution among sharing group: "+(sgNum +' / '+ data.allSharingGroup.length)
|
||||
});
|
||||
$('#eventdistri_sg_pb').data("distribution", '4' + (event_distribution==4 ? '|5' : ''));
|
||||
$('#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: '<b>Distribution description:</b> ' + data.distributionInfo[4].desc + generate_additional_info(data.additionalDistributionInfo[4]) + '<div class="distributionInfo" style="height: 150px; width: 300px; position: relative; left: 25%;"><canvas class="distributionInfo" id="sg_distribution_graph_canvas" height="150px" width="300px"></canvas></div>',
|
||||
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>'
|
||||
})
|
||||
.click(function() {
|
||||
generate_pie_chart(data.sharingGroupRepartition, document.getElementById('sg_distribution_graph_canvas'));
|
||||
});
|
||||
|
||||
// doughtnut
|
||||
var doughnutColors = ['#ff0000', '#ff9e00', '#957200', '#008000', 'rgb(122, 134, 224)'];
|
||||
var doughnut_dataset = [
|
||||
{
|
||||
label: "All",
|
||||
data: data.event,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
{
|
||||
label: "Attributes",
|
||||
data: data.attribute,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
{
|
||||
label: "Object attributes",
|
||||
data: data.obj_attr,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
|
||||
];
|
||||
var ctx = document.getElementById("distribution_graph_canvas");
|
||||
ctx.onclick = function(evt) { clickHandlerGraph(evt); };
|
||||
|
||||
var count = 0;
|
||||
for (var i=0, n=data.event.length; i < n; i++) {
|
||||
count += data.event[i];
|
||||
}
|
||||
if (count > 0) {
|
||||
distribution_chart = new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.distributionInfo.map(function(elem, index) { return [elem.key]; }),
|
||||
distribution: data.distributionInfo,
|
||||
datasets: doughnut_dataset,
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: false
|
||||
},
|
||||
animation: {
|
||||
duration: 500
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(item, data) {
|
||||
return data.datasets[item.datasetIndex].label
|
||||
+ " - " + data.labels[item.index]
|
||||
+ ": " + data.datasets[item.datasetIndex].data[item.index];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
var canvas = ctx;
|
||||
ctx = canvas.getContext("2d");
|
||||
ctx.font = "30px Comic Sans MS";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText("Event is empty", canvas.width/2, canvas.height/2);
|
||||
}
|
||||
|
||||
// create checkboxes
|
||||
var div = $('<div class="toBeCleared"></div>');
|
||||
div.addClass('distribution_checkboxes_dataset');
|
||||
var distri_graph = $('#eventdistri_graph');
|
||||
var distriOffset = distri_graph.offset();
|
||||
var distriHeight = distri_graph.height()/2;
|
||||
div.css({left: '50px'});
|
||||
for (var i in doughnut_dataset) {
|
||||
var item = doughnut_dataset[i];
|
||||
var label = $('<label></label>');
|
||||
label.addClass('useCursorPointer');
|
||||
label.css({'user-select': 'none'});
|
||||
var checkbox = $('<input type="checkbox">');
|
||||
checkbox.data('dataset-index', i);
|
||||
checkbox.prop('checked', true);
|
||||
checkbox.change(function(evt) {
|
||||
var clickedIndex = $(this).data('dataset-index');
|
||||
var isChecked = $(this).prop('checked');
|
||||
distribution_chart.config.data.datasets[clickedIndex].hidden = !isChecked;
|
||||
distribution_chart.update();
|
||||
});
|
||||
label.append(checkbox);
|
||||
label.append(item.label);
|
||||
div.append(label);
|
||||
}
|
||||
distri_graph.append(div);
|
||||
}
|
||||
|
||||
function construct_network(target_distribution, scope_text, overwriteSg) {
|
||||
cacheAddedOrgName = {};
|
||||
if (advancedSharingNetwork !== undefined) {
|
||||
|
@ -684,30 +848,7 @@ function inject_this_community_org(nodesToAdd, edgesToAdd, orgs, group, root) {
|
|||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var rightBtn = '<span type="button" id="showAdvancedSharingButton" title="Toggle advanced sharing network viewer" class="fa fa-share-alt useCursorPointer" aria-hidden="true" style="float:right; margin-left: 5px;" onclick="showAdvancedSharing(this)"></span>';
|
||||
var pop = $('.distribution_graph').popover({
|
||||
title: "<b>Distribution graph</b> [atomic event]" + rightBtn,
|
||||
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() {
|
||||
if ($(this).data('shown') == 'true') {
|
||||
$(this).data('shown', 'false');
|
||||
$('#advancedSharingNetworkWrapper').hide('slide', {direction: 'right'}, 200, function() { $('#advancedSharingNetworkWrapper').remove(); });
|
||||
return;
|
||||
} else {
|
||||
$(this).data('shown', 'true');
|
||||
}
|
||||
function fetchDistributionData(callback) {
|
||||
$.ajax({
|
||||
url: "/events/"+"getDistributionGraph"+"/"+scope_id+"/event.json",
|
||||
dataType: 'json',
|
||||
|
@ -720,169 +861,53 @@ $(document).ready(function() {
|
|||
},
|
||||
success: function( data, textStatus, jQxhr ){
|
||||
distributionData = data;
|
||||
$(".loadingPopover").hide();
|
||||
|
||||
// DISTRIBUTION PROGRESSBAR
|
||||
$('#eventdistri_pb_invalid').tooltip();
|
||||
$('#eventdistri_pb').tooltip();
|
||||
$('#eventdistri_pb_min').tooltip();
|
||||
|
||||
$('#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, min_distri, max_distri;
|
||||
if (event_distribution == 4) { // if distribution is sharing group, overwrite default behavior
|
||||
var event_dist = 1;
|
||||
var min_distri = 0;
|
||||
var max_distri = 0;
|
||||
} else {
|
||||
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
|
||||
if (callback !== undefined) {
|
||||
callback(data);
|
||||
}
|
||||
add_level_to_pb(data.distributionInfo, data.additionalDistributionInfo, event_dist);
|
||||
|
||||
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*25);
|
||||
$('#eventdistri_pb_min').css("background", "#ffc107");
|
||||
|
||||
$('#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)*25);
|
||||
$('#eventdistri_pb').css("background", "#28a745");
|
||||
|
||||
$('#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)*25);
|
||||
$('#eventdistri_pb_invalid').css("background", "#dc3545");
|
||||
|
||||
// SHARING GROUPS
|
||||
var sgNum = data.additionalDistributionInfo[4].length;
|
||||
var sgPerc = (sgNum/data.allSharingGroup.length)*100;
|
||||
if (sgPerc > 0) {
|
||||
$('#eventdistri_sg_pb').width(sgPerc+'%');
|
||||
$('#eventdistri_sg_pb').tooltip({
|
||||
title: "Distribution among sharing group: "+(sgNum +' / '+ data.allSharingGroup.length)
|
||||
});
|
||||
$('#eventdistri_sg_pb').data("distribution", '4' + (event_distribution==4 ? '|5' : ''));
|
||||
$('#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: '<b>Distribution description:</b> ' + data.distributionInfo[4].desc + generate_additional_info(data.additionalDistributionInfo[4]) + '<div class="distributionInfo" style="height: 150px; width: 300px; position: relative; left: 25%;"><canvas class="distributionInfo" id="sg_distribution_graph_canvas" height="150px" width="300px"></canvas></div>',
|
||||
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>'
|
||||
})
|
||||
.click(function() {
|
||||
generate_pie_chart(data.sharingGroupRepartition, document.getElementById('sg_distribution_graph_canvas'));
|
||||
});
|
||||
|
||||
// doughtnut
|
||||
var doughnutColors = ['#ff0000', '#ff9e00', '#957200', '#008000', 'rgb(122, 134, 224)'];
|
||||
var doughnut_dataset = [
|
||||
{
|
||||
label: "All",
|
||||
data: data.event,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
{
|
||||
label: "Attributes",
|
||||
data: data.attribute,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
{
|
||||
label: "Object attributes",
|
||||
data: data.obj_attr,
|
||||
hidden: false,
|
||||
backgroundColor: doughnutColors
|
||||
},
|
||||
|
||||
];
|
||||
var ctx = document.getElementById("distribution_graph_canvas");
|
||||
ctx.onclick = function(evt) { clickHandlerGraph(evt); };
|
||||
|
||||
var count = 0;
|
||||
for (var i=0, n=data.event.length; i < n; i++) {
|
||||
count += data.event[i];
|
||||
}
|
||||
if (count > 0) {
|
||||
distribution_chart = new Chart(ctx, {
|
||||
type: 'doughnut',
|
||||
data: {
|
||||
labels: data.distributionInfo.map(function(elem, index) { return [elem.key]; }),
|
||||
distribution: data.distributionInfo,
|
||||
datasets: doughnut_dataset,
|
||||
},
|
||||
options: {
|
||||
title: {
|
||||
display: false
|
||||
},
|
||||
animation: {
|
||||
duration: 500
|
||||
},
|
||||
tooltips: {
|
||||
callbacks: {
|
||||
label: function(item, data) {
|
||||
return data.datasets[item.datasetIndex].label
|
||||
+ " - " + data.labels[item.index]
|
||||
+ ": " + data.datasets[item.datasetIndex].data[item.index];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
} else {
|
||||
var canvas = ctx;
|
||||
ctx = canvas.getContext("2d");
|
||||
ctx.font = "30px Comic Sans MS";
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText("Event is empty", canvas.width/2, canvas.height/2);
|
||||
}
|
||||
|
||||
// create checkboxes
|
||||
var div = $('<div></div>');
|
||||
div.addClass('distribution_checkboxes_dataset');
|
||||
var distri_graph = $('#eventdistri_graph');
|
||||
var distriOffset = distri_graph.offset();
|
||||
var distriHeight = distri_graph.height()/2;
|
||||
div.css({left: '50px'});
|
||||
for (var i in doughnut_dataset) {
|
||||
var item = doughnut_dataset[i];
|
||||
var label = $('<label></label>');
|
||||
label.addClass('useCursorPointer');
|
||||
label.css({'user-select': 'none'});
|
||||
var checkbox = $('<input type="checkbox">');
|
||||
checkbox.data('dataset-index', i);
|
||||
checkbox.prop('checked', true);
|
||||
checkbox.change(function(evt) {
|
||||
var clickedIndex = $(this).data('dataset-index');
|
||||
var isChecked = $(this).prop('checked');
|
||||
distribution_chart.config.data.datasets[clickedIndex].hidden = !isChecked;
|
||||
distribution_chart.update();
|
||||
});
|
||||
label.append(checkbox);
|
||||
label.append(item.label);
|
||||
div.append(label);
|
||||
}
|
||||
distri_graph.append(div);
|
||||
},
|
||||
error: function( jqXhr, textStatus, errorThrown ){
|
||||
console.log( errorThrown );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function drawBarChart(data) {
|
||||
var csv = "scope,val\n";
|
||||
var lineCount = 0;
|
||||
data.event.forEach(function(d, i) {
|
||||
var scope = data.distributionInfo[i].key;
|
||||
var val = d;
|
||||
csv += scope + "," + val + "\n";
|
||||
lineCount++;
|
||||
})
|
||||
sparklineBar('#distribution_graph_bar', csv, lineCount);
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
var rightBtn = '<div style="float:right;"><span type="button" id="reloadDistributionGraph" title="Reload Distribution Graph" class="fa fa-refresh useCursorPointer" aria-hidden="true" style="margin-left: 5px;" onclick="fetchDistributionData(function(data) { construct_piechart(data); });"></span></div>';
|
||||
var pop = $('.distribution_graph').popover({
|
||||
title: "<b>Distribution graph</b> [atomic event]" + rightBtn,
|
||||
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>'
|
||||
}).on('shown.bs.popover', function(e) {
|
||||
if (distributionData !== undefined) {
|
||||
construct_piechart(distributionData);
|
||||
} else {
|
||||
fetchDistributionData(function(data) { construct_piechart(data); });
|
||||
}
|
||||
}).on('hide.bs.popover', function(e) {
|
||||
// $('#advancedSharingNetworkWrapper').hide('slide', {direction: 'right'}, 200, function() { $('#advancedSharingNetworkWrapper').remove(); });
|
||||
});
|
||||
|
||||
$('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');
|
||||
}
|
||||
});
|
||||
|
||||
fetchDistributionData(function(data) {
|
||||
drawBarChart(data);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3998,6 +3998,45 @@ function liveFilter() {
|
|||
}
|
||||
}
|
||||
|
||||
function sparklineBar(elemId, data, lineCount) {
|
||||
data = d3.csv.parse(data);
|
||||
var y_max = 0;
|
||||
data.forEach(function(e) {
|
||||
e = parseInt(e.val);
|
||||
y_max = e > y_max ? e : y_max;
|
||||
});
|
||||
// y_max = Math.log(y_max)
|
||||
var WIDTH = 50;
|
||||
var HEIGHT = 25;
|
||||
var DATA_COUNT = lineCount;
|
||||
var BAR_WIDTH = (WIDTH - DATA_COUNT) / DATA_COUNT;
|
||||
var x = d3.scale.linear().domain([0, DATA_COUNT]).range([0, WIDTH]);
|
||||
var y = d3.scale.linear().domain([0, y_max]).range([0, HEIGHT]);
|
||||
|
||||
var distributionGraphBarTooltip = d3.select("body").append("div")
|
||||
.attr("class", "distributionGraphBarTooltip")
|
||||
.style("opacity", 0);
|
||||
|
||||
var svg = d3.select(elemId).append('svg')
|
||||
.attr('width', WIDTH)
|
||||
.attr('height', HEIGHT)
|
||||
.append('g');
|
||||
svg.selectAll('.bar').data(data)
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('title', function(d, i) { return d.scope + ': ' + d.val })
|
||||
.attr('class', 'DGbar')
|
||||
.append('rect')
|
||||
.attr('class', 'bar')
|
||||
.attr('x', function(d, i) { return x(i); })
|
||||
.attr('y', function(d, i) { return HEIGHT - y(d.val); })
|
||||
.attr('width', BAR_WIDTH)
|
||||
.attr('height', function(d, i) { return y(d.val); })
|
||||
.attr('fill', '#3465a4');
|
||||
|
||||
$('.DGbar').tooltip({container: 'body'});
|
||||
}
|
||||
|
||||
(function(){
|
||||
"use strict";
|
||||
$(".datepicker").datepicker({
|
||||
|
|
Loading…
Reference in New Issue