Skip to content

Instantly share code, notes, and snippets.

@aditeyapandey
Created October 17, 2017 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aditeyapandey/afc636dd2d8ec05b452725cd7e563bea to your computer and use it in GitHub Desktop.
Save aditeyapandey/afc636dd2d8ec05b452725cd7e563bea to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
stroke: #17202A;
stroke-opacity: .2;
}
.node {
stroke: #fff;
stroke-width: 1.5px;
}
/*w3 schools:https://www.w3schools.com/css/tryit.asp?filename=trycss_buttons_basic*/
.button {
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
margin: 4px 2px;
cursor: pointer;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<div >
<button class="button" id="forceButton">Spring Layout</button>
<button class="button" id="reset">Reset</button>
</div>
<div>
<svg></svg>
</div>
</body>
<script>
//Reading the data file
d3.json("miserables.json", function(error, localgraph) {
graph=localgraph
random();
document.getElementById("forceButton").onclick = function() {spring()};
document.getElementById("reset").onclick = function() {reset()};
})
var graph
var width = 1000,
height = 500,
radius = 4;
transition_time = 6000;
var color = d3.scaleOrdinal(d3.schemeCategory20);
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height);
g = svg.append("g")
function random(){
var random_coords=randomLayout(graph)
drawGraph(graph.nodes, graph.links, random_coords);
};
function spring(){
updated_coords = springLayout(2, 2, 0.4, 0.1,300);
update(updated_coords);
}
function reset(){
random()
}
function drawGraph(nodes, links, positions){
var links = g.selectAll(".link")
.data(links, function(d){
return d.source + d.target + Math.random() ;
});
links.enter().append("line")
.attr("class", "link")
.transition()
.duration(1000)
.attr("x1", function(d) {
return positions[d.source].cx;
})
.attr("y1", function(d) {
return positions[d.source].cy;
})
.attr("x2", function(d) {
return positions[d.target].cx;
})
.attr("y2", function(d) {
return positions[d.target].cy;
});
links.exit().remove();
var nodes = g.selectAll(".node")
.data(nodes, function(d){
return d.id + Math.random() ;
});
nodes.enter().append("circle")
.attr("class", "node")
.attr("id", function(d) {
return d.id;
})
.transition()
.duration(1000)
.attr("r", radius)
.attr("cx", function(d) {
return positions[d.id].cx;
})
.attr("cy", function(d) {
return positions[d.id].cy;
})
.attr("fill", function(d){
return color(d.group);
});
nodes.exit().remove();
};
function update(positions){
var links = g.selectAll(".link")
.transition()
.duration(transition_time)
.attr("x1", function(d) {
return positions[d.source].cx;
})
.attr("y1", function(d) {
return positions[d.source].cy;
})
.attr("x2", function(d) {
return positions[d.target].cx;
})
.attr("y2", function(d) {
return positions[d.target].cy;
});
var nodes = g.selectAll(".node")
nodes.transition()
.duration(transition_time)
.attr("cx", function(d) {
return positions[d.id].cx;
})
.attr("cy", function(d) {
return positions[d.id].cy;
})
};
//Datastructures
function adjacency_list(graph){
all_nodes = node_list(graph);
adj_list = {};
graph.links.forEach(function (d){
if (adj_list[d.source] === undefined){
adj_list[d.source] = [];
adj_list[d.source].push(d.target);
}
else{
adj_list[d.source].push(d.target);
};
if (adj_list[d.target] === undefined){
adj_list[d.target] = [];
adj_list[d.target].push(d.source);
}
else{
adj_list[d.target].push(d.source);
};
});
all_nodes.forEach(function(node){
if (adj_list[node] === undefined){
adj_list[node] = [];
};
});
return adj_list;
};
function non_adjacent_list(graph){
non_adj_list = {};
all_nodes = node_list(graph);
node_ls = new Set(node_list(graph));
adj_list = adjacency_list(graph);
for (var k in adj_list) {
nei = new Set(adj_list[k]);
nei.add(k);
minus = [...node_ls].filter(x => !nei.has(x));
//console.log(k, "non adjacent", minus)
non_adj_list[k] = Array.from(minus);
var index = all_nodes.indexOf(k);
if (index > -1) {
all_nodes.splice(index, 1);
}
};
all_nodes.forEach(function (disconnected_node){
non_adj_list[disconnected_node] = Array.from(node_ls);
});
return non_adj_list;
};
//Helper Functions
function distance(x1, y1, x2, y2){
dist = Math.sqrt(Math.pow((x1-x2),2) + Math.pow((y1-y2),2));
return dist;
};
function get_current_positions(graph){
current_positions = {};
graph.nodes.forEach(function (node){
pos = {};
pos.cx = parseFloat(d3.select("#"+node.id).attr("cx"));
pos.cy = parseFloat(d3.select("#"+node.id).attr("cy"));
current_positions[node.id] = pos;
});
return current_positions;
};
function get_angle(x1, y1, x2, y2){
// first we will calculate the cos_theta
base = Math.abs(x1 - x2);
pythagorean_distance = distance(x1,y1,x2,y2);
cos_theta = base / pythagorean_distance;
angle = Math.acos(cos_theta);
return angle;
}
function node_list(graph){
nodes = [];
graph.nodes.forEach(function (node){
nodes.push(node.id);
});
return nodes;
};
//Layout Functions
function randomLayout(graph){
positions = {}
graph.nodes.forEach( function (node){
positions[node.id] = {
"cx": Math.random() * (width) * 0.8 ,
"cy": Math.random() * (height) * 0.8
}
});
return positions;
}
function springLayout(c1, c2, c3, c4, max){
non_adj_list = non_adjacent_list(graph);
adj_nei = adjacency_list(graph);
all_nodes = node_list(graph);
final_positions = get_current_positions(graph);
for (var i = 0; i < max; i++){
position_change = {};
all_nodes.forEach(function(current_node){
x1 = 0;
y1 = 0;
actual_x1 = final_positions[current_node].cx;
actual_y1 = final_positions[current_node].cy;
// Adding repulsions from non-adjacent neighbors
non_adj_list[current_node].forEach(function (nodej){
nei_x1 = final_positions[nodej].cx;
nei_y1 = final_positions[nodej].cy;
current_distance = distance(actual_x1, actual_y1, nei_x1, nei_y1);
current_angle = get_angle(actual_x1, actual_y1, nei_x1, nei_y1);
change_x1 = Math.abs(c3 / (Math.sqrt(current_distance)* Math.cos(angle)));
change_y1 = Math.abs(c3 / (Math.sqrt(current_distance) * Math.sin(angle)));
if ((actual_x1 - nei_x1) > 0){
x1 += change_x1;
}
else{
x1 -= change_x1;
};
if ((actual_y1 - nei_y1) > 0){
y1 += change_y1;
}
else{
y1 -= change_y1;
}
});
// Adding repulsion from adjacent neighbours
adj_nei[current_node].forEach(function(nodej){
nei_x1 = final_positions[nodej].cx;
nei_y1 = final_positions[nodej].cy;
current_distance = distance(actual_x1, actual_y1, nei_x1, nei_y1);
current_angle = get_angle(actual_x1, actual_y1, nei_x1, nei_y1);
change_x1 = Math.abs(c3 / (Math.sqrt(current_distance)* Math.cos(angle)));
change_y1 = Math.abs(c3 / (Math.sqrt(current_distance) * Math.sin(angle)));
if ((actual_x1 - nei_x1) > 0){
x1 += change_x1;
}
else{
x1 -= change_x1;
};
if ((actual_y1 - nei_y1) > 0){
y1 += change_y1;
}
else{
y1 -= change_y1;
}
});
// Adding spring attractions
adj_nei[current_node].forEach(function(nodej){
nei_x1 = final_positions[nodej].cx;
nei_y1 = final_positions[nodej].cy;
current_distance = distance(actual_x1, actual_y1, nei_x1, nei_y1);
current_angle = get_angle(actual_x1, actual_y1, nei_x1, nei_y1);
change_x1 = c1 * (Math.log10(current_distance/c2) * Math.cos(angle));
change_y1 = c1 * (Math.log10(current_distance/c2) * Math.sin(angle));
if ((actual_x1 - nei_x1) < 0){
x1 += change_x1;
}
else{
x1 -= change_x1;
};
if ((actual_y1 - nei_y1) < 0){
y1 += change_y1;
}
else{
y1 -= change_y1;
}
});
change = {};
change.cx = c4*x1 ;
change.cy = c4*y1 ;
position_change[current_node] = change;
});
for (node in final_positions){
updated_x = final_positions[node].cx + position_change[node].cx
updated_y = final_positions[node].cy + position_change[node].cy
final_positions[node].cx = updated_x;
final_positions[node].cy = updated_y;
}
}
return_position = {}
for (node in final_positions){
pos = {};
pos.cx = final_positions[node].cx;
pos.cy = final_positions[node].cy;
return_position[node] = pos;
}
return return_position
};
</script>
{
"nodes": [
{"id": "Myriel", "group": 1},
{"id": "Napoleon", "group": 1},
{"id": "MlleBaptistine", "group": 1},
{"id": "MmeMagloire", "group": 1},
{"id": "CountessdeLo", "group": 1},
{"id": "Geborand", "group": 1},
{"id": "Champtercier", "group": 1},
{"id": "Cravatte", "group": 1},
{"id": "Count", "group": 1},
{"id": "OldMan", "group": 1},
{"id": "Labarre", "group": 2},
{"id": "Valjean", "group": 2},
{"id": "Marguerite", "group": 3},
{"id": "MmedeR", "group": 2},
{"id": "Isabeau", "group": 2},
{"id": "Gervais", "group": 2},
{"id": "Tholomyes", "group": 3},
{"id": "Listolier", "group": 3},
{"id": "Fameuil", "group": 3},
{"id": "Blacheville", "group": 3},
{"id": "Favourite", "group": 3},
{"id": "Dahlia", "group": 3},
{"id": "Zephine", "group": 3},
{"id": "Fantine", "group": 3},
{"id": "MmeThenardier", "group": 4},
{"id": "Thenardier", "group": 4},
{"id": "Cosette", "group": 5},
{"id": "Javert", "group": 4},
{"id": "Fauchelevent", "group": 0},
{"id": "Bamatabois", "group": 2},
{"id": "Perpetue", "group": 3},
{"id": "Simplice", "group": 2},
{"id": "Scaufflaire", "group": 2},
{"id": "Woman1", "group": 2},
{"id": "Judge", "group": 2},
{"id": "Champmathieu", "group": 2},
{"id": "Brevet", "group": 2},
{"id": "Chenildieu", "group": 2},
{"id": "Cochepaille", "group": 2},
{"id": "Pontmercy", "group": 4},
{"id": "Boulatruelle", "group": 6},
{"id": "Eponine", "group": 4},
{"id": "Anzelma", "group": 4},
{"id": "Woman2", "group": 5},
{"id": "MotherInnocent", "group": 0},
{"id": "Gribier", "group": 0},
{"id": "Jondrette", "group": 7},
{"id": "MmeBurgon", "group": 7},
{"id": "Gavroche", "group": 8},
{"id": "Gillenormand", "group": 5},
{"id": "Magnon", "group": 5},
{"id": "MlleGillenormand", "group": 5},
{"id": "MmePontmercy", "group": 5},
{"id": "MlleVaubois", "group": 5},
{"id": "LtGillenormand", "group": 5},
{"id": "Marius", "group": 8},
{"id": "BaronessT", "group": 5},
{"id": "Mabeuf", "group": 8},
{"id": "Enjolras", "group": 8},
{"id": "Combeferre", "group": 8},
{"id": "Prouvaire", "group": 8},
{"id": "Feuilly", "group": 8},
{"id": "Courfeyrac", "group": 8},
{"id": "Bahorel", "group": 8},
{"id": "Bossuet", "group": 8},
{"id": "Joly", "group": 8},
{"id": "Grantaire", "group": 8},
{"id": "MotherPlutarch", "group": 9},
{"id": "Gueulemer", "group": 4},
{"id": "Babet", "group": 4},
{"id": "Claquesous", "group": 4},
{"id": "Montparnasse", "group": 4},
{"id": "Toussaint", "group": 5},
{"id": "Child1", "group": 10},
{"id": "Child2", "group": 10},
{"id": "Brujon", "group": 4},
{"id": "MmeHucheloup", "group": 8}
],
"links": [
{"source": "Napoleon", "target": "Myriel", "value": 1},
{"source": "MlleBaptistine", "target": "Myriel", "value": 8},
{"source": "MmeMagloire", "target": "Myriel", "value": 10},
{"source": "MmeMagloire", "target": "MlleBaptistine", "value": 6},
{"source": "CountessdeLo", "target": "Myriel", "value": 1},
{"source": "Geborand", "target": "Myriel", "value": 1},
{"source": "Champtercier", "target": "Myriel", "value": 1},
{"source": "Cravatte", "target": "Myriel", "value": 1},
{"source": "Count", "target": "Myriel", "value": 2},
{"source": "OldMan", "target": "Myriel", "value": 1},
{"source": "Valjean", "target": "Labarre", "value": 1},
{"source": "Valjean", "target": "MmeMagloire", "value": 3},
{"source": "Valjean", "target": "MlleBaptistine", "value": 3},
{"source": "Valjean", "target": "Myriel", "value": 5},
{"source": "Marguerite", "target": "Valjean", "value": 1},
{"source": "MmedeR", "target": "Valjean", "value": 1},
{"source": "Isabeau", "target": "Valjean", "value": 1},
{"source": "Gervais", "target": "Valjean", "value": 1},
{"source": "Listolier", "target": "Tholomyes", "value": 4},
{"source": "Fameuil", "target": "Tholomyes", "value": 4},
{"source": "Fameuil", "target": "Listolier", "value": 4},
{"source": "Blacheville", "target": "Tholomyes", "value": 4},
{"source": "Blacheville", "target": "Listolier", "value": 4},
{"source": "Blacheville", "target": "Fameuil", "value": 4},
{"source": "Favourite", "target": "Tholomyes", "value": 3},
{"source": "Favourite", "target": "Listolier", "value": 3},
{"source": "Favourite", "target": "Fameuil", "value": 3},
{"source": "Favourite", "target": "Blacheville", "value": 4},
{"source": "Dahlia", "target": "Tholomyes", "value": 3},
{"source": "Dahlia", "target": "Listolier", "value": 3},
{"source": "Dahlia", "target": "Fameuil", "value": 3},
{"source": "Dahlia", "target": "Blacheville", "value": 3},
{"source": "Dahlia", "target": "Favourite", "value": 5},
{"source": "Zephine", "target": "Tholomyes", "value": 3},
{"source": "Zephine", "target": "Listolier", "value": 3},
{"source": "Zephine", "target": "Fameuil", "value": 3},
{"source": "Zephine", "target": "Blacheville", "value": 3},
{"source": "Zephine", "target": "Favourite", "value": 4},
{"source": "Zephine", "target": "Dahlia", "value": 4},
{"source": "Fantine", "target": "Tholomyes", "value": 3},
{"source": "Fantine", "target": "Listolier", "value": 3},
{"source": "Fantine", "target": "Fameuil", "value": 3},
{"source": "Fantine", "target": "Blacheville", "value": 3},
{"source": "Fantine", "target": "Favourite", "value": 4},
{"source": "Fantine", "target": "Dahlia", "value": 4},
{"source": "Fantine", "target": "Zephine", "value": 4},
{"source": "Fantine", "target": "Marguerite", "value": 2},
{"source": "Fantine", "target": "Valjean", "value": 9},
{"source": "MmeThenardier", "target": "Fantine", "value": 2},
{"source": "MmeThenardier", "target": "Valjean", "value": 7},
{"source": "Thenardier", "target": "MmeThenardier", "value": 13},
{"source": "Thenardier", "target": "Fantine", "value": 1},
{"source": "Thenardier", "target": "Valjean", "value": 12},
{"source": "Cosette", "target": "MmeThenardier", "value": 4},
{"source": "Cosette", "target": "Valjean", "value": 31},
{"source": "Cosette", "target": "Tholomyes", "value": 1},
{"source": "Cosette", "target": "Thenardier", "value": 1},
{"source": "Javert", "target": "Valjean", "value": 17},
{"source": "Javert", "target": "Fantine", "value": 5},
{"source": "Javert", "target": "Thenardier", "value": 5},
{"source": "Javert", "target": "MmeThenardier", "value": 1},
{"source": "Javert", "target": "Cosette", "value": 1},
{"source": "Fauchelevent", "target": "Valjean", "value": 8},
{"source": "Fauchelevent", "target": "Javert", "value": 1},
{"source": "Bamatabois", "target": "Fantine", "value": 1},
{"source": "Bamatabois", "target": "Javert", "value": 1},
{"source": "Bamatabois", "target": "Valjean", "value": 2},
{"source": "Perpetue", "target": "Fantine", "value": 1},
{"source": "Simplice", "target": "Perpetue", "value": 2},
{"source": "Simplice", "target": "Valjean", "value": 3},
{"source": "Simplice", "target": "Fantine", "value": 2},
{"source": "Simplice", "target": "Javert", "value": 1},
{"source": "Scaufflaire", "target": "Valjean", "value": 1},
{"source": "Woman1", "target": "Valjean", "value": 2},
{"source": "Woman1", "target": "Javert", "value": 1},
{"source": "Judge", "target": "Valjean", "value": 3},
{"source": "Judge", "target": "Bamatabois", "value": 2},
{"source": "Champmathieu", "target": "Valjean", "value": 3},
{"source": "Champmathieu", "target": "Judge", "value": 3},
{"source": "Champmathieu", "target": "Bamatabois", "value": 2},
{"source": "Brevet", "target": "Judge", "value": 2},
{"source": "Brevet", "target": "Champmathieu", "value": 2},
{"source": "Brevet", "target": "Valjean", "value": 2},
{"source": "Brevet", "target": "Bamatabois", "value": 1},
{"source": "Chenildieu", "target": "Judge", "value": 2},
{"source": "Chenildieu", "target": "Champmathieu", "value": 2},
{"source": "Chenildieu", "target": "Brevet", "value": 2},
{"source": "Chenildieu", "target": "Valjean", "value": 2},
{"source": "Chenildieu", "target": "Bamatabois", "value": 1},
{"source": "Cochepaille", "target": "Judge", "value": 2},
{"source": "Cochepaille", "target": "Champmathieu", "value": 2},
{"source": "Cochepaille", "target": "Brevet", "value": 2},
{"source": "Cochepaille", "target": "Chenildieu", "value": 2},
{"source": "Cochepaille", "target": "Valjean", "value": 2},
{"source": "Cochepaille", "target": "Bamatabois", "value": 1},
{"source": "Pontmercy", "target": "Thenardier", "value": 1},
{"source": "Boulatruelle", "target": "Thenardier", "value": 1},
{"source": "Eponine", "target": "MmeThenardier", "value": 2},
{"source": "Eponine", "target": "Thenardier", "value": 3},
{"source": "Anzelma", "target": "Eponine", "value": 2},
{"source": "Anzelma", "target": "Thenardier", "value": 2},
{"source": "Anzelma", "target": "MmeThenardier", "value": 1},
{"source": "Woman2", "target": "Valjean", "value": 3},
{"source": "Woman2", "target": "Cosette", "value": 1},
{"source": "Woman2", "target": "Javert", "value": 1},
{"source": "MotherInnocent", "target": "Fauchelevent", "value": 3},
{"source": "MotherInnocent", "target": "Valjean", "value": 1},
{"source": "Gribier", "target": "Fauchelevent", "value": 2},
{"source": "MmeBurgon", "target": "Jondrette", "value": 1},
{"source": "Gavroche", "target": "MmeBurgon", "value": 2},
{"source": "Gavroche", "target": "Thenardier", "value": 1},
{"source": "Gavroche", "target": "Javert", "value": 1},
{"source": "Gavroche", "target": "Valjean", "value": 1},
{"source": "Gillenormand", "target": "Cosette", "value": 3},
{"source": "Gillenormand", "target": "Valjean", "value": 2},
{"source": "Magnon", "target": "Gillenormand", "value": 1},
{"source": "Magnon", "target": "MmeThenardier", "value": 1},
{"source": "MlleGillenormand", "target": "Gillenormand", "value": 9},
{"source": "MlleGillenormand", "target": "Cosette", "value": 2},
{"source": "MlleGillenormand", "target": "Valjean", "value": 2},
{"source": "MmePontmercy", "target": "MlleGillenormand", "value": 1},
{"source": "MmePontmercy", "target": "Pontmercy", "value": 1},
{"source": "MlleVaubois", "target": "MlleGillenormand", "value": 1},
{"source": "LtGillenormand", "target": "MlleGillenormand", "value": 2},
{"source": "LtGillenormand", "target": "Gillenormand", "value": 1},
{"source": "LtGillenormand", "target": "Cosette", "value": 1},
{"source": "Marius", "target": "MlleGillenormand", "value": 6},
{"source": "Marius", "target": "Gillenormand", "value": 12},
{"source": "Marius", "target": "Pontmercy", "value": 1},
{"source": "Marius", "target": "LtGillenormand", "value": 1},
{"source": "Marius", "target": "Cosette", "value": 21},
{"source": "Marius", "target": "Valjean", "value": 19},
{"source": "Marius", "target": "Tholomyes", "value": 1},
{"source": "Marius", "target": "Thenardier", "value": 2},
{"source": "Marius", "target": "Eponine", "value": 5},
{"source": "Marius", "target": "Gavroche", "value": 4},
{"source": "BaronessT", "target": "Gillenormand", "value": 1},
{"source": "BaronessT", "target": "Marius", "value": 1},
{"source": "Mabeuf", "target": "Marius", "value": 1},
{"source": "Mabeuf", "target": "Eponine", "value": 1},
{"source": "Mabeuf", "target": "Gavroche", "value": 1},
{"source": "Enjolras", "target": "Marius", "value": 7},
{"source": "Enjolras", "target": "Gavroche", "value": 7},
{"source": "Enjolras", "target": "Javert", "value": 6},
{"source": "Enjolras", "target": "Mabeuf", "value": 1},
{"source": "Enjolras", "target": "Valjean", "value": 4},
{"source": "Combeferre", "target": "Enjolras", "value": 15},
{"source": "Combeferre", "target": "Marius", "value": 5},
{"source": "Combeferre", "target": "Gavroche", "value": 6},
{"source": "Combeferre", "target": "Mabeuf", "value": 2},
{"source": "Prouvaire", "target": "Gavroche", "value": 1},
{"source": "Prouvaire", "target": "Enjolras", "value": 4},
{"source": "Prouvaire", "target": "Combeferre", "value": 2},
{"source": "Feuilly", "target": "Gavroche", "value": 2},
{"source": "Feuilly", "target": "Enjolras", "value": 6},
{"source": "Feuilly", "target": "Prouvaire", "value": 2},
{"source": "Feuilly", "target": "Combeferre", "value": 5},
{"source": "Feuilly", "target": "Mabeuf", "value": 1},
{"source": "Feuilly", "target": "Marius", "value": 1},
{"source": "Courfeyrac", "target": "Marius", "value": 9},
{"source": "Courfeyrac", "target": "Enjolras", "value": 17},
{"source": "Courfeyrac", "target": "Combeferre", "value": 13},
{"source": "Courfeyrac", "target": "Gavroche", "value": 7},
{"source": "Courfeyrac", "target": "Mabeuf", "value": 2},
{"source": "Courfeyrac", "target": "Eponine", "value": 1},
{"source": "Courfeyrac", "target": "Feuilly", "value": 6},
{"source": "Courfeyrac", "target": "Prouvaire", "value": 3},
{"source": "Bahorel", "target": "Combeferre", "value": 5},
{"source": "Bahorel", "target": "Gavroche", "value": 5},
{"source": "Bahorel", "target": "Courfeyrac", "value": 6},
{"source": "Bahorel", "target": "Mabeuf", "value": 2},
{"source": "Bahorel", "target": "Enjolras", "value": 4},
{"source": "Bahorel", "target": "Feuilly", "value": 3},
{"source": "Bahorel", "target": "Prouvaire", "value": 2},
{"source": "Bahorel", "target": "Marius", "value": 1},
{"source": "Bossuet", "target": "Marius", "value": 5},
{"source": "Bossuet", "target": "Courfeyrac", "value": 12},
{"source": "Bossuet", "target": "Gavroche", "value": 5},
{"source": "Bossuet", "target": "Bahorel", "value": 4},
{"source": "Bossuet", "target": "Enjolras", "value": 10},
{"source": "Bossuet", "target": "Feuilly", "value": 6},
{"source": "Bossuet", "target": "Prouvaire", "value": 2},
{"source": "Bossuet", "target": "Combeferre", "value": 9},
{"source": "Bossuet", "target": "Mabeuf", "value": 1},
{"source": "Bossuet", "target": "Valjean", "value": 1},
{"source": "Joly", "target": "Bahorel", "value": 5},
{"source": "Joly", "target": "Bossuet", "value": 7},
{"source": "Joly", "target": "Gavroche", "value": 3},
{"source": "Joly", "target": "Courfeyrac", "value": 5},
{"source": "Joly", "target": "Enjolras", "value": 5},
{"source": "Joly", "target": "Feuilly", "value": 5},
{"source": "Joly", "target": "Prouvaire", "value": 2},
{"source": "Joly", "target": "Combeferre", "value": 5},
{"source": "Joly", "target": "Mabeuf", "value": 1},
{"source": "Joly", "target": "Marius", "value": 2},
{"source": "Grantaire", "target": "Bossuet", "value": 3},
{"source": "Grantaire", "target": "Enjolras", "value": 3},
{"source": "Grantaire", "target": "Combeferre", "value": 1},
{"source": "Grantaire", "target": "Courfeyrac", "value": 2},
{"source": "Grantaire", "target": "Joly", "value": 2},
{"source": "Grantaire", "target": "Gavroche", "value": 1},
{"source": "Grantaire", "target": "Bahorel", "value": 1},
{"source": "Grantaire", "target": "Feuilly", "value": 1},
{"source": "Grantaire", "target": "Prouvaire", "value": 1},
{"source": "MotherPlutarch", "target": "Mabeuf", "value": 3},
{"source": "Gueulemer", "target": "Thenardier", "value": 5},
{"source": "Gueulemer", "target": "Valjean", "value": 1},
{"source": "Gueulemer", "target": "MmeThenardier", "value": 1},
{"source": "Gueulemer", "target": "Javert", "value": 1},
{"source": "Gueulemer", "target": "Gavroche", "value": 1},
{"source": "Gueulemer", "target": "Eponine", "value": 1},
{"source": "Babet", "target": "Thenardier", "value": 6},
{"source": "Babet", "target": "Gueulemer", "value": 6},
{"source": "Babet", "target": "Valjean", "value": 1},
{"source": "Babet", "target": "MmeThenardier", "value": 1},
{"source": "Babet", "target": "Javert", "value": 2},
{"source": "Babet", "target": "Gavroche", "value": 1},
{"source": "Babet", "target": "Eponine", "value": 1},
{"source": "Claquesous", "target": "Thenardier", "value": 4},
{"source": "Claquesous", "target": "Babet", "value": 4},
{"source": "Claquesous", "target": "Gueulemer", "value": 4},
{"source": "Claquesous", "target": "Valjean", "value": 1},
{"source": "Claquesous", "target": "MmeThenardier", "value": 1},
{"source": "Claquesous", "target": "Javert", "value": 1},
{"source": "Claquesous", "target": "Eponine", "value": 1},
{"source": "Claquesous", "target": "Enjolras", "value": 1},
{"source": "Montparnasse", "target": "Javert", "value": 1},
{"source": "Montparnasse", "target": "Babet", "value": 2},
{"source": "Montparnasse", "target": "Gueulemer", "value": 2},
{"source": "Montparnasse", "target": "Claquesous", "value": 2},
{"source": "Montparnasse", "target": "Valjean", "value": 1},
{"source": "Montparnasse", "target": "Gavroche", "value": 1},
{"source": "Montparnasse", "target": "Eponine", "value": 1},
{"source": "Montparnasse", "target": "Thenardier", "value": 1},
{"source": "Toussaint", "target": "Cosette", "value": 2},
{"source": "Toussaint", "target": "Javert", "value": 1},
{"source": "Toussaint", "target": "Valjean", "value": 1},
{"source": "Child1", "target": "Gavroche", "value": 2},
{"source": "Child2", "target": "Gavroche", "value": 2},
{"source": "Child2", "target": "Child1", "value": 3},
{"source": "Brujon", "target": "Babet", "value": 3},
{"source": "Brujon", "target": "Gueulemer", "value": 3},
{"source": "Brujon", "target": "Thenardier", "value": 3},
{"source": "Brujon", "target": "Gavroche", "value": 1},
{"source": "Brujon", "target": "Eponine", "value": 1},
{"source": "Brujon", "target": "Claquesous", "value": 1},
{"source": "Brujon", "target": "Montparnasse", "value": 1},
{"source": "MmeHucheloup", "target": "Bossuet", "value": 1},
{"source": "MmeHucheloup", "target": "Joly", "value": 1},
{"source": "MmeHucheloup", "target": "Grantaire", "value": 1},
{"source": "MmeHucheloup", "target": "Bahorel", "value": 1},
{"source": "MmeHucheloup", "target": "Courfeyrac", "value": 1},
{"source": "MmeHucheloup", "target": "Gavroche", "value": 1},
{"source": "MmeHucheloup", "target": "Enjolras", "value": 1}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment