mirror of
https://github.com/gsi-upm/soil
synced 2024-11-14 15:32:29 +00:00
Charts
This commit is contained in:
parent
563dc8dc4c
commit
c93f3fafc7
25
config_copy.yml
Normal file
25
config_copy.yml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
name: ControlModelM2_sim
|
||||||
|
max_time: 100
|
||||||
|
num_trials: 2
|
||||||
|
network_params:
|
||||||
|
generator: barabasi_albert_graph
|
||||||
|
n: 100
|
||||||
|
m: 2
|
||||||
|
network_agents:
|
||||||
|
- agent_type: ControlModelM2
|
||||||
|
weight: 0.1
|
||||||
|
state:
|
||||||
|
id: 1
|
||||||
|
- agent_type: SpreadModelM2
|
||||||
|
weight: 0.9
|
||||||
|
state:
|
||||||
|
id: 0
|
||||||
|
environment_params:
|
||||||
|
prob_neutral_making_denier: 0.035
|
||||||
|
prob_infect: 0.075
|
||||||
|
prob_cured_healing_infected: 0.035
|
||||||
|
prob_cured_vaccinate_neutral: 0.035
|
||||||
|
prob_vaccinated_healing_infected: 0.035
|
||||||
|
prob_vaccinated_vaccinate_neutral: 0.035
|
||||||
|
prob_generate_anti_rumor: 0.035
|
||||||
|
standard_variance: 0.055
|
@ -17,7 +17,16 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
box-shadow: 0px -2px 5px 3px rgba(0, 0, 0, .3);
|
box-shadow: 0px 0px 5px 2px rgba(0, 0, 0, .2)
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav.navbar-right {
|
||||||
|
margin-right: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu > li > a:hover {
|
||||||
|
background-color: #d4d3d3;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node {
|
.node {
|
||||||
@ -49,6 +58,10 @@ svg#graph, #configuration {
|
|||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-left: none !important;
|
border-left: none !important;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: inherit;
|
||||||
|
justify-content: space-evenly;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
@ -86,8 +99,14 @@ button.pressed {
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-item {
|
hr {
|
||||||
margin-top: 15px !important;
|
margin-top: 15px !important;
|
||||||
|
margin-bottom: 15px !important;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#update .config-item {
|
||||||
|
margin-top: 15px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** LOADER **/
|
/** LOADER **/
|
||||||
@ -203,6 +222,16 @@ button.pressed {
|
|||||||
padding: 5px 2px;
|
padding: 5px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#percentTable .no-data-table {
|
||||||
|
font-size: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
margin-top: 15px !important;
|
margin-top: 15px !important;
|
||||||
margin-bottom: 15px !important;
|
margin-bottom: 15px !important;
|
||||||
@ -304,6 +333,19 @@ table#link-distance .max {
|
|||||||
padding: 15px !important;
|
padding: 15px !important;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper-settings.none {
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper-settings.none:before {
|
||||||
|
content: 'No configuration provided';
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper-settings .btn-group button:focus {
|
#wrapper-settings .btn-group button:focus {
|
||||||
@ -329,3 +371,30 @@ table#link-distance .max {
|
|||||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
|
||||||
background-color: #ccc;
|
background-color: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** CHARTS **/
|
||||||
|
#charts {
|
||||||
|
height: 100%;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
padding-top: 15px !important;
|
||||||
|
padding-bottom: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart {
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart.no-data:before {
|
||||||
|
content: 'No data';
|
||||||
|
position: absolute;
|
||||||
|
font-size: 10px;
|
||||||
|
padding-bottom: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart.no-data {
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
@ -20,6 +20,10 @@
|
|||||||
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
|
<script type="text/javascript" src="http://d3js.org/d3.v3.js"></script>
|
||||||
<script type="text/javascript" src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
|
<script type="text/javascript" src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
|
||||||
|
|
||||||
|
<!-- C3.js // D3-based reusable chart library -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.css" rel="stylesheet">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.min.js"></script>
|
||||||
|
|
||||||
<!-- JAVASCRIPTS -->
|
<!-- JAVASCRIPTS -->
|
||||||
<script type="text/javascript" src="js/visualization.js"></script>
|
<script type="text/javascript" src="js/visualization.js"></script>
|
||||||
<script type="text/javascript" src="js/timeline.js"></script>
|
<script type="text/javascript" src="js/timeline.js"></script>
|
||||||
@ -41,6 +45,11 @@
|
|||||||
play,
|
play,
|
||||||
slider;
|
slider;
|
||||||
|
|
||||||
|
var width_chart = (window.innerWidth - 30) / 2 - 15,
|
||||||
|
height_chart = (window.innerHeight - 230) / 2,
|
||||||
|
chart_nodes,
|
||||||
|
chart_attrs;
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
@ -56,6 +65,7 @@
|
|||||||
$('#update #file').change(function() {
|
$('#update #file').change(function() {
|
||||||
|
|
||||||
var file = $('#file')[0].files[0];
|
var file = $('#file')[0].files[0];
|
||||||
|
$('.console').append('<br/>');
|
||||||
self.GraphVisualization.reset();
|
self.GraphVisualization.reset();
|
||||||
$('#load').show();
|
$('#load').show();
|
||||||
|
|
||||||
@ -83,11 +93,6 @@
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select 'trials'
|
|
||||||
$('.config-item #trials').change(function() {
|
|
||||||
_socket.send($(this).val(), 'get_trial');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Select 'attributes'
|
// Select 'attributes'
|
||||||
$('.config-item #properties').change(function() {
|
$('.config-item #properties').change(function() {
|
||||||
self.GraphVisualization.update_graph($(this).val(), slider.value(), function() {
|
self.GraphVisualization.update_graph($(this).val(), slider.value(), function() {
|
||||||
@ -95,8 +100,38 @@
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
$('[data-toggle="tooltip"]').tooltip()
|
chart_nodes = c3.generate({
|
||||||
|
size: {
|
||||||
|
width: width_chart,
|
||||||
|
height: height_chart
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
columns: [],
|
||||||
|
type: 'area-spline'
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: { label: 'Time' },
|
||||||
|
y: { label: 'Number of nodes' }
|
||||||
|
},
|
||||||
|
point: { show: false },
|
||||||
|
bindto: '#chart_nodes'
|
||||||
|
});
|
||||||
|
chart_attrs = c3.generate({
|
||||||
|
size: {
|
||||||
|
width: width_chart,
|
||||||
|
height: height_chart
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
columns: [],
|
||||||
|
type: 'area-spline'
|
||||||
|
},
|
||||||
|
axis: {
|
||||||
|
x: { label: 'Time' },
|
||||||
|
y: { label: 'Attributes' }
|
||||||
|
},
|
||||||
|
point: { show: false },
|
||||||
|
bindto: '#chart_attrs'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
///]]
|
///]]
|
||||||
@ -113,7 +148,7 @@
|
|||||||
<div class="col-sm-9 console">
|
<div class="col-sm-9 console">
|
||||||
Please, upload a YAML file that defines all the parameters of a simulation. <br/>
|
Please, upload a YAML file that defines all the parameters of a simulation. <br/>
|
||||||
If you don't know how to write the file, please visit this page:<br/>
|
If you don't know how to write the file, please visit this page:<br/>
|
||||||
http://soilsim.readthedocs.io/en/latest/quickstart.html<br/><br/>
|
http://soilsim.readthedocs.io/en/latest/quickstart.html<br/>
|
||||||
</div>
|
</div>
|
||||||
<!-- //CONSOLE -->
|
<!-- //CONSOLE -->
|
||||||
|
|
||||||
@ -127,13 +162,15 @@
|
|||||||
</form>
|
</form>
|
||||||
<!-- //Load File -->
|
<!-- //Load File -->
|
||||||
|
|
||||||
<!-- TRIALS -->
|
<!-- Atributos -->
|
||||||
<div class="config-item">
|
<div class="config-item">
|
||||||
Trials:
|
Attributes:
|
||||||
<select id="trials" class="form-control form-control-sm">
|
<select id="properties" class="form-control form-control-sm">
|
||||||
|
<optgroup id="properties-dynamic" label="Dynamics"></optgroup>
|
||||||
|
<optgroup id="properties-static" label="Statics"></optgroup>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<!-- //TRIALS -->
|
<!-- //Atributos -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -141,19 +178,23 @@
|
|||||||
<nav class="navbar navbar-default navbar-fixed-bottom">
|
<nav class="navbar navbar-default navbar-fixed-bottom">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
<a class="navbar-brand" href="#">Brand</a>
|
<a class="navbar-brand" href="#">{{ model_name }}</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse navbar-collapse">
|
<div class="collapse navbar-collapse">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li data-target="#myCarousel" data-slide-to="0" class="active"><a href='#'>Home</a></li>
|
<li data-target="#myCarousel" data-slide-to="0" class="active" id="home_menu"><a href='#'>Home</a></li>
|
||||||
<li data-target="#myCarousel" data-slide-to="1"><a href="#" onclick="">Settings</a></li>
|
<li data-target="#myCarousel" data-slide-to="1" id="settings_menu"><a href="#">Settings & Charts</a></li>
|
||||||
|
<li class="dropdown" id="trials">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Trials <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu"></ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<ul class="nav navbar-nav navbar-right">
|
||||||
<li><a href="#">Run simulation</a></li>
|
<li><a href="#">Run simulation</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$('.nav li').click(function() {
|
$('.nav li[data-target="#myCarousel"]').click(function() {
|
||||||
$('.nav li').removeClass('active');
|
$('.nav li').removeClass('active');
|
||||||
$(this).addClass('active');
|
$(this).addClass('active');
|
||||||
});
|
});
|
||||||
@ -191,17 +232,9 @@
|
|||||||
<!-- //Graph Info -->
|
<!-- //Graph Info -->
|
||||||
|
|
||||||
<!-- PROPIEDADES -->
|
<!-- PROPIEDADES -->
|
||||||
<div class="config-item">
|
|
||||||
Propiedades:
|
|
||||||
<select id="properties" class="form-control form-control-sm">
|
|
||||||
<optgroup id="properties-dynamic" label="Dynamics"></optgroup>
|
|
||||||
<optgroup id="properties-static" label="Statics"></optgroup>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<div class="config-item">
|
<div class="config-item">
|
||||||
<table id="percentTable">
|
<table id="percentTable">
|
||||||
<tbody><tr><th></th></tr></tbody>
|
<tbody><tr><th class="no-data-table">No data</th></tr></tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
@ -271,10 +304,13 @@
|
|||||||
<!-- //Wrapper Graph Container -->
|
<!-- //Wrapper Graph Container -->
|
||||||
|
|
||||||
<!-- Wrapper Settings -->
|
<!-- Wrapper Settings -->
|
||||||
<div class="item settings">
|
<div class="item" id="settings">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="col-sm-6" id="charts"></div>
|
<div class="col-sm-6" id="charts">
|
||||||
<div class="col-sm-6" id="wrapper-settings"></div>
|
<div id="chart_nodes" class="chart no-data"></div>
|
||||||
|
<div id="chart_attrs" class="chart no-data"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6 none" id="wrapper-settings"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -284,7 +320,5 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -16,6 +16,7 @@ ws.onmessage = function(message) {
|
|||||||
switch(msg['type']) {
|
switch(msg['type']) {
|
||||||
case 'trials':
|
case 'trials':
|
||||||
$('#load').removeClass('loader');
|
$('#load').removeClass('loader');
|
||||||
|
reset_trials();
|
||||||
set_trials(msg['data']);
|
set_trials(msg['data']);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -25,13 +26,22 @@ ws.onmessage = function(message) {
|
|||||||
$('#load').hide();
|
$('#load').hide();
|
||||||
reset_configuration();
|
reset_configuration();
|
||||||
set_configuration();
|
set_configuration();
|
||||||
|
$('#home_menu').click(function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
reset_timeline();
|
||||||
|
set_timeline(msg['data']['graph']);
|
||||||
|
}, 1000);
|
||||||
|
});
|
||||||
reset_timeline();
|
reset_timeline();
|
||||||
set_timeline(msg['data']['graph']);
|
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;
|
break;
|
||||||
|
|
||||||
case 'settings':
|
case 'settings':
|
||||||
//console.log(msg['data']);
|
$('#wrapper-settings').empty().removeClass('none');
|
||||||
initGUI(msg['data']);
|
initGUI(msg['data']);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -67,12 +77,26 @@ var _socket = {
|
|||||||
|
|
||||||
var set_trials = function(trials) {
|
var set_trials = function(trials) {
|
||||||
for ( i in 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
|
// Request first trial as default
|
||||||
_socket.send(0, 'get_trial')
|
_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) {
|
var convertJSON = function(json) {
|
||||||
json.links.forEach(function(link) {
|
json.links.forEach(function(link) {
|
||||||
link.source = json.nodes[link.source]
|
link.source = json.nodes[link.source]
|
||||||
@ -156,7 +180,6 @@ var reset_configuration = function() {
|
|||||||
|
|
||||||
// 'Link Distance' slider
|
// 'Link Distance' slider
|
||||||
$('#link-distance-slider').slider('disable').slider('setValue', 30);
|
$('#link-distance-slider').slider('disable').slider('setValue', 30);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var set_timeline = function(graph) {
|
var set_timeline = function(graph) {
|
||||||
@ -278,3 +301,42 @@ var get_limits = function(graph) {
|
|||||||
})
|
})
|
||||||
return [min, max];
|
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) {
|
input.slider().on('change', function(slideEvt) {
|
||||||
current_value.text(slideEvt.value.newValue);
|
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);
|
input.slider('setValue', input.slider('getValue') - 0.001);
|
||||||
current_value.text(input.slider('getValue'));
|
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);
|
input.slider('setValue', input.slider('getValue') + 0.001);
|
||||||
current_value.text(input.slider('getValue'));
|
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) {
|
var addTextBox = function(param, obj) {
|
||||||
|
@ -37,22 +37,26 @@
|
|||||||
node; // Circles for the nodes
|
node; // Circles for the nodes
|
||||||
|
|
||||||
Number.prototype.between = function(min, max) {
|
Number.prototype.between = function(min, max) {
|
||||||
var min = (min) ? min : Math.max(),
|
var min = (min || min === 0) ? min : Math.max(),
|
||||||
max = (max) ? max : Math.min();
|
max = (max || max === 0) ? max : Math.min();
|
||||||
|
|
||||||
return this > min && this <= max;
|
return ( this > min && this <= max ) || ( min === 0 && this === 0 );
|
||||||
};
|
};
|
||||||
|
|
||||||
var lastFocusNode;
|
var lastFocusNode;
|
||||||
var _helpers = {
|
var _helpers = {
|
||||||
set_node: function(node, property) {
|
set_node: function(node, property, time) {
|
||||||
// Add nodes if data has more nodes than before
|
// Add nodes if data has more nodes than before
|
||||||
node.enter().append('circle')
|
node.enter().append('circle')
|
||||||
.attr('class', 'node')
|
.attr('class', 'node')
|
||||||
.attr('r', radius)
|
.attr('r', radius)
|
||||||
.style('fill', function (d) {
|
.style('fill', function (d) {
|
||||||
if ( Array.isArray(d[property]) ) {
|
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 {
|
} else {
|
||||||
return color(d[property]);
|
return color(d[property]);
|
||||||
}
|
}
|
||||||
@ -82,7 +86,11 @@
|
|||||||
.attr('r', radius)
|
.attr('r', radius)
|
||||||
.style('fill', function (d) {
|
.style('fill', function (d) {
|
||||||
if ( Array.isArray(d[property]) ) {
|
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 {
|
} else {
|
||||||
return color(d[property]);
|
return color(d[property]);
|
||||||
}
|
}
|
||||||
@ -226,7 +234,7 @@
|
|||||||
|
|
||||||
// Do the same with the circles for the nodes - no
|
// Do the same with the circles for the nodes - no
|
||||||
node = gnodes.selectAll('.node').data(data_node);
|
node = gnodes.selectAll('.node').data(data_node);
|
||||||
_helpers.set_node(node, property);
|
_helpers.set_node(node, property, time);
|
||||||
|
|
||||||
// Node Attributes
|
// Node Attributes
|
||||||
var statistics = {}
|
var statistics = {}
|
||||||
@ -234,10 +242,10 @@
|
|||||||
data_node.forEach(function(n) {
|
data_node.forEach(function(n) {
|
||||||
// Count node properties
|
// Count node properties
|
||||||
if ( Array.isArray(n[property]) ) {
|
if ( Array.isArray(n[property]) ) {
|
||||||
statistics[n[property][0][0]] = (!statistics[n[property][0][0]]) ? 1 : statistics[n[property][0][0]] + 1;
|
n[property].forEach(function(p) {
|
||||||
} else {
|
if ( time.between(p[1], p[2]) ) statistics[p[0]] = (!statistics[p[0]]) ? 1 : statistics[p[0]] + 1;
|
||||||
statistics[n[property]] = (!statistics[n[property]]) ? 1 : statistics[n[property]] + 1;
|
});
|
||||||
}
|
} else { statistics[n[property]] = (!statistics[n[property]]) ? 1 : statistics[n[property]] + 1; }
|
||||||
});
|
});
|
||||||
for ( i in statistics ) {
|
for ( i in statistics ) {
|
||||||
statistics[i] = (statistics[i] / data_node.length * 100).toFixed(2);
|
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
|
* Exporting
|
||||||
@ -418,6 +491,8 @@
|
|||||||
|
|
||||||
// Getters
|
// Getters
|
||||||
color: color,
|
color: color,
|
||||||
|
get_attributes: get_attributes,
|
||||||
|
get_nodes: get_nodes,
|
||||||
|
|
||||||
// Statistics
|
// Statistics
|
||||||
statistics: {},
|
statistics: {},
|
||||||
|
Loading…
Reference in New Issue
Block a user