Skip to content

Instantly share code, notes, and snippets.

@helderdarocha
Last active May 30, 2016 02:35
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 helderdarocha/fe4e3e5ff7422f953d001e97ef0b4ad5 to your computer and use it in GitHub Desktop.
Save helderdarocha/fe4e3e5ff7422f953d001e97ef0b4ad5 to your computer and use it in GitHub Desktop.
Histogram: diameters of asteroids
height: 650
license: cc-by-sa-4.0

There are two stacked histograms in this graph. The first groups asteroids from the main belt by their diameters. Click anywhere in the graph and the histogram will show diameters from the Kuiper belt.

These graphs are based on data obtained from the NASA JPL databases in 2010 (limited to a certain minimum diameter, for each belt).

<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment