D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
kcsluis
Full window
Github gist
Moons of the Solar System
<!DOCTYPE html> <meta charset="utf-8"> <head> <link href='https://fonts.googleapis.com/css?family=Quicksand:300' rel='stylesheet' type='text/css'> </head> <style> body { background: #111; } input[type=range] { /*removes default webkit styles*/ -webkit-appearance: none; /*fix for FF unable to apply focus style bug */ /*border: 1px solid white;*/ /*required for proper track sizing in FF*/ width: 200px; } input[type=range]::-webkit-slider-runnable-track { width: 200px; height: 3px; background: #888; border: none; border-radius: 3px; } input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; border: none; height: 12px; width: 12px; border-radius: 50%; background: white; margin-top: -4px; } input[type=range]:focus { outline: none; } input[type=range]:focus::-webkit-slider-runnable-track { background: #ccc; } input[type=range]::-moz-range-track { width: 200px; height: 3px; background: #888; border: none; border-radius: 3px; } input[type=range]::-moz-range-thumb { border: none; height: 12px; width: 12px; border-radius: 50%; background: white; } /*hide the outline behind the border*/ input[type=range]:-moz-focusring{ /*outline: 1px solid white;*/ outline-offset: -1px; } input[type=range]::-ms-track { width: 200px; height: 3px; /*remove bg colour from the track, we'll use ms-fill-lower and ms-fill-upper instead */ background: transparent; /*leave room for the larger thumb to overflow with a transparent border */ border-color: transparent; border-width: 6px 0; /*remove default tick marks*/ color: transparent; } input[type=range]::-ms-fill-lower { background: #777; border-radius: 10px; } input[type=range]::-ms-fill-upper { background: #ddd; border-radius: 10px; } input[type=range]::-ms-thumb { border: none; height: 12px; width: 12px; border-radius: 50%; background: white; } input[type=range]:focus::-ms-fill-lower { background: #888; } input[type=range]:focus::-ms-fill-upper { background: #ccc; } .system { display: block; position: relative; margin: 60px auto; vertical-align: middle; } .orbit { fill: none; stroke: #888; stroke-dasharray: 3,5; } .planet { position: absolute; top: 0; left: 0; -moz-animation-name: rotate; -moz-animation-iteration-count: infinite; -moz-animation-timing-function: linear; -webkit-animation-name: rotate; -webkit-animation-iteration-count: infinite; -webkit-animation-timing-function: linear; animation-name: rotate; animation-iteration-count: infinite; animation-timing-function: linear; } .reverse { -moz-animation-name: rotateBack; -webkit-animation-name: rotateBack; animation-name: rotateBack; } @-moz-keyframes rotate { from { -moz-transform: rotateZ(0deg); } to { -moz-transform: rotateZ(-360deg); } } @-webkit-keyframes rotate { from { -webkit-transform: rotateZ(0deg); } to { -webkit-transform: rotateZ(-360deg); } } @keyframes rotate { from { transform: rotateZ(0deg); } to { transform: rotateZ(-360deg); } } @-moz-keyframes rotateBack { from { -moz-transform: rotateZ(-360deg); } to { -moz-transform: rotateZ(0deg); } } @-webkit-keyframes rotateBack { from { -webkit-transform: rotateZ(-360deg); } to { -webkit-transform: rotateZ(0deg); } } @keyframes rotateBack { from { transform: rotateZ(-360deg); } to { transform: rotateZ(0deg); } } .thePlanet { fill: #fff; } .moonName { fill: #fff; font-size: 7px; text-transform: uppercase; font-family: sans-serif; } .moonLine { fill: none; stroke: #444; stroke-width: 0.5px; } .mPlanetCircle { fill: #aaa; stroke: #444; } .saturnRings { fill: #444; } .saturnRingsInner { fill: #111; } .mPlanetName { color: #fff; font-size: 28px; text-transform: uppercase; font-family: 'Quicksand', sans-serif; } .moonComp { fill: none; stroke: #fff; } .intro { margin: 160px auto; } h1 { color: #fff; text-align: center; font-family: 'Quicksand', sans-serif; font-size: 144px; margin-bottom: -24px; } h2 { color: #888; text-align: center; font-family: 'Quicksand', sans-serif; font-size: 18px; } h3 { color: #fff; text-align: center; font-family: 'Quicksand', sans-serif; font-size: 48px; margin-bottom: 24px; text-transform: uppercase; } p { color: #ddd; text-align: center; font-family: sans-serif; font-size: 11px; letter-spacing: 1.1px; line-height: 2; text-transform: uppercase; } p a { color: #ddd; } p a:hover { color: #fff; } p a:visited { color: #ddd; } .intro_copy { max-width: 540px; margin: 0px auto; margin-top: 80px; } .controls { position: fixed; width: 200px; right: 27px; bottom: 90px; z-index: 10000; } .controlBackground { position: fixed; right: 0px; bottom: 0px; height: 150px; width: 250px; z-index: 5000; background-color: rgba(17,17,17,0.8); } .slider { position: fixed; width: 200px; right: 25px; z-index: 10000; } .slider:hover { cursor: pointer; } .control_label { color: #fff; font-family: sans-serif; font-size: 9px; } .cl0 { position: relative; top: 4px; } .cl1 { position: relative; top: 10px; } .cl2 { position: relative; top: 41px; } .planetLabel { margin-left: 12.5%; position: relative; z-index: 1000; } .head_label { font-family: 'Quicksand', sans-serif; font-size: 12px; text-transform: uppercase; margin-top: 10px; } .moonProfiles { color: #fff; text-align: center; font-family: sans-serif; font-size: 12px; } .moonProfile { margin: 60px auto; } .moonTitle { font-family: 'Quicksand', sans-serif; font-size: 28px; text-transform: uppercase; position: absolute; } .moonDetails { position: absolute; text-transform: uppercase; font-size: 9px; color: #888; } .profileSVG { /*fill: none;*/ fill: url(#diagonal-stripe-6); stroke: #fff; stroke-width: 3px; } .moonShadow { fill: #111; stroke: none; opacity: 0.5; } .middle_text { margin-top: 80px; margin-bottom: 140px; } </style> <body> <div class="starryNight"></div> <svg class="svg_pattern" height="10" width="10" xmlns="https://www.w3.org/2000/svg" version="1.1"> <defs> <pattern id="diagonal-stripe-6" patternUnits="userSpaceOnUse" width="10" height="10"> <image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSdibGFjaycvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J3doaXRlJyBzdHJva2Utd2lkdGg9JzEnLz4KPC9zdmc+" x="0" y="0" width="10" height="10"> </image> </pattern> </defs> </svg> <div class="intro"> <h1>MOONS</h1> <h2>of the Solar System</h2> <div class="intro_copy"> <p>Orbits of all round-bodied moons of the solar system</p> </div> </div> <div class="controlBackground"></div> <div class="controls"> <div class="control_label head_label">Orbit Scales</div> <div class="control_label cl0">Planet Diameter: 1 pixel = 6000 km</div> <div class="control_label cntrlRadius cl1">Moon Radius</div> <input class="slider" style="bottom: 70px;" type="range" min="0.08333" max="8" step="0.1" id="moonRadius" > <div class="control_label cntrlSpeed cl2">Rotation Speed</div> <input class="slider" style="bottom: 30px;" type="range" min="0.1" max="5" step="0.1" id="moonSpeed" > </div> <div class="planetSystems"> <div class="system Earth"></div> <div class="system Jupiter"></div> <div class="system Saturn"></div> <div class="system Uranus"></div> <div class="system Neptune"></div> </div> <div class="moonProfiles"> <p class="middle_text">All moons, together</p> <div class="profilesEarth"></div> <div class="profilesJupiter"></div> <div class="profilesSaturn"></div> <div class="profilesUranus"></div> <div class="profilesNeptune"></div> </div> <p class="middle_text">Curious? <a href="https://en.wikipedia.org/wiki/List_of_natural_satellites">Learn more on Wikipedia</a></p> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script> function getWidth() { if (self.innerHeight) { return self.innerWidth; }; if (document.documentElement && document.documentElement.clientHeight) { return document.documentElement.clientWidth; }; if (document.body) { return document.body.clientWidth; }; }; var browserWidth = getWidth(); var topRange = browserWidth/20; // Scales for semimajor axis, planet radius, and planet period. var x = d3.scale.linear().range([0, topRange]), r = d3.scale.linear().domain([0.3, 5.2]).range([0,10]), mr = d3.scale.linear().domain([0, 1400]).range([0,120]), c = d3.scale.linear().domain([0.1, 6]).range([1,60]), t = d3.scale.linear().range([0, 3]); // Detect the appropriate vendor prefix. var prefix = "-webkit-transform" in document.body.style ? "-webkit-" : "-moz-transform" in document.body.style ? "-moz-" : ""; d3.csv('solarsystem.csv', function(error, mPlanets) { mPlanets.forEach( function (d) { if (d.mPlanetMoons === 'x'){ //no moons } else { //moons var csv = d.mPlanetMoons; var mPlanetName = d.mPlanetName; // LOOPS THROUGH EACH SEPARATE CSV FOR MOONS (TODO: REFACTOR INTO ONE SHEET) d3.csv(csv + '.csv', type, function(error, planets) { var numMoons = planets.length; var maxRadius = x(planets[numMoons-1].semimajor_axis); var width = browserWidth-16; var moonWidth = maxRadius*2; var height = maxRadius*2+40; // MOON PROFILES var moonProfileScale = 40; var uniqueProfileName = 'div.profiles' + mPlanetName; var profileSection = d3.select(uniqueProfileName).selectAll('div.moonProfile') .data(planets) .enter() .append('div') .attr('class', function (d) { return d.planet_name + 'Profile moonProfile'; }); profileSection.append('div') .attr('class', 'moonTitle') .text( function (d) { return d.planet_name; }) .style('left', (width*0.75+6) + 'px') .style('margin-top', function (d) { return (d.planet_radius*moonProfileScale-16) + 'px'; }); profileSection.append('div') .attr('class', 'moonDetails') .style('left', (width*0.75+6) + 'px') .style('margin-top', function (d) { return (d.planet_radius*moonProfileScale+20) + 'px'; }) .text( function (d) { return "Diameter: " + d.planet_radius*1000 + " km"; }); profileSection.append('div') .attr('class', 'moonDetails') .style('left', (width*0.75+6) + 'px') .style('margin-top', function (d) { return (d.planet_radius*moonProfileScale+32) + 'px'; }) .text( function (d) { return "Period: " + Math.abs(d.period.toFixed(1)) + " days"; }); var moonProfileSVG = profileSection.append('svg') .attr('class', 'profileSVG') .attr('height', function (d) { return d.planet_radius*moonProfileScale*2+4; }) .attr('width', function (d) { return d.planet_radius*moonProfileScale*2+4; }); moonProfileSVG.append('circle') .attr("class", function (d) { return "moonProfileSVG " + d.planet_name; }) .attr('r', function (d) { return d.planet_radius*moonProfileScale; }) .attr('cx', function (d) { return d.planet_radius*moonProfileScale+2; }) .attr('cy', function (d) { return d.planet_radius*moonProfileScale+2; }); moonProfileSVG.append('rect') .attr('class', 'moonShadow') .attr('y', function (d) { return (d.planet_radius*moonProfileScale*2+4)/2; }) .attr('x', 0) .attr('height', function (d) { return (d.planet_radius*moonProfileScale*2+4)/2; }) .attr('width', function (d) { return d.planet_radius*moonProfileScale*2+4; }); // PRIMARY ORBIT VIS d3.select("div." + mPlanetName) .style("width", width + "px") .style("height", height+40 + "px"); var planet = d3.select('div.' + mPlanetName).selectAll(".planet") .data(planets.sort(function(a, b) { return b.planet_radius - a.planet_radius; })) .enter(); var moons = planet.append("svg") .attr("class", function (d) { if (d.period > 0) { return "planet"; } else { return "planet reverse"; }; }) .attr("width", width) .attr("height", height) .style(prefix + "animation-duration", function(d) { return t(Math.abs(d.period)) + "s";}) .style(prefix + "transform-origin", width / 2 + "px " + height / 2 + "px"); moons.append('circle') .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .attr('class', 'orbit') .attr('cx', 0) .attr('cy', 0) .attr("r", function(d) { return x(d.semimajor_axis); }); moons.append("circle") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .attr("cx", function(d) { return x(d.semimajor_axis); }) .attr("r", function(d) { return r(d.planet_radius); }) .attr('class', 'thePlanet'); var NC = d3.select('div.' + mPlanetName).append('svg').attr('class','nameContainer') .style("width", width + "px") .style("height", height + "px"); var NCS = NC.selectAll('svg.nameContainer') .data(planets) .enter(); NCS.append('text') .attr('class', 'moonName') .attr('dx', width*0.75+6) .attr('dy', function (d) { return -x(d.semimajor_axis)+3; }) .attr("transform", "translate(0," + height/2 + ")") .text(function (d) { return d.planet_name; }); NCS.append('line') .attr("transform", "translate(0," + height/2 + ")") .attr('class', 'moonLine') .attr('x1', width*0.5) .attr('x2', width*0.75) .attr('y1', function (d) { return -x(d.semimajor_axis); }) .attr('y2', function (d) { return -x(d.semimajor_axis); }); if (csv === 'saturn_moons') { NCS.append('circle') .attr('class', 'saturnRings') .attr('r', mr(241)) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); NCS.append('circle') .attr('class', 'saturnRingsInner') .attr('r', mr(150)) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); }; NCS.append('circle') .attr('class', 'mPlanetCircle') .attr('r', mr(d.mPlanetRadius)) .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var thisPlanetName = d3.select("." + mPlanetName) .append('div') .style('top', (-(height/2+20)) + "px") .attr('class', 'planetLabel'); thisPlanetName.append('div') .attr('class', 'mPlanetName') .text(mPlanetName); // controls for radius d3.select("#moonRadius").on("input", function() { moonRadius(+this.value); }); moonRadius(4); // update the elements function moonRadius(moonRadius) { d3.select("#moonRadius-value").text(moonRadius); d3.select("#moonRadius").property("value", moonRadius); r = d3.scale.linear().range([1,moonRadius]); d3.selectAll('circle.thePlanet') .attr("r", function(d) { return r(d.planet_radius); }); d3.select('.cntrlRadius') .text("Moon Diameter : 1 pixel = " + (500/moonRadius).toFixed(0) + " km"); }; // controls for speed d3.select("#moonSpeed").on("input", function() { moonSpeed(+this.value); }); moonSpeed(2.5); // update the elements function moonSpeed(moonSpeed) { d3.select("#moonSpeed-value").text(moonSpeed); d3.select("#moonSpeed").property("value", moonSpeed); t = d3.scale.linear().range([0, moonSpeed]); d3.selectAll('svg.planet') .style(prefix + "animation-duration", function(d) { return t(Math.abs(d.period)) + "s";}) d3.select('.cntrlSpeed') .text("Rotation Speed : 1 sec = " + moonSpeed.toFixed(1) + " days"); }; }); function type(d) { d.period = +d.period; d.planet_radius = +d.planet_radius; d.semimajor_axis = +d.semimajor_axis; return d; }; }; }); }); </script>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js