mirror of
https://github.com/gsi-upm/soil
synced 2025-08-24 12:02:20 +00:00
Charts
This commit is contained in:
@@ -16,6 +16,7 @@ ws.onmessage = function(message) {
|
||||
switch(msg['type']) {
|
||||
case 'trials':
|
||||
$('#load').removeClass('loader');
|
||||
reset_trials();
|
||||
set_trials(msg['data']);
|
||||
break;
|
||||
|
||||
@@ -25,13 +26,22 @@ ws.onmessage = function(message) {
|
||||
$('#load').hide();
|
||||
reset_configuration();
|
||||
set_configuration();
|
||||
$('#home_menu').click(function() {
|
||||
setTimeout(function() {
|
||||
reset_timeline();
|
||||
set_timeline(msg['data']['graph']);
|
||||
}, 1000);
|
||||
});
|
||||
reset_timeline();
|
||||
set_timeline(msg['data']['graph']);
|
||||
});
|
||||
$('#charts .chart').removeClass('no-data');
|
||||
set_chart_nodes(msg['data']['graph'], chart_nodes)
|
||||
set_chart_attrs(msg['data']['graph'], chart_attrs, $('.config-item #properties').val())
|
||||
break;
|
||||
|
||||
case 'settings':
|
||||
//console.log(msg['data']);
|
||||
$('#wrapper-settings').empty().removeClass('none');
|
||||
initGUI(msg['data']);
|
||||
break;
|
||||
|
||||
@@ -67,12 +77,26 @@ var _socket = {
|
||||
|
||||
var set_trials = function(trials) {
|
||||
for ( i in trials ) {
|
||||
$('<option>').val(i).text(trials[i]).appendTo('select#trials');
|
||||
var list_item = $('<li>').appendTo('.dropdown#trials .dropdown-menu');
|
||||
$('<a>').val(i).text(trials[i]).appendTo(list_item);
|
||||
}
|
||||
// Select 'trials'
|
||||
$('.dropdown#trials li a').click(function() {
|
||||
var a = $('.dropdown-toggle .caret');
|
||||
$('.dropdown-toggle').text($(this).text() + ' ').append(a);
|
||||
_socket.send($(this).val(), 'get_trial');
|
||||
});
|
||||
// Request first trial as default
|
||||
_socket.send(0, 'get_trial')
|
||||
};
|
||||
|
||||
var reset_trials = function() {
|
||||
// 'Trials' selector
|
||||
$('.dropdown-menu').empty();
|
||||
var a = $('.dropdown-toggle .caret');
|
||||
$('.dropdown-toggle').text('Trials ').append(a);
|
||||
}
|
||||
|
||||
var convertJSON = function(json) {
|
||||
json.links.forEach(function(link) {
|
||||
link.source = json.nodes[link.source]
|
||||
@@ -156,7 +180,6 @@ var reset_configuration = function() {
|
||||
|
||||
// 'Link Distance' slider
|
||||
$('#link-distance-slider').slider('disable').slider('setValue', 30);
|
||||
|
||||
}
|
||||
|
||||
var set_timeline = function(graph) {
|
||||
@@ -278,3 +301,42 @@ var get_limits = function(graph) {
|
||||
})
|
||||
return [min, max];
|
||||
}
|
||||
|
||||
var set_chart_nodes = function(graph, chart) {
|
||||
var [min, max] = get_limits(graph);
|
||||
var data = ['nodes']
|
||||
for (var i = min; i <= max; i++) {
|
||||
data.push(this.GraphVisualization.get_nodes(i));
|
||||
}
|
||||
chart.load({
|
||||
unload: true,
|
||||
columns: [data]
|
||||
});
|
||||
}
|
||||
|
||||
var set_chart_attrs = function(graph, chart, property) {
|
||||
var [min, max] = get_limits(graph);
|
||||
var data_tmp = {}
|
||||
for (var i = min; i <= max; i++) {
|
||||
this.GraphVisualization.get_attributes(property, i, function(object) {
|
||||
for (var value in object) {
|
||||
if (!data_tmp[value]) {
|
||||
var time = 0
|
||||
for (var done in data_tmp)
|
||||
time = (data_tmp[done].length > time) ? data_tmp[done].length - 1 : time
|
||||
data_tmp[value] = Array(time).fill(0);
|
||||
}
|
||||
data_tmp[value].push(object[value]);
|
||||
}
|
||||
});
|
||||
}
|
||||
var data = $.map(data_tmp, function(value, index) {
|
||||
value.splice(0,0,index);
|
||||
return [value];
|
||||
});
|
||||
chart.load({
|
||||
unload: true,
|
||||
columns: data
|
||||
});
|
||||
chart.axis.labels({y: property});
|
||||
}
|
||||
|
@@ -37,14 +37,35 @@ var initGUI = function(model_params) {
|
||||
input.slider().on('change', function(slideEvt) {
|
||||
current_value.text(slideEvt.value.newValue);
|
||||
});
|
||||
button_down.click(function() {
|
||||
var timeout, interval;
|
||||
button_down.on('mousedown', function() {
|
||||
input.slider('setValue', input.slider('getValue') - 0.001);
|
||||
current_value.text(input.slider('getValue'));
|
||||
timeout = setTimeout(function() {
|
||||
interval = setInterval(function() {
|
||||
input.slider('setValue', input.slider('getValue') - 0.001);
|
||||
current_value.text(input.slider('getValue'));
|
||||
}, 30);
|
||||
}, 500);
|
||||
});
|
||||
button_up.click(function() {
|
||||
button_down.on('mouseup', function() {
|
||||
clearTimeout(timeout);
|
||||
clearInterval(interval);
|
||||
});
|
||||
button_up.on('mousedown', function() {
|
||||
input.slider('setValue', input.slider('getValue') + 0.001);
|
||||
current_value.text(input.slider('getValue'));
|
||||
})
|
||||
timeout = setTimeout(function() {
|
||||
interval = setInterval(function() {
|
||||
input.slider('setValue', input.slider('getValue') + 0.001);
|
||||
current_value.text(input.slider('getValue'));
|
||||
}, 30);
|
||||
}, 500);
|
||||
});
|
||||
button_up.on('mouseup', function() {
|
||||
clearTimeout(timeout);
|
||||
clearInterval(interval);
|
||||
});
|
||||
};
|
||||
|
||||
var addTextBox = function(param, obj) {
|
||||
|
@@ -37,22 +37,26 @@
|
||||
node; // Circles for the nodes
|
||||
|
||||
Number.prototype.between = function(min, max) {
|
||||
var min = (min) ? min : Math.max(),
|
||||
max = (max) ? max : Math.min();
|
||||
var min = (min || min === 0) ? min : Math.max(),
|
||||
max = (max || max === 0) ? max : Math.min();
|
||||
|
||||
return this > min && this <= max;
|
||||
return ( this > min && this <= max ) || ( min === 0 && this === 0 );
|
||||
};
|
||||
|
||||
var lastFocusNode;
|
||||
var _helpers = {
|
||||
set_node: function(node, property) {
|
||||
set_node: function(node, property, time) {
|
||||
// Add nodes if data has more nodes than before
|
||||
node.enter().append('circle')
|
||||
.attr('class', 'node')
|
||||
.attr('r', radius)
|
||||
.style('fill', function (d) {
|
||||
if ( Array.isArray(d[property]) ) {
|
||||
return color(d[property][0][0]);
|
||||
var color_node = color(d[property][0][0]);
|
||||
d[property].forEach(function(p) {
|
||||
if ( time.between(p[1], p[2]) ) color_node = color(p[0]);
|
||||
});
|
||||
return color_node;
|
||||
} else {
|
||||
return color(d[property]);
|
||||
}
|
||||
@@ -82,7 +86,11 @@
|
||||
.attr('r', radius)
|
||||
.style('fill', function (d) {
|
||||
if ( Array.isArray(d[property]) ) {
|
||||
return color(d[property][0][0]);
|
||||
var color_node = color(d[property][0][0]);
|
||||
d[property].forEach(function(p) {
|
||||
if ( time.between(p[1], p[2]) ) color_node = color(p[0]);
|
||||
});
|
||||
return color_node;
|
||||
} else {
|
||||
return color(d[property]);
|
||||
}
|
||||
@@ -226,7 +234,7 @@
|
||||
|
||||
// Do the same with the circles for the nodes - no
|
||||
node = gnodes.selectAll('.node').data(data_node);
|
||||
_helpers.set_node(node, property);
|
||||
_helpers.set_node(node, property, time);
|
||||
|
||||
// Node Attributes
|
||||
var statistics = {}
|
||||
@@ -234,10 +242,10 @@
|
||||
data_node.forEach(function(n) {
|
||||
// Count node properties
|
||||
if ( Array.isArray(n[property]) ) {
|
||||
statistics[n[property][0][0]] = (!statistics[n[property][0][0]]) ? 1 : statistics[n[property][0][0]] + 1;
|
||||
} else {
|
||||
statistics[n[property]] = (!statistics[n[property]]) ? 1 : statistics[n[property]] + 1;
|
||||
}
|
||||
n[property].forEach(function(p) {
|
||||
if ( time.between(p[1], p[2]) ) statistics[p[0]] = (!statistics[p[0]]) ? 1 : statistics[p[0]] + 1;
|
||||
});
|
||||
} else { statistics[n[property]] = (!statistics[n[property]]) ? 1 : statistics[n[property]] + 1; }
|
||||
});
|
||||
for ( i in statistics ) {
|
||||
statistics[i] = (statistics[i] / data_node.length * 100).toFixed(2);
|
||||
@@ -396,6 +404,71 @@
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributes at one moment given.
|
||||
* A function that get the attributes of all nodes at a specific time.
|
||||
*
|
||||
* @param {object} time Instant of time.
|
||||
* @param {object} callback A function called at the end.
|
||||
* @return {object} object An object with the number of nodes.
|
||||
*/
|
||||
function get_attributes(property, time, callback) {
|
||||
var attrs = {}
|
||||
|
||||
graph.nodes.forEach(function(node) {
|
||||
|
||||
if (Array.isArray(node.spells)) {
|
||||
node.spells.forEach( function(d) {
|
||||
if ( time.between(d[0], d[1]) ) {
|
||||
|
||||
if (Array.isArray(node[property])) {
|
||||
node[property].forEach( function(p) {
|
||||
if ( time.between(p[1], p[2]) ) attrs[p[0]] = (!attrs[p[0]]) ? 1 : attrs[p[0]] + 1;
|
||||
});
|
||||
} else { attrs[node[property]] = (!attrs[node[property]]) ? 1 : attrs[node[property]] + 1; }
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
if (Array.isArray(node[property])) {
|
||||
node[property].forEach( function(p) {
|
||||
if ( time.between(p[1], p[2]) ) attrs[p[0]] = (!attrs[p[0]]) ? 1 : attrs[p[0]] + 1;
|
||||
});
|
||||
} else { attrs[node[property]] = (!attrs[node[property]]) ? 1 : attrs[node[property]] + 1; }
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
if (callback) { callback(attrs); }
|
||||
else { return attrs }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get nodes at one moment given.
|
||||
* A function that get the number of nodes at a specific time.
|
||||
*
|
||||
* @param {object} time Instant of time.
|
||||
* @param {object} callback A function called at the end.
|
||||
* @return {object} number The number of nodes.
|
||||
*/
|
||||
function get_nodes(time, callback) {
|
||||
var total_nodes = 0;
|
||||
graph.nodes.forEach(function(node) {
|
||||
if (Array.isArray(node.spells)) {
|
||||
node.spells.forEach( function(d) {
|
||||
if ( time.between(d[0], d[1]) ) { total_nodes++; }
|
||||
});
|
||||
} else {
|
||||
total_nodes++;
|
||||
}
|
||||
});
|
||||
|
||||
if (callback) { callback(total_nodes); }
|
||||
else { return total_nodes }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Exporting
|
||||
@@ -418,6 +491,8 @@
|
||||
|
||||
// Getters
|
||||
color: color,
|
||||
get_attributes: get_attributes,
|
||||
get_nodes: get_nodes,
|
||||
|
||||
// Statistics
|
||||
statistics: {},
|
||||
|
Reference in New Issue
Block a user