Skip to content

Instantly share code, notes, and snippets.

@endocrimes
Created November 25, 2012 21:15
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 endocrimes/4145390 to your computer and use it in GitHub Desktop.
Save endocrimes/4145390 to your computer and use it in GitHub Desktop.
Clustered Force Layout + Custom Gravity with Pan & Zoom, importing a Json file & Canvas boundaries
{
"name": "Products",
"children": [
{
"name": "Cluster1",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Palma Hotel",
"size": 26
},
{
"name": "Pineta Hotel",
"size": 26
},
{
"name": "Histria Hotel",
"size": 26
},
{
"name": "Medulin Hotel",
"size": 26
},
{
"name": "Valdaliso Hotel",
"size": 26
},
{
"name": "Grand Hotel Orebic",
"size": 26
},
{
"name": "Villa Erna",
"size": 26
},
{
"name": "Villa Amfora Dubrovnik",
"size": 26
},
{
"name": "Villa Katarina",
"size": 26
},
{
"name": "Apartments Marina",
"size": 26
},
{
"name": "Hotel As",
"size": 26
},
{
"name": "Apartments Ana",
"size": 26
}
]
},
{
"name": "Supplier: Cosmos",
"children": []
},
{
"name": "Supplier: Adriatica",
"children": [
{
"name": "Hotel Nimfa",
"size": 26
},
{
"name": "Bluesun Hotel Bonaca",
"size": 26
},
{
"name": "H. Valamar Dubrovnik President",
"size": 26
},
{
"name": "Valamar Club Dubrovnik",
"size": 26
},
{
"name": "Hotel Tirena",
"size": 26
},
{
"name": "Hotel Valamar Club Tamaris",
"size": 26
},
{
"name": "Hotel Mediteran",
"size": 26
},
{
"name": "Hotel Zorna",
"size": 26
},
{
"name": "Hotel Laguna Albatros",
"size": 26
},
{
"name": "Hotel Park ",
"size": 26
},
{
"name": "Bluesun Hotel Neptun",
"size": 26
},
{
"name": "Hotel Meteor",
"size": 26
},
{
"name": "Hotel Punta",
"size": 26
},
{
"name": "Hotel Argosy",
"size": 26
}
]
}
]
},
{
"name": "Cluster 2",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Family Apartments NOVI",
"size": 10
},
{
"name": "Belvedere Resort",
"size": 10
},
{
"name": "Plat Hotels & Villas",
"size": 10
},
{
"name": "Petalon Resort",
"size": 10
},
{
"name": "Bluesun Apartments Alan",
"size": 10
},
{
"name": "Medena Apartments",
"size": 10
},
{
"name": "Vranjica Belvedere Apartments",
"size": 10
},
{
"name": "The Residence Hotel",
"size": 10
},
{
"name": "Imperial Hotel",
"size": 10
},
{
"name": "Miran Hotel",
"size": 10
}
]
},
{
"name": "Supplier: Cosmos",
"children": []
},
{
"name": "Supplier: Adriatica",
"children": []
}
]
},
{
"name": "Cluster 3",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Feral Hotel",
"size": 72
},
{
"name": "Marco Polo Hotel",
"size": 72
},
{
"name": "Korcula Hotel",
"size": 72
},
{
"name": "Hedera Hotel",
"size": 72
},
{
"name": "Narcis Hotel",
"size": 72
},
{
"name": "Conte Hotel",
"size": 72
},
{
"name": "Pinija Hotel",
"size": 72
},
{
"name": "Vis Hotel",
"size": 72
},
{
"name": "Liburna Hotel",
"size": 72
},
{
"name": "Park Hotel Rovinj",
"size": 72
},
{
"name": "Mimosa Hotel",
"size": 72
},
{
"name": "Biokovo Hotel",
"size": 72
},
{
"name": "Astarea 2 Hotel",
"size": 72
},
{
"name": "Dubrovnik Hotel",
"size": 72
},
{
"name": "Zagreb Hotel",
"size": 72
},
{
"name": "Adriatic Hotel Biograd n/m",
"size": 72
},
{
"name": "Kornati Hotel",
"size": 72
},
{
"name": "Tragos Hotel",
"size": 72
},
{
"name": "Lafodia Hotel",
"size": 72
},
{
"name": "Medena Hotel",
"size": 72
},
{
"name": "Solaris Hotel Ivan",
"size": 72
},
{
"name": "Solaris Hotel Jure",
"size": 72
},
{
"name": "Solaris Hotel Niko",
"size": 72
},
{
"name": "Bluesun Hotel Borak",
"size": 72
},
{
"name": "Sagitta Holiday Village",
"size": 72
},
{
"name": "Croatia Hotel",
"size": 72
},
{
"name": "Iberostar Albatros Hotel",
"size": 72
},
{
"name": "Iberostar Epidaurus Hotel",
"size": 72
},
{
"name": "Astarea 1 Hotel",
"size": 72
},
{
"name": "Sumratin Hotel",
"size": 72
},
{
"name": "Ariston Hotel",
"size": 72
},
{
"name": "Dubrovnik Palace Hotel",
"size": 72
},
{
"name": "More Hotel Dubrovnik",
"size": 72
},
{
"name": "Rixos Libertas Dubrovnik",
"size": 72
},
{
"name": "Lero Hotel",
"size": 72
},
{
"name": "Splendid Hotel",
"size": 72
},
{
"name": "Uvala Hotel",
"size": 72
},
{
"name": "Berkeley Hotel Dubrovnik",
"size": 72
},
{
"name": "Komodor Hotel",
"size": 72
},
{
"name": "Kompas Hotel",
"size": 72
},
{
"name": "Admiral Grand Hotel",
"size": 72
},
{
"name": "Bellevue Hotel Orebic",
"size": 72
},
{
"name": "Podgorka Hotel",
"size": 72
},
{
"name": "Bella Vista Hotel",
"size": 72
},
{
"name": "Zora Hotel",
"size": 72
},
{
"name": "Solaris Hotel Andrija",
"size": 72
},
{
"name": "Solaris Hotel Jakov",
"size": 72
},
{
"name": "Olympia Hotel",
"size": 72
},
{
"name": "Bluesun Hotel Elaphusa",
"size": 72
},
{
"name": "Bluesun Hotel Bonaca",
"size": 72
},
{
"name": "Diadem Aparthotel",
"size": 72
},
{
"name": "The View Hotel",
"size": 72
},
{
"name": "Aurora Hotel",
"size": 72
},
{
"name": "Ambasador Hotel",
"size": 72
},
{
"name": "Admiral Hotel",
"size": 72
},
{
"name": "Kristal Hotel",
"size": 72
},
{
"name": "Cavtat Hotel",
"size": 72
},
{
"name": "Adriatic Hotel Dubrovnik",
"size": 72
},
{
"name": "Neptun Hotel",
"size": 72
},
{
"name": "Eden Hotel",
"size": 72
},
{
"name": "Istra Hotel",
"size": 72
},
{
"name": "Maestral Hotel",
"size": 72
},
{
"name": "Laguna Hotel",
"size": 72
},
{
"name": "Dalmacija Hotel",
"size": 72
},
{
"name": "Minerva Hotel",
"size": 72
},
{
"name": "Punta Hotel",
"size": 72
},
{
"name": "Punta Complex - Villa Arausa Arausana Antonina",
"size": 72
},
{
"name": "Bluesun Hotel Alan",
"size": 72
},
{
"name": "Ilirija Hotel",
"size": 72
},
{
"name": "Adriatiq Hotel Hvar",
"size": 72
},
{
"name": "Waterman Svpetrvs Resort",
"size": 72
},
{
"name": "Meteor Hotel",
"size": 72
}
]
},
{
"name": "Supplier: Cosmos",
"children": []
},
{
"name": "Supplier: Adriatica",
"children": []
}
]
},
{
"name": "Cluster 4",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Marina Hotel",
"size": 27
}
]
},
{
"name": "Supplier: Cosmos",
"children": []
},
{
"name": "Supplier: Adriatica",
"children": [
{
"name": "Hotel Vis",
"size": 27
},
{
"name": "Bluesun Hotel Marina",
"size": 27
},
{
"name": "Hotel Jure",
"size": 27
},
{
"name": "Hotel Niko",
"size": 27
},
{
"name": "Hotel Ivan",
"size": 27
},
{
"name": "Hotel Istra",
"size": 27
},
{
"name": "Bluesun Hotel Elaphusa",
"size": 27
},
{
"name": "Hotel Neptun",
"size": 27
},
{
"name": "GH Park",
"size": 27
},
{
"name": "Hotel Adriatica",
"size": 27
},
{
"name": "Hotel Medulin",
"size": 27
},
{
"name": "Hotel Plavi",
"size": 27
},
{
"name": "Hotel Laguna Molindrio",
"size": 27
},
{
"name": "Hotel Pical",
"size": 27
},
{
"name": "Valamar Pinia",
"size": 27
},
{
"name": "Hotel Park Plaza Verudela",
"size": 27
},
{
"name": "Hotel Amfora",
"size": 27
},
{
"name": "Hotel Sol Garden Istra",
"size": 27
},
{
"name": "Hotel Podgorka",
"size": 27
},
{
"name": "Hotel Lero",
"size": 27
},
{
"name": "Bluesun Hotel Alga",
"size": 27
},
{
"name": "Hotelsko naselje Waterman ",
"size": 27
},
{
"name": "Hotel Aurora",
"size": 27
},
{
"name": "Hotel Opatija",
"size": 27
},
{
"name": "Hotel Minerva",
"size": 27
},
{
"name": "Hotel Ariston ",
"size": 27
}
]
}
]
},
{
"name": "Cluster 5",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Valamar Lacroma Dubrovnik",
"size": 6
},
{
"name": "The Pucic Palace",
"size": 6
},
{
"name": "Hotel Luxe",
"size": 6
},
{
"name": "Jupiter Luxury Hotel",
"size": 6
},
{
"name": "Hotel Lapad",
"size": 6
}
]
},
{
"name": "Supplier: Cosmos",
"children": [
{
"name": "Hotel Uvala",
"size": 6
}
]
},
{
"name": "Supplier: Adriatica",
"children": []
}
]
},
{
"name": "Cluster 6",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Grand Villa Argentina",
"size": 6
},
{
"name": "Hotel Bellevue Dubrovnik",
"size": 6
}
]
},
{
"name": "Supplier: Cosmos",
"children": [
{
"name": "Grand Hotel Park",
"size": 6
},
{
"name": "Hilton Imperial Dubrovnik",
"size": 6
},
{
"name": "Hotel Dubrovnik Palace",
"size": 6
}
]
},
{
"name": "Supplier: Adriatica",
"children": [
{
"name": "Hotel Excelsior",
"size": 6
}
]
}
]
},
{
"name": "Cluster 7",
"children": [
{
"name": "Supplier: OHG",
"children": [
{
"name": "Hilton Imperial Dubrovnik",
"size": 4
},
{
"name": "Grand Hotel Park",
"size": 4
}
]
},
{
"name": "Supplier: Cosmos",
"children": []
},
{
"name": "Supplier: Adriatica",
"children": [
{
"name": "Hotel Excelsior",
"size": 4
},
{
"name": "Hotel Dubrovnik Palace",
"size": 4
}
]
}
]
}
]
}
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Data-Driven Documents</title>
<link rel="stylesheet" href="main.css">
<script src="http://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script>
// drawing the graph
var drawthegraphthing = function(data, numclusters) {
// basics
var margin = {top: 0, right: 0, bottom: 0, left: 0},
width = 1352 - margin.left - margin.right,
height = 630 - margin.top - margin.bottom;
var n = data.length,
m = numclusters,
padding = 12,
radius = d3.scale.sqrt().range([0, 6]),
color = d3.scale.category10().domain(d3.range(m));
// cluster coloring
var clusterColours = [];
var getClusterColour = function(clusterName) {
for (var cluster = 0; cluster < clusterColours.length; ++cluster) {
if (clusterColours[cluster].name == clusterName) {
return clusterColours[cluster].colour;
}
}
var colour = {
name: clusterName,
colour: color(clusterColours.length)
};
clusterColours.push(colour);
return colour.colour;
};
// nodes & svg's
var nodes = d3.range(n).map(function(a, b, c, d, e) {
var node = data[a];
return {
data: node,
color: getClusterColour(node.cluster),
radius: radius(node.size)
};
});
function svg() {
this.style("left", function(d) { return d.x + "px"; })
}
// defining the position
function position() {
this.style("left", function(d) { return d.x + "px"; })
.style("top", function(d) { return d.y + "px"; })
.style("width", function(d) { return Math.max(0, d.dx - 1) + "px"; })
.style("height", function(d) { return Math.max(0, d.dy - 1) + "px"; });
}
// forced layout
var force = d3.layout.force()
.nodes(nodes)
.size([width, height])
.gravity(0)
.charge(0)
.linkDistance(20)
.on("tick", tick)
.start();
// declaring
var svg = d3.select("body").append("svg","div")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var body = d3.selectAll("body")
.call(d3.behavior.zoom().scaleExtent([1, 168]).on("zoom", zoom))
.append("g");
// forming force
var circle = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.attr("r", function(d) { return d.radius; })
.style("fill", function(d) { return d.color; })
.text(function(d) { return d.data.name; })
.call(force.drag);
function tick(e) {
circle
.each(cluster(10 * e.alpha * e.alpha))
.each(collide(.5))
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
// Move d to be adjacent to the cluster node.
function cluster(alpha) {
var max = {};
// locating the largest node in each cluster set
nodes.forEach(function(d) {
if (!(d.color in max) || (d.radius > max[d.color].radius)) {
max[d.color] = d;
}
});
return function(d) {
var node = max[d.color],
l,
r,
x,
y,
i = -1;
if (node == d) return;
x = d.x - node.x;
y = d.y - node.y;
l = Math.sqrt(x * x + y * y);
r = d.radius + node.radius;
if (l != r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
node.x += x;
node.y += y;
}
};
}
// resolving collisions
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var r = d.radius + radius.domain()[1] + padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.point.radius + (d.color !== quad.point.color) * padding;
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2
|| x2 < nx1
|| y1 > ny2
|| y2 < ny1;
});
};
}
// zoom & pan
var x = d3.scale.linear()
.domain([-width / 2, width / 2])
.range([0, width]);
var y = d3.scale.linear()
.domain([-height / 2, height / 2])
.range([height, 0]);
svg.append("div")
.attr("width", width)
.attr("height", height);
function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
}
// building the graph
d3.json('flare.json', function(err, data, root, error, div) {
var nodeData = [];
var clusters = data.children;
for (var cluster = 0; cluster < clusters.length; ++cluster) {
var suppliers = clusters[cluster].children;
for (var supplier = 0; supplier < suppliers.length; ++supplier) {
var products = suppliers[supplier].children;
for (var product = 0; product < products.length; ++product) {
var node = {
cluster: clusters[cluster].name,
supplier: suppliers[supplier].name,
name: products[product].name,
size: suppliers.length
};
nodeData.push(node);
}
}
}
drawthegraphthing(nodeData, clusters.length);
//console.log(nodeData);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment