index.html
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#legend {
position:absolute;
left: 810px;
top: 50px;
border: 1px solid orange;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<svg width=800 height=500 id="canvas"></svg>
<div id="legend"></div>
<script>
var url = "mozilla.json";
d3.json(url, function(err, data){
console.log(url, "error", err);
console.log(url, "data", data)
var filtered = data.filter(function(d) { return !!d.repository })
updateCircles(filtered);
})
function updateCircles(data) {
var extent = d3.extent(data, function(d,i) {
return d.repository.stargazers
})
var chartHeight = 300;
var chartWidth = 700;
var starScale = d3.scale.sqrt()
.domain(extent)
.range([5, 30])
var max = d3.max(data, function(d,i) {
return d.repository.open_issues
})
var issueScale = d3.scale.linear()
.domain([0, max])
.range([chartHeight, 50])
var languageScale = d3.scale.category10()
var max = d3.max(data, function(d,i) {
return d.repository.forks
})
var forkScale = d3.scale.linear()
.domain([0, max])
.range([100, chartWidth])
var svg = d3.select('#canvas')
var circles = svg
.selectAll('circle.item')
.data(data)
var enters = circles.enter()
.append('circle').classed('item', true)
.attr({
cx: function(d,i) {
return forkScale(d.repository.forks);
},
cy: function(d,i) {
return issueScale(d.repository.open_issues);
},
r: function(d,i) {
return starScale(d.repository.stargazers);
},
fill: function(d,i) {
return languageScale(d.repository.language)
},
stroke: function(d,i) {
return languageScale(d.repository.language)
},
"fill-opacity": 0.5,
"stroke-width": 3
})
.on("click", function(d,i){
console.log("d", d)
})
var xAxis = d3.svg.axis()
.scale(forkScale)
.orient("bottom")
.ticks(4)
var xg = svg.append("g")
xAxis(xg)
xg.attr("transform", "translate(0, " + chartHeight + ")")
xg.selectAll("path")
.style({ fill: "none", stroke: "#000"})
xg.selectAll("line")
.style({ stroke: "#000"})
var yAxis = d3.svg.axis()
.scale(issueScale)
.orient("left")
.ticks(4)
var yg = svg.append("g")
yAxis(yg)
yg.attr("transform", "translate(100, 0)")
yg.selectAll("path")
.style({ fill: "none", stroke: "#000"})
yg.selectAll("line")
.style({ stroke: "#000"})
var languages = languageScale.domain()
var div = d3.select("#legend")
div.selectAll("div.language")
.data(languages)
.enter()
.append("div").classed("language", true)
.text(function(d) { return d; })
.style({
"background-color": function(d) {
var rgb = d3.rgb(languageScale(d))
return "rgba(" + [rgb.r, rgb.g, rgb.b, 0.5] + ")";
},
"border": function(d){ return "2px solid " + languageScale(d)},
"padding":"5px",
"margin":"5px"
})
.on("mouseover", function(d){
svg.selectAll("circle.item").filter(function(c) {
return c.repository.language !== d
}).transition()
.style("opacity", 0.01)
.style("stroke-opacity", 0.01)
})
.on("mouseout", function(d) {
svg.selectAll("circle.item")
.transition()
.style("opacity", 0.5)
.style("stroke-opacity", 1)
})
}
</script>
</body>