// tbody').empty();
$('#info-graph > tbody').empty();
$('#info-graph > tbody').empty();
}
function loader(show) {
$('.load').show();
// Show loader
if (show) {
$('svg#graph').css("background-color", "white");
$('.load').text("").addClass("loader");
// Show "No File"
} else {
$('svg#graph').css("background-color", "rgba(128,128,128,0.1)");
$('.load').text("No file").removeClass("loader");
}
}
=====================================================================================================================================================================
function loadFile(file) {
/**
* GRAPH
*/
// Color
color = d3.scale.category20();
// Zoom
zoom = d3.behavior
.zoom()
.scaleExtent([1/10, 10])
.on('zoom', function () {
//console.trace("zoom", d3.event.translate, d3.event.scale);
groot.attr('transform',
'translate(' + d3.event.translate + ')scale(' + d3.event.scale + ')');
});
// Set up the force layout
force = d3.layout.force()
.charge(-500)
.linkDistance(30)
.size([width, height]);
// Activate zoom for the svg item
svg = d3.select('#graph')
.attr("width", width)
.attr("height", height)
.call(zoom);
// Append sections to svg to have nodes and edges separately
groot = svg.append("g") .attr("id", "root");
glinks = groot.append("g") .attr("id", "links");
gnodes = groot.append("g") .attr("id", "nodes");
// Read the data from the graph
graph = GexfParser.fetch(file);
console.log("Graph", graph);
if (graph.mode === "dynamic") {
atts = GexfParser.dynamic(file, graph.timeformat)
colorProperty = graph.model[0].title;
console.log("Dynamic Attributes", atts);
} else {
atts = null;
}
// Number of nodes and links info table
$('
').appendTo('#info-graph > tbody');
$('').text('Nodes:').appendTo('#info-graph > tbody tr:nth-child(1)');
$(' | ').text(graph.nodes.length).addClass('text-right').appendTo('#info-graph > tbody tr:nth-child(1)');
$(' |
').appendTo('#info-graph > tbody');
$('').text('Links:').appendTo('#info-graph > tbody tr:nth-child(2)');
$(' | ').text(graph.links.length).addClass('text-right').appendTo('#info-graph > tbody tr:nth-child(2)');
// Update linkedByIndex
linkedByIndex = {};
graph.links.forEach(function(d) {
linkedByIndex[d.source + "," + d.target] = true;
});
// Creates the graph data structure out of the json data
force.nodes(graph.nodes)
.links(graph.links)
.start();
// Create all the line svgs but without locations yet
link = glinks.selectAll(".link").data(graph.links);
set_link(link);
// Do the same with the circles for the nodes - no
var lastFocusNode;
node = gnodes.selectAll(".node").data(graph.nodes);
set_node(node);
// Now we are giving the SVGs coordinates - the force layout is generating the coordinates which this code is using to update the attributes
// of the SVG elements
force.on("tick", function () {
link.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", function (d) {
return d.target.x;
})
.attr("y2", function (d) {
return d.target.y;
});
node.attr('transform', function translate(d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
});
function set_node(node) {
// Add nodes if the data has more nodes than before
node.enter().append("circle")
.attr("class", "node")
.attr("r", radius)
.style("fill", function (d) {
return color(d.attributes[colorProperty]);
})
// Cancel zoom movement so you can move the node
.on("mousedown", function(d) {
d3.event.stopPropagation();
})
// Double-click to focus neighbours
.on("dblclick", function(d) {
d3.event.stopPropagation();
if (d === lastFocusNode) {
lastFocusNode = undefined;
node.style("opacity", 1);
link.style("opacity", 1);
} else {
lastFocusNode = d;
set_focus(d);
}
}).call(force.drag);
// Remove nodes if the data has less nodes than before
node.exit().remove();
}
function set_link(link) {
// Remove links if the data has more links than before
link.enter().append("line")
.attr("class", "link")
.style("stroke-width", function (d) {
return Math.sqrt(d.value);
});
// Remove links if the data has less links than before
link.exit().remove();
}
function set_focus(d) {
node.style("opacity", function(o) {
return isConnected(d,o) || d.index == o.index ? 1 : focus_opacity;
});
link.style("opacity", function(o) {
return o.source.index == d.index || o.target.index == d.index ? 1 : focus_opacity;
});
function isConnected(source, neighbour) {
return linkedByIndex[source.index + "," + neighbour.index] ||
linkedByIndex[neighbour.index + "," + source.index];
}
}
=====================================================================================================================================================================
/**
* TIMELINE
*/
// Maximum and minimum of all the intervals
minInterval = Math.min();
maxInterval = Math.max();
_helpers.attributesInterval(atts, function(d) {
if ( d[0] < minInterval && d[0] != -Infinity ) minInterval = d[0];
if ( d[1] < minInterval && d[0] != +Infinity ) minInterval = d[1];
if ( d[0] > maxInterval && d[0] != -Infinity ) maxInterval = d[0];
if ( d[1] > maxInterval && d[1] != +Infinity ) maxInterval = d[1];
});
// Transform dates to ints
if ( graph.timeformat === "date" ) {
time = d3.scale.linear().domain([minInterval, maxInterval]).range([1, 20]);
// Attributes
_helpers.attributesInterval(atts, function(d) {
if (d[0] !== -Infinity) d[0] = time(d[0]);
if (d[1] !== +Infinity) d[1] = time(d[1]);
});
// Nodes
graph.nodes.forEach( function(node) {
if (Array.isArray(node.spell)) {
node.spell.forEach( function(d) {
if (d[0] !== -Infinity) d[0] = time(d[0]);
if (d[1] !== +Infinity) d[1] = time(d[1]);
});
}
});
// Links
graph.links.forEach( function(link) {
if (link.spell[0] !== -Infinity) link.spell[0] = time(link.spell[0]);
if (link.spell[1] !== +Infinity) link.spell[1] = time(link.spell[1]);
});
minInterval = 1;
maxInterval = 20;
}
stepUnix = (maxInterval - minInterval) / 200;
minUnix = (minInterval !== Math.min()) ? minInterval - 2 * stepUnix : 0;
maxUnix = (maxInterval !== Math.max()) ? maxInterval + 2 * stepUnix : minUnix + 20;
// Create the slider
slider = d3.slider();
d3.select("#slider3").attr("width", width).call(slider.axis(true)
.min(minUnix).max(maxUnix).step(stepUnix).value(maxUnix)
.on("slide", function(evt, value) {
updateData(value);
})
);
function updateData(value) {
var statics = {};
$('#percentTable > tbody').empty();
// Reset data
var delete_links = true;
data_node = [];
data_link = graph.links.slice();
// Nodes
graph.nodes.forEach(function(n) {
if (Array.isArray(n.spell)) {
n.spell.forEach( function(d) {
if (d[0] < value && value <= d[1]) {
data_node.push(n);
delete_links = false;
}
});
if (delete_links) {
graph.links.forEach(function(e) {
if (e.source === n || e.target === n) {
data_link.splice(data_link.indexOf(e), 1);
}
});
}
} else {
data_node.push(n);
}
});
// Links
graph.links.forEach(function(e) {
if ( !(e.spell[0] < value && value <= e.spell[1]) && data_link.includes(e) )
data_link.splice(data_link.indexOf(e), 1);
});
// Reset force
force.stop()
.nodes(data_node)
.links(data_link)
.start();
// Redraw Graph
link = glinks.selectAll(".link").data(data_link);
set_link(link);
node = gnodes.selectAll(".node").data(data_node);
set_node(node);
// Node Attributes
data_node.forEach(function(n) {
for (var property in atts) {
var interval = atts[property][n.index].interval
for ( var i = 0; i < interval.length; i++ ) {
//console.log(interval[i][0], value, interval[i][1], "->", interval[i][2])
if (interval[i][0] < value && value <= interval[i][1])
n.attributes[property] = interval[i][2];
else if (value === minUnix)
n.attributes[property] = interval[0][2];
}
}
// Count node properties
statics[n.attributes[colorProperty]] = (!statics[n.attributes[colorProperty]]) ? 1 :
statics[n.attributes[colorProperty]] + 1;
});
node.style("fill", function (d) {
return color(d.attributes[colorProperty]);
});
// Show the five properties with more percentage
var staticsSorted = Object.keys(statics).sort(function(a,b) {
return statics[b] - statics[a];
});
for ( var i = 0; ( i < staticsSorted.length ) && ( i < 5 ); i++ ) {
var percent = statics[staticsSorted[i]] / data_node.length * 100;
var propertyName = (staticsSorted[i].includes("class")) ?
staticsSorted[i].split('.').pop().split('\'')[0] : staticsSorted[i];
// Draw table every time
var appendTo = '#percentTable > tbody tr:nth-child(' + Number(i + 1) + ')';
$(' |
').addClass('col-sm-12').appendTo('#percentTable > tbody');
$('').css("background-color", color(staticsSorted[i])).addClass('col-sm-1').attr('data-value', staticsSorted[i]).appendTo(appendTo);
$(' | ').addClass('text-left col-sm-4').text(percent.toFixed(2) + " %").appendTo(appendTo);
$(' | ').addClass('text-right col-sm-6 property-name').text(propertyName).appendTo(appendTo);
}
return;
}
=====================================================================================================================================================================
/**
* PAGE ELEMENTS
*/
$('.load').hide();
$('button#button_play').on('click', function() {
$('button#button_play').addClass('pressed').prop("disabled", true);
$('#speed-slider').slider('disable');
slider.step( 1 / speed );
if (slider.value() >= maxUnix) {
slider.value(minUnix);
updateData(slider.value());
setTimeout(player, 2000);
} else {
player();
}
var i = slider.value();
function player() {
clearInterval(play);
play = setInterval(function() {
if (slider.value() + slider.step() >= maxUnix) {
slider.value(maxUnix);
slider.step(stepUnix);
clearInterval(play);
$('button#button_play').removeClass('pressed').prop("disabled", false);
$('#speed-slider').slider('enable');
} else {
updateData(slider.value());
slider.value(i);
i += slider.step();
}
}, 5);
}
});
$('button#button_pause').on('click', function() {
clearInterval(play);
slider.step(stepUnix);
$('button#button_play').removeClass('pressed').prop("disabled", false);
$('#speed-slider').slider('enable');
});
var dynamicArray = _helpers.dynamicAttsToArray(atts);
for (var i = 0; i < graph.model.length; i++) {
if ( dynamicArray.includes(graph.model[i].title) )
$(' |