Last active
October 17, 2017 03:25
-
-
Save aditeyapandey/fb4465efcc81ed3915f853c4488d43fe to your computer and use it in GitHub Desktop.
HW Spring layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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 = 960, | |
height = 600, | |
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,250); | |
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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