Skip to content

Commit

Permalink
bubbles render for songs
Browse files Browse the repository at this point in the history
  • Loading branch information
kpchoy committed Mar 19, 2019
1 parent 1296695 commit c7056b9
Show file tree
Hide file tree
Showing 2 changed files with 176 additions and 135 deletions.
304 changes: 172 additions & 132 deletions bubble.js
Original file line number Diff line number Diff line change
@@ -1,153 +1,193 @@

var width = 960,
$(document).ready(function() {

$.getJSON("https://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks&api_key=f21088bf9097b49ad4e7f487abab981e&limit=100&format=json", function(json) {

$.each(json.tracks.track, function(i, item) {

let trackRequest = $.getJSON(`https://ws.audioscrobbler.com/2.0/?method=track.getInfo&api_key=f21088bf9097b49ad4e7f487abab981e&artist=${item.artist.name}&track=${item.name}&format=json`, function(json) {
$.each(json, function(i, item) {


if (typeof item.toptags === "undefined" || item.toptags.tag.length == 0) {
return songs ;

} else if (item.toptags.tag[0].name.toLowerCase() === "pop") {
popSongs.push({cluster: 0, label: `${item.name}`});


} else if (item.toptags.tag[0].name.toLowerCase().includes("hip") || item.toptags.tag[0].name.toLowerCase().includes("rap")) {
hhSongs.push({cluster: 1, label: `${item.name}`});


} else if (item.toptags.tag[0].name.toLowerCase().includes("alt")) {
aSongs.push({cluster: 2, label: `${item.name}`});


} else if (item.toptags.tag[0].name.toLowerCase().includes("rock")) {
rSongs.push({cluster: 3, label: `${item.name}`});


} else {
popSongs.push({cluster: 0, label: `${item.name}`});
}
});

});
trackRequestArr.push(trackRequest);
});

Promise.all(trackRequestArr).then(() => {
let allSongs = popSongs.concat(hhSongs, aSongs, rSongs);

var width = 960,
height = 500,
padding = 1.5, // separation between same-color nodes
clusterPadding = 6, // separation between different-color nodes
maxRadius = 12;
maxRadius = 2;

var n = allSongs.length, // total number of nodes
m = 20; // number of distinct clusters

var color = d3.scale.category10()
.domain(d3.range(m));

// The largest node for each cluster.
var clusters = new Array(m);

var idx = 0;

var nodes = d3.range(n).map(function() {
var songClusterId = allSongs[idx].cluster;
var i = Math.floor(Math.random() * m) + 10,
r = i * maxRadius,
d = {
cluster: songClusterId,
radius: r,
x: Math.cos(i / m * 2 * Math.PI) * 200 + width / 2 + Math.random(),
y: Math.sin(i / m * 2 * Math.PI) * 200 + height / 2 + Math.random(),
text: allSongs[idx].label,
};
if (!clusters[songClusterId] || (r > clusters[songClusterId].radius)) clusters[songClusterId] = d;
idx++;
return d;
});

var color = d3.scale.ordinal()
.range(["#7A99AC", "#E4002B"]);
var force = d3.layout.force()
.nodes(nodes)
.size([width, height])
.gravity(.02)
.charge(0)
.on("tick", tick)
.start();

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

var node = svg.selectAll("circle")
.data(nodes)
.enter().append("circle")
.style("fill", function(d) { return color(d.cluster); })
.call(force.drag);

node.transition()
.duration(750)
.delay(function(d, i) { return i * 5; })
.attrTween("r", function(d) {
var i = d3.interpolate(0, d.radius);
return function(t) { return d.radius = i(t); };
});

node.append("text")
// .attr("dy", ".3em")
// .style("text-anchor", "middle")
.attr("font-size", 100)
.text(function(d) {
// debugger;
return d.text;
});

function tick(e) {
node
.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) {
return function(d) {
var cluster = clusters[d.cluster];
if (cluster === d) return;
var x = d.x - cluster.x,
y = d.y - cluster.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + cluster.radius;
if (l != r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
cluster.x += x;
cluster.y += y;
}
};
}

// Resolves collisions between d and all other circles.
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function(d) {
var r = d.radius + maxRadius + Math.max(padding, clusterPadding),
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.cluster === quad.point.cluster ? padding : clusterPadding);
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;
});
};
}

d3.text("word_groups.csv", function(error, text) {
if (error) throw error;
var colNames = "text,size,group\n" + text;
var data = d3.csv.parse(colNames);

data.forEach(function(d) {
d.size = +d.size;
});


//unique cluster/group id's
var cs = [];
data.forEach(function(d){
if(!cs.contains(d.group)) {
cs.push(d.group);
}

});
});
});
var songs = [];

var n = data.length, // total number of nodes
m = cs.length; // number of distinct clusters
var popSongs = [];

//create clusters and nodes
var clusters = new Array(m);
var nodes = [];
for (var i = 0; i<n; i++){
nodes.push(create_nodes(data,i));
}

var force = d3.layout.force()
.nodes(nodes)
.size([width, height])
.gravity(.02)
.charge(0)
.on("tick", tick)
.start();
var hhSongs = [];


var aSongs = [];


var rSongs = [];

let trackRequestArr = [];


var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);


var node = svg.selectAll("circle")
.data(nodes)
.enter().append("g").call(force.drag);


node.append("circle")
.style("fill", function (d) {
return color(d.cluster);
})
.attr("r", function(d){return d.radius})


node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.text.substring(0, d.radius / 3); });




function create_nodes(data,node_counter) {
var i = cs.indexOf(data[node_counter].group),
r = Math.sqrt((i + 1) / m * -Math.log(Math.random())) * maxRadius,
d = {
cluster: i,
radius: data[node_counter].size*1.5,
text: data[node_counter].text,
x: Math.cos(i / m * 2 * Math.PI) * 200 + width / 2 + Math.random(),
y: Math.sin(i / m * 2 * Math.PI) * 200 + height / 2 + Math.random()
};
if (!clusters[i] || (r > clusters[i].radius)) clusters[i] = d;
return d;
};



function tick(e) {
node.each(cluster(10 * e.alpha * e.alpha))
.each(collide(.5))
.attr("transform", function (d) {
var k = "translate(" + d.x + "," + d.y + ")";
return k;
})

}

// Move d to be adjacent to the cluster node.
function cluster(alpha) {
return function (d) {
var cluster = clusters[d.cluster];
if (cluster === d) return;
var x = d.x - cluster.x,
y = d.y - cluster.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + cluster.radius;
if (l != r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
cluster.x += x;
cluster.y += y;
}
};
}

// Resolves collisions between d and all other circles.
function collide(alpha) {
var quadtree = d3.geom.quadtree(nodes);
return function (d) {
var r = d.radius + maxRadius + Math.max(padding, clusterPadding),
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.cluster === quad.point.cluster ? padding : clusterPadding);
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;
});
};
}
});

Array.prototype.contains = function(v) {
for(var i = 0; i < this.length; i++) {
if(this[i] === v) return true;
}
return false;
};
7 changes: 4 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
</div>


<script src="https://d3js.org/d3.v5.min.js"></script>
<!-- <script src="https://d3js.org/d3.v3.min.js"></script> -->
<!-- <script src="https://d3js.org/d3.v5.min.js"></script> -->
<script src="https://d3js.org/d3.v3.min.js"></script>


<svg width="960" height="600"></svg>
Expand All @@ -56,7 +56,8 @@
});
</script>

<script src="main.js"></script>
<!-- <script src="main.js"></script> -->
<script src="bubble.js"></script>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-rc.2/js/materialize.min.js"></script>

Expand Down

0 comments on commit c7056b9

Please sign in to comment.