Skip to content

Instantly share code, notes, and snippets.

@davidbjourno
Last active January 26, 2016 18:13
Show Gist options
  • Save davidbjourno/1b1786489e15cefbb56d to your computer and use it in GitHub Desktop.
Save davidbjourno/1b1786489e15cefbb56d to your computer and use it in GitHub Desktop.
Force layout showing Gabriele Volpi's corporate network (partial)
<!DOCTYPE html>
<html>
<head>
<title>Explore Gabriele Volpi's corporate network</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/flag-icon-css/0.8.5/css/flag-icon.min.css">
<style>
body {
height: auto;
margin: 0;
background-color: #5cb85c;
}
svg {
display: block;
}
.node {
cursor: pointer;
stroke-width: 5;
fill: #ddd;
}
.node text {
pointer-events: none;
font-family: "FontAwesome";
font-size: 2.5em;
fill: #333;
}
.edge {
cursor: pointer;
stroke-width: 5;
}
#tooltip {
position: absolute;
width: 300px;
height: auto;
-webkit-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip dl {
margin: 0;
}
#tooltip-edge {
position: absolute;
width: 300px;
height: auto;
-webkit-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
box-shadow: 0 4px 5px 0 rgba(0, 0, 0, .14), 0 1px 10px 0 rgba(0, 0, 0, .12), 0 2px 4px -1px rgba(0, 0, 0, .2);
pointer-events: none;
}
#tooltip-edge.hidden {
display: none;
}
#tooltip-edge.panel-heading {
font-family: "FontAwesome";
font-size: 2.5em;
}
.company.hidden {
display: none;
}
.source.hidden {
display: none;
}
</style>
</head>
<body>
<div id="tooltip" class="panel panel-default hidden">
<div class="panel-heading">
<h3 class="panel-title" id="name"></h3>
<small id="flag"></small>
<small id="jurisdiction"></small>
</div>
<div class="panel-body company hidden">
<dl>
<dt>Company Status</dt>
<dd><span id="status"></span> as of <span id="status-date"></span></dd>
<dt>Company Assets</dt>
<dd><span id="assets"></span> as of <span id="assets-date"></span></dd>
<dt>Volpi Role</dt>
<dd><span id="role"></span> from <span id="role-from"></span> to <span id="role-to"></span></dd>
</dl>
</div>
<div class="panel-footer source hidden">
<small>Source: <span id="source"></span></small>
</div>
</div>
<div id="tooltip-edge" class="panel panel-default hidden">
<div class="panel-heading">
<h3 class="panel-title" id="name-edge"></h3>
</div>
<div class="panel-body">
<p id="desc"></p>
</div>
<div class="panel-footer">
<small>Source: <span id="source-edge"></span></small>
</div>
</div>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
// Dimensions
var width = 960,
height = 720,
aspect = width / height;
// Original data
var dataset = {
nodes: [
{ id: 0, name: "Gabriele Volpi", type: "individual", flag: "ng", jurisdiction: "Nigeria", source: "UK Companies House" },
{ id: 1, name: "Football College Abuja", type: "company", flag: "ng", jurisdiction: "Nigeria", companyStatus: "(Unknown)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Founder", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "Football College Abuja" },
{ id: 2, name: "Orlean Invest Services Ltd", type: "company", flag: "gb", jurisdiction: "UK", companyStatus: "In liquidation", companyStatusDate: "1 November 2010", companyAssets: "£1,672,642", companyAssetsDate: "(unknown)", volpiRole: "Director", volpiRoleFrom: "3 October 1997", volpiRoleTo: "(no date of resignation)", source: "UK Companies House" },
{ id: 3, name: "GBI Consulting Ltd", type: "company", flag: "gb", jurisdiction: "UK", companyStatus: "Active", companyStatusDate: "12 October 2015", companyAssets: "£329,334", companyAssetsDate: "31 December 2014", volpiRole: "Director", volpiRoleFrom: "25 June 2002", volpiRoleTo: "5 September 2006", source: "UK Companies House" },
{ id: 4, name: "Daniel Michel Sigaud", type: "individual", flag: "ch", jurisdiction: "Switzerland", source: "UK Companies House" },
{ id: 5, name: "N'Zogi Yetu-Gestao de Empreendimentos Limitada", flag: "ao", type: "company", jurisdiction: "Angola", companyStatus: "(Unknown)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "(Unknown)", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "UK Companies House" },
{ id: 6, name: "Orlean Invest Holding S.A.", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Vigente (current)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 7, name: "West Africa Commercial Services Ltd Inc", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Vigente (current)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 8, name: "Spaceman Ltd Inc", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Disuelto (dissolved)", companyStatusDate: "26 July 2002", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Vice-President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 9, name: "Daniellia Inc", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Disuelto (dissolved)", companyStatusDate: "25 July 2002", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 10, name: "Maritime Royal Stevedoring West Africa S.A.", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Vigente (current)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 11, name: "Alambra Ltd Inc", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Vigente (current)", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 12, name: "B & B International Services Ltd", type: "company", flag: "gb", jurisdiction: "UK", companyStatus: "Dissolved", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Director", volpiRoleFrom: "31 December 1991", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 13, name: "Nicotes West Africa Services Ltd", type: "company", flag: "gb", jurisdiction: "UK", companyStatus: "Dissolved", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Director", volpiRoleFrom: "31 August 1991", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 14, name: "Florafin Investments Corp", type: "company", flag: "pa", jurisdiction: "Panama", companyStatus: "Disuelto (dissolved)", companyStatusDate: "26 July 2002", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Vice-President and Director", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "OpenCorporates" },
{ id: 15, name: "Orlean Invest Africa Ltd", type: "company", flag: "im", jurisdiction: "Isle of Man", companyStatus: "Live", companyStatusDate: "(unknown)", companyAssets: "(Unknown)", companyAssetsDate: "(unknown)", volpiRole: "Chairman", volpiRoleFrom: "(unknown)", volpiRoleTo: "(unknown)", source: "Isle of Man Companies Registry" },
],
edges: [
{ source: 0, target: 1, name: "Volpi > Football College Abuja", desc: "Volpi founded Football College Abuja in 2012.", infoSource: "Football College Abuja" },
{ source: 0, target: 15, name: "Volpi > Orlean Invest Africa Ltd", desc: "Though the company's official filings are not publicly available, the Orlean Invest Africa website describes Volpi as \"our Chairman\".", infoSource: "Orlean Invest Africa Ltd" },
{ source: 0, target: 2, name: "Volpi > Orlean Invest Services Ltd", desc: "Volpi has been a director of Orlean Invest Services since 1997.", infoSource: "UK Companies House" },
{ source: 0, target: 3, name: "Volpi > GBI Consulting", desc: "Volpi was a director of GBI Consulting from 2002 to 2006.", infoSource: "UK Companies House" },
{ source: 0, target: 6, name: "Volpi > Orlean Invest Holding S.A.", desc: "Volpi is named as President and a director of Orlean Invest Holding.", infoSource: "OpenCorporates" },
{ source: 0, target: 7, name: "Volpi > West Africa Commercial Services Ltd Inc", desc: "Volpi is named as President and a director of West Africa Commercial Services.", infoSource: "OpenCorporates" },
{ source: 0, target: 8, name: "Volpi > Spaceman Ltd Inc", desc: "Volpi is named as Vice-President and a director of the now-dissolved Spaceman.", infoSource: "OpenCorporates" },
{ source: 0, target: 9, name: "Volpi > Daniellia Inc", desc: "Volpi is named as President and a director of the now-dissolved Daniellia.", infoSource: "OpenCorporates" },
{ source: 0, target: 10, name: "Volpi > Maritime Royal Stevedoring West Africa S.A.", desc: "Volpi is named as President and a director of Maritime Royal Stevedoring West Africa.", infoSource: "OpenCorporates" },
{ source: 0, target: 11, name: "Volpi > Alambra Ltd Inc", desc: "Volpi is named as President and a director of Alambra.", infoSource: "OpenCorporates" },
{ source: 0, target: 12, name: "Volpi > B & B International Services Ltd", desc: "Volpi is named as a director of B & B International Services.", infoSource: "OpenCorporates" },
{ source: 0, target: 13, name: "Volpi > Nicotes West Africa Services Ltd", desc: "Volpi is named as a director of the now-dissolved Nicotes West Africa Services.", infoSource: "OpenCorporates" },
{ source: 0, target: 14, name: "Volpi > Florafin Investments Corp", desc: "Volpi is named as Vice-President and a director of the now-dissolved Florafin Investments.", infoSource: "OpenCorporates" },
{ source: 1, target: 15, name: "Football College Abuja > Orlean Invest Africa Ltd", desc: "Football College Abuja's website describes it as \"a private organization established as a Corporate Social Responsibility initiative by Orlean Invest Ltd... dedicated to developing young school-age boys with football talent, especially from financially-challenged backgrounds\".", infoSource: "Orlean Invest Africa Ltd"},
{ source: 3, target: 4, name: "Daniel Michel Sigaud > GBI Consulting Ltd", desc: "Sigaud owns 25% of shares in GBI Consulting.", infoSource: "UK Companies House" },
{ source: 3, target: 5, name: "N'Zogi Yetu-Gestao de Empreendimentos Limitada > GBI Consulting Ltd", desc: "N'Zogi Yetu-Gestao de Empreendimentos owns 75% of shares in GBI Consulting.", infoSource: "UK Companies House" }
]
};
// Create SVG element
var svg = d3.select("body")
.append("svg")
.attr("id", "graph")
.attr("preserveAspectRatio", "xMidYMid")
.attr("viewBox", "0 0 " + width + " " + height);
// Initialize a default force layout, using the nodes and edges in dataset
var force = d3.layout
.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([width, height])
.gravity(.07)
.distance(180)
.charge(-1000)
.start();
// Define mouseoverNode behaviour
var mouseoverNode = function(d) {
// Highlight the circle stroke
d3.select(this)
.transition()
.duration(150)
.attr("stroke", "#d9534f");
};
// Define mousemoveNode (tooltip) behaviour
var mousemoveNode = function(d) {
// Get the mouse pointer's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.event.pageX + 10);
var yPosition = parseFloat(d3.event.pageY + 10);
// Update the tooltip position and content
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px");
d3.select("#name")
.text(d.name);
d3.select("#flag")
.attr("class", "flag-icon flag-icon-" + d.flag);
d3.select("#jurisdiction")
.text(d.jurisdiction);
d3.select("#status")
.text(d.companyStatus);
d3.select("#status-date")
.text(d.companyStatusDate);
d3.select("#assets")
.text(d.companyAssets);
d3.select("#assets-date")
.text(d.companyAssetsDate);
d3.select("#role")
.text(d.volpiRole);
d3.select("#role-from")
.text(d.volpiRoleFrom);
d3.select("#role-to")
.text(d.volpiRoleTo);
d3.select("#source")
.text(d.source);
// Show the tooltip
d3.select("#tooltip")
.classed("hidden", false);
d3.select(".company")
.classed("hidden", function() {
if (d.type == "individual") {
return true;
}
else {
return false;
}
});
d3.select(".source")
.classed("hidden", function() {
if (d.type == "individual") {
return true;
}
else {
return false;
}
});
};
// Define mouseoutNode behaviour
var mouseoutNode = function(d) {
// Unhighlight the circle stroke
d3.select(this)
.transition()
.duration(150)
.attr("stroke", "#eee");
// Hide the tooltip
d3.select("#tooltip")
.classed("hidden", true);
};
// Define mouseoverEdge behaviour
var mouseoverEdge = function(d) {
// Highlight the circle stroke
d3.select(this)
.transition()
.duration(150)
.attr("stroke", "#d9534f");
};
// Define mousemoveEdge (tooltip) behaviour
var mousemoveEdge = function(d) {
// Get the mouse pointer's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.event.pageX + 10);
var yPosition = parseFloat(d3.event.pageY + 10);
// Update the tooltip position and content
d3.select("#tooltip-edge")
.style("left", xPosition + "px")
.style("top", yPosition + "px");
d3.select("#name-edge")
.text(d.name);
d3.select("#desc")
.text(d.desc);
d3.select("#source-edge")
.text(d.infoSource);
// Show the tooltip
d3.select("#tooltip-edge")
.classed("hidden", false);
};
// Define mouseoutEdge behaviour
var mouseoutEdge = function(d) {
// Unhighlight the circle stroke
d3.select(this)
.transition()
.duration(150)
.attr("stroke", "#eee");
// Hide the tooltip
d3.select("#tooltip-edge")
.classed("hidden", true);
};
// Create edges as lines
var edge = svg.selectAll(".edge")
.data(dataset.edges)
.enter()
.append("line")
.attr("class", "edge");
// Create nodes
var node = svg.selectAll(".node")
.data(dataset.nodes)
.enter()
.append("g")
.attr("class", "node")
.call(force.drag);
// Draw node circles
node.append("circle")
.attr("r", function(d) {
if (d.id == 0) {
return 50;
}
else {
return 33;
}
})
.attr("stroke", "#eee")
.on("mouseover", mouseoverNode)
.on("mousemove", mousemoveNode)
.on("mouseout", mouseoutNode);
edge.attr("stroke", "#eee")
.on("mouseover", mouseoverEdge)
.on("mousemove", mousemoveEdge)
.on("mouseout", mouseoutEdge);;
// Add node icons
node.append("text")
.attr("dx", function(d) {
if (d.name == "Football College Abuja")
return -17.5;
else
return -14;
})
.attr("dy", 13)
.text(function(d) {
if (d.type == "individual")
return "\uf007";
if (d.name == "Football College Abuja")
return "\uf1e3";
else
return "\uf1ad";
});
// Every time the simulation "ticks", this will be called
force.on("tick", function() {
edge.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(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
// Scale on window resize
$(window).on("resize", function() {
var graph = $("#graph"),
container = graph.parent(),
targetWidth = container.width();
graph.attr("width", targetWidth);
graph.attr("height", targetWidth / aspect);
})
.trigger("resize");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment