Bubble chart showing 100.000 Kickstarter projects. Based on the data and idea of Polygraph but trying to reorganize the colors. Color represents the project category, size the number of backers.
forked from mbostock's block: Bubble Chart
forked from john-guerra's block: Bubble Chart d3 v4
forked from john-guerra's block: Kickstarter projects in New York
xxxxxxxxxx
<meta charset="utf-8">
<style>
text {
font: 10px sans-serif;
}
</style>
<body>
<h2>Kickstarter projects in: <select name="city" id="selectCity"></select></h2>
<div id="chart"></div>
<script src="//d3js.org/d3.v4.js"></script>
<script>
var diameter = 900,
format = d3.format(",d"),
color = d3.scaleOrdinal(d3.schemeCategory20c);
var bubble = d3.pack()
.size([diameter, diameter])
.padding(0);
var svg = d3.select("body").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");
function ready(error,
unique_subs,
city_data,
city_meta,
project_backers
// uSmap,
// ipInfo
)
{
if (error) throw error;
function updateCity(city_id) {
var mapSubs = d3.map(unique_subs, function (d) { return d.sub_id;});
var mapSubsCounts = d3.map();
var mapCities = d3.map(city_meta, function (d) { return d.city_id;});
data = project_backers.filter(function (d) {
return d.city_id == city_id;
});
project_backers.forEach(function (d) {
d.backers_count = +d.backers_count;
d.city = mapCities.get(d.city_id);
d.sub = mapSubs.get(d.sub_id);
if (!mapSubsCounts.has(d.sub_id)) {
mapSubsCounts.set(d.sub_id, 0);
}
mapSubsCounts.set(d.sub_id, mapSubsCounts.get(d.sub_id)+1);
});
var root = d3.hierarchy({children:data})
.sum(function(d) { return d.backers_count; })
.sort(function(a, b) {
//Sort by categories that have more projects first
return d3.descending(mapSubsCounts.get(a.data.sub_id), mapSubsCounts.get(b.data.sub_id)) ||
// d3.ascending(a.data.sub_id, b.data.sub_id) ||
b.data.backers_count - a.data.backers_count ;
});
bubble(root);
d3.selectAll(".node").remove();
var node = svg.selectAll(".node")
.data(root.children)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return "Project id: " + d.data.project_id +
" Category:" + d.data.sub.subcategory +
" Backers: " + format(d.data.backers_count); });
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) {
return color(d.data.sub_id);
});
//Text looks kind of ugly...
// node.append("text")
// .attr("dy", ".3em")
// .style("text-anchor", "middle")
// .text(function(d) { return d.data.project_id.substring(0, d.r / 3); });
}
d3.select("#selectCity")
.on("change", function () {
updateCity(d3.select(this).property("value"));
})
.selectAll("option")
.data(city_meta)
.enter()
.append("option")
.text(function (d) { return d.city_state; })
.attr("value", function (d) { return d.city_id; });
updateCity("1") //New York
}
d3.queue()
.defer(d3.csv, "unique_subs.csv") // 67KB
.defer(d3.csv, "city_data_2.csv") // 67KB
.defer(d3.csv, "city_map_5.csv") // 23KB
.defer(d3.csv, "project_raw_4.csv") // 2.4MB
// .defer(d3.json, "map.json") //600kb
// .defer(d3.json, 'https://ipinfo.io')
// .defer()
.await(ready);
d3.select(self.frameElement).style("height", diameter + "px");
</script>
https://d3js.org/d3.v4.js