Create a gist now

Instantly share code, notes, and snippets.

Densities of worlds with diameter > 900km
height: 900
license: cc-by-sa-4.0

This chart places several planets and moons from our solar system in a chart where the horizontal scale represents the volume, and the vertical scale the density. The radius of each planet represents the diameter. This scale is not proportionally exact.

The chart reveals the extremely low densities of the giant gaseous planets, compared to the other rocky planets. Earth is shown as the densest of the planets, while Saturn has a density which is below the density of water. Move the mouse over each planet/moon to see its name and density.

The data used in this graph was obtained from the public NASA JPL databases in 2010.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Densities of worlds with diameter > 900km</title>
<script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
circle {
opacity: .9;
}
path.domain {
fill: none;
stroke: #999;
}
text, h1 {
color: #ddd;
font-family: sans-serif;
font-size: 16pt;
text-align: center;
}
text {
fill: white;
font-size: 8pt;
font-family: sans-serif;
pointer-events: none;
text-anchor: middle;
}
text.label, text.scale {
font-size: 10pt;
}
line {
stroke: #666;
shape-rendering: crispEdges;
}
body, svg {
background: #444;
}
</style>
</head>
<body>
<h1>Density x Volume of worlds with diameter > 900km</h1>
<script>
var height = 800;
var width = 1000;
var dimensions = {
height: "100%",
width: "100%",
};
var margin = 50;
var viewBox = {
viewBox: "0 0 " + width + " " + height
};
var xScale = d3.scale.log()
.range([margin, width - margin * 2]);
var yScale = d3.scale.linear()
.range([height - margin * 2, margin]);
var dScale = d3.scale.linear()
.range([4, 115]);
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(height - margin * 3)
.orient("top");
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(width - margin * 3)
.orient("right");
var plotCircle = {
"r": function (d) {
return dScale(d.diameterKm);
},
"cx": function (d, i) {
return xScale(d.volume);
},
"cy": function (d) {
return yScale(d.density);
}
};
var colors = function(n) {
var planetColors = ["#ff9900", "coral", "aqua", "cornflowerblue", "#0099c6", "gold", "orange", "coral", "green", "#dc3912"];
return planetColors[n % planetColors.length];
}
var plot = function (data) {
var svg = d3.select("body")
.append("div").attr(dimensions)
.append("svg").attr(viewBox);
var defs = svg.append("defs");
var gradient = defs.selectAll("radialGradient")
.data(data)
.enter()
.append("radialGradient")
.attr("cx", .7).attr("cy", .6).attr("r", .9)
.attr("id", function (d) {
return "gradient-" + d.id.replace(/\./g, "_");
});
gradient.append("stop")
.attr("stop-color", function(d, i) {
return d3.hsl(colors(i)).brighter();
})
.attr("offset", "0%")
gradient.append("stop")
.attr("stop-color", function(d, i) {
return colors(i);
})
.attr("offset", "33%")
.attr("stop-opacity", 1)
gradient.append("stop")
.attr("stop-color", function(d, i) {
return d3.hsl(colors(i)).darker();
})
.attr("offset", "66%")
.attr("stop-opacity", .6)
gradient.append("stop")
.attr("stop-color", function(d, i) {
return d3.hsl(colors(i)).darker().darker();
})
.attr("offset", "100%")
.attr("stop-opacity", .2);
var xExtent = d3.extent(data, function (d) {
return d.volume;
});
var yExtent = d3.extent(data, function (d) {
return d.density;
});
var dExtent = d3.extent(data, function (d) {
return d.diameterKm;
});
xScale.domain([xExtent[0] / 2, xExtent[1] * 20]);
yScale.domain([yExtent[0], yExtent[1] * 1.05]);
dScale.domain(dExtent);
svg.append("g")
.attr("id", "x")
.attr("transform", "translate(0," + (height - margin * 2) + ")")
.call(xAxis);
svg.append("g")
.attr("id", "y")
.attr("transform", "translate(" + (margin) + ",0)")
.call(yAxis);
svg.select("#x")
.append("text").attr("class", "scale")
.text("Volume in km3")
.attr("transform", "translate("+ (width/2) +","+ margin +")");
svg.select("#y")
.append("text").attr("class", "scale")
.text("Density in g/cm3")
.attr("transform", "rotate (-90, 0, 0) translate("+ -(height/2) +","+ -margin/2 +")");
var entries = svg.selectAll(".entry")
.data(data)
.enter()
.append("g")
.attr("class", "entry");
entries.append("circle")
.attr(plotCircle)
.attr("fill", function(d,i) {
return "url(#gradient-" + d.id.replace(/\./g, "_") + ")";
});
entries.on("mouseover", function (d) {
var text = d3.select(this)
.append("text").attr("class", "label")
.attr("id", "label-"+d.id.replace(/\./g, "_"))
.text(function (d) {
return d.name + ((d.planet) ? " (" + d.planet + ")" : "");
})
.attr("transform", function (d, i) {
return "translate("
+ (xScale(d.volume) - 20)
+ ","
+ (yScale(d.density) - 20)
+ ")";
});
text.append("tspan")
.attr("dy", 20)
.attr("x", 0)
.text(function(d) {
return d.density + " g/cm3";
});
svg.node().appendChild(text.node());
})
.on("mouseout", function (d) {
d3.select("#label-"+d.id.replace(/\./g, "_"))
.remove();
});
}
d3.json("https://raw.githubusercontent.com/helderdarocha/D3Examples/master/PlanetaryData/data/sol_2016.json", function (data) {
var planets = d3.merge([data.planets, data.tnos, data.asteroids, data.centaurs]);
var satellites = [];
planets.forEach(function (d) {
if (d.satellites) {
d.satellites.forEach(function (e) {
e["planet"] = d.name;
});
satellites = d3.merge([satellites, d.satellites]);
}
});
var dataset = d3.merge([planets, satellites]).filter(function (d) {
return d.density && d.volume;
}).sort(function (a, b) {
return d3.descending(a.diameterKm, b.diameterKm);
});
console.log(dataset);
plot(dataset);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment