|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<title>Histograms: diameters of asteroids</title> |
|
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> |
|
<style> |
|
path.domain { |
|
fill: none; |
|
stroke: #999; |
|
} |
|
|
|
line { |
|
stroke: #666; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
rect { |
|
fill: red; |
|
opacity: .5; |
|
} |
|
|
|
text { |
|
font-family: sans-serif; |
|
font-size: 9pt; |
|
text-anchor: middle; |
|
} |
|
|
|
.bar text { |
|
font-size: 10pt; |
|
text-anchor: start; |
|
} |
|
svg { |
|
background: #eee; |
|
} |
|
|
|
h1 { |
|
font-family: sans-serif; |
|
color: #555; |
|
text-align: center; |
|
font-size: 16pt; |
|
} |
|
|
|
body { |
|
background: #eee; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body> |
|
<h1>Diameters of asteroids (main belt)</h1> |
|
|
|
<script> |
|
var svgWidth = 960, |
|
svgHeight = 500; |
|
var margin = {top: 10, right: 30, bottom: 30, left: 50}; |
|
width = svgWidth - margin.left - margin.right, |
|
height = svgHeight - margin.top - margin.bottom; |
|
|
|
var dimensions = { |
|
height: "100%", |
|
width: "100%", |
|
}; |
|
|
|
var viewBox = { |
|
viewBox: "0 0 " + svgWidth + " " + svgHeight |
|
}; |
|
|
|
var xScale = d3.scale.linear() |
|
.range([0, width]); |
|
var yScale = d3.scale.linear() |
|
.range([height, 50]); |
|
|
|
var xAxis = d3.svg.axis() |
|
.scale(xScale) |
|
.orient("bottom"); |
|
var yAxis = d3.svg.axis() |
|
.scale(yScale) |
|
.orient("left"); |
|
|
|
var dataset; |
|
|
|
var histograms = function (datasets) { |
|
|
|
if (dataset == datasets.asteroids) { |
|
dataset = datasets.tnos; |
|
d3.select("h1").html("Average diameters of "+dataset.length+" Kuiper belt objects"); |
|
} else { |
|
dataset = datasets.asteroids; |
|
d3.select("h1").html("Average diameters of "+dataset.length+" main asteroid belt objects"); |
|
} |
|
|
|
var thresholds = d3.range(0, d3.max(dataset, function (d) { |
|
return d.diameterKm; |
|
}), 10); |
|
|
|
var histogram = d3.layout.histogram() |
|
.value(function (d) { |
|
return d.diameterKm; |
|
}) |
|
.bins(thresholds); |
|
|
|
var data = histogram(dataset); |
|
|
|
xScale.domain([0, d3.max(thresholds)]); |
|
yScale.domain([0, d3.max(data, function (d) { |
|
return d.length; |
|
})]); |
|
|
|
var svg = d3.select("body") |
|
.append("div").attr(dimensions) |
|
.append("svg").attr(viewBox) |
|
|
|
var defs = svg.append("defs"); |
|
|
|
svg.on("click", function () { |
|
d3.select("body").selectAll("div").remove(); |
|
histograms(datasets) |
|
}); |
|
|
|
svg.append("g") |
|
.attr("id", "x") |
|
.attr("transform", "translate(" + margin.left + "," + height + ")") |
|
.call(xAxis); |
|
|
|
svg.append("g") |
|
.attr("id", "y") |
|
.attr("transform", "translate(" + margin.left + "," + 0 + ")") |
|
.call(yAxis); |
|
|
|
svg.select("#x") |
|
.append("text").attr("class", "scale") |
|
.text("Average diameter (km)") |
|
.attr("transform", "translate(" + width / 2 + "," + (margin.bottom * 1.20) + ")"); |
|
|
|
svg.select("#y") |
|
.append("text").attr("class", "scale") |
|
.text("Number of known objects") |
|
.attr("transform", "rotate (-90, 0, 0) translate(" + -height / 2 + "," + -margin.left * .8 + ")"); |
|
|
|
var entry = svg.selectAll(".bar") |
|
.data(data) |
|
.enter() |
|
.append("g").attr("class", "bar") |
|
.attr("transform", "translate(" + margin.left + "," + 0 + ")") |
|
.on("mouseover", function (d) { |
|
d3.select(this) |
|
.append("text").attr("class", "tooltip") |
|
.text(function (d) { |
|
if (d.length == 1) { |
|
return d.length + " (" + d[0].name + ")"; |
|
} else if (d.length > 0) { |
|
return d.length + " objects between " + d.x + " and " + (d.x + d.dx) + "km"; |
|
} else { |
|
return ""; |
|
} |
|
}) |
|
.attr("x", function (d) { |
|
return xScale(d.x) - margin.right; |
|
}) |
|
.attr("y", function (d) { |
|
return margin.top; |
|
}); |
|
}) |
|
.on("mouseout", function (d) { |
|
d3.select(this) |
|
.select(".tooltip").remove(); |
|
}); |
|
|
|
entry.append("rect") |
|
.attr("x", function (d) { |
|
return xScale(d.x); |
|
}) |
|
.attr("y", function (d) { |
|
return yScale(d.y); |
|
}) |
|
.attr("width", function (d) { |
|
return xScale(data[0].dx) * .9; |
|
}) |
|
.attr("height", function (d) { |
|
return height - yScale(d.y); |
|
}); |
|
|
|
entry.append("text") |
|
.text(function (d) { |
|
if (d.length == 1) { |
|
return d.length + " (" + d[0].name + ")"; |
|
} else if (d.length > 0) { |
|
return d.length; |
|
} else { |
|
return ""; |
|
} |
|
}) |
|
.attr("transform", function (d) { |
|
return "translate(" + xScale(d.x) + "," + (yScale(d.y)) + ") rotate(290,0," + d3.max([-12, -xScale(data[0].dx) / 2]) + ") "; |
|
}) |
|
.style("font-size", function (d) { |
|
return d3.min([12, xScale(data[0].dx) * .5]); |
|
}); |
|
|
|
} |
|
|
|
d3.json("https://raw.githubusercontent.com/helderdarocha/D3Examples/master/PlanetaryData/data/sol_2016.json", function (data) { |
|
histograms(data); |
|
}); |
|
|
|
</script> |
|
</body> |
|
</html> |