xxxxxxxxxx
<html>
<meta charset="utf-8">
<!-- Example based on https://bl.ocks.org/mbostock/3887118 -->
<!-- Tooltip example from https://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html -->
<link href='https://fonts.googleapis.com/css?family=Codystar:300,400|Ubuntu:300,400,500,700|Tulpen+One|Expletus+Sans:400,600,500,700|Roboto:500,900,100,300,700,400|Oswald:400,300,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://intentive.info/styles/components.css">
<style>
body {
font: 11px sans-serif;
}
.viz{
width:90%;
margin:0 auto;
}
.axis path,
.axis line {
fill: none;
stroke: #B5B5B5;
shape-rendering: crispEdges;
}
.axis text {
font: 13px "Ubuntu";
}
.dot {
stroke: #000;
}
.tooltip {
position: absolute;
pointer-events: none;
background: white;
z-index: 99;
font-size: small;
border-left: 1px solid #D30000;
padding: 1em;
border-radius: 20px;
}
.ui {
float: left;
}
.title {
float: left;
margin-left: 108px;
}
.ui #selector {
height: 3em;
width: 120px;
margin: 1.5em;
}
h2.sub.small {
clear: both;
margin: 0;
padding: 0;
margin-left: 110px;
}
span.numberLabel {
width: 70px;
overflow: inherit;
display: block;
margin-top:-5px;
}
.tooltip div {
float: left;
position: relative;
margin-right:1.5em;
}
.tooltip h5.large.oswald {
margin-top: 15px;
padding-top: 0;
padding-bottom: 0.75em;
line-height: 0px;
}
</style>
<body><script type='text/javascript' id="__bs_script__">//<![CDATA[
document.write("<script async src='/browser-sync/browser-sync-client.1.9.2.js'><\/script>".replace(/HOST/g, location.hostname).replace(/PORT/g, location.port));
//]]></script>
<div class="viz">
<span class="title huge oswald">Countdown to the Singularity</span>
<div class="ui">
<select id="selector" class="form-control">
<option value="Log">Logarithmic</option>
<option value="Linear">Linear</option>
</select>
</div>
<h2 class="sub small">
Chart Countdown to Singularity, Events expressed as Time before Present (Years) on the X axis and Time to Next Event (Years) on the Y axis.
</h2>
</div>
<div class="small ref">
<ul>
<li>
M.T. Rosing, "13C-Depleted carbon microparticles in >3700-Ma sea-floor sedimentary rocks from west greenland," Science 283.5402 (January 29, 1999): 674-6, See also H. Furnes et al., "Early life recorded in archean pillow lavas," Science 304.5670 (April 23, 2004):578-81;
</li>
<li>
M.T. Rosing, "Early Archaean oxygenic photosynthesis - The observational approach," Geophysical Research Abstracts 7.11202 (2005);
</li>
<li>
W. Altermann and J. Kazmierczak, "Archean microfossils: a reappraisal of early life on Earth," Research in Microbiology 154.9 (November 2003): 611-617; and Technical Comments, "Origin and Significance of Archean Quartzose Rocks at Akilia, Greenland," Science 298.5595 (November 1, 2002): 917, https://sciencemag.org/cgi/content/full/298/5595/917a.
</li>
<li>
S.B. Hedges et al., "A molecular timescale of eukaryote evolution and the rise of complex multicellular life," BMC Evolutionary Biology 4:2 (2004), https://www.pubmedcentral.gov/articlerender.fcgi?pubmedid=15005799.
</li>
<li>
J. W. Valentine, D. Jablonski and D. H. Erwin, "Fossils, molecules and embryos: new perspectives on the Cambrian explosion," Development 126.5 (1999): 851-859, https://dev.biologists.org/cgi/reprint/126/5/851.pdf.
</li>
<li>
R. L. Paton, T. R. Smithson and J. A. Clack, "An amniote-like skeleton from the Early Carboniferous of Scotland," Nature 398 (08 April 8, 1999): 508 - 513.
</li>
<li>
Z.X. Luo, A.W. Crompton and A.L. Sun, "A new mammaliaform from the early Jurassic and evolution of mammalian characteristics," Science 292.5521 (May 25, 2001):1535-40.
</li>
<li>
S. Tavare et al., "Using the fossil record to estimate the age of the last common ancestor of extant primates," Nature 416.6882 (April 18, 2002):726-9.
</li>
<li>
C.B. Stewart and T.R. Disotell, "Primate evolution—in and out of Africa," Current Biology 8 (1998):R582–R588.
</li>
<li>
C.J. Cela-Conde and F.J. Ayala, "Genera of the human lineage," PNAS [Proceedings of the National Academy of Sciences of the United States] 100.13(June 24, 2003): 7684-7689, published online June 6, 2003, https://www.pnas.org/cgi/content/full/100/13/7684.
</li>
<li>
M.G. Leakey et al., "New four-million-year-old hominid species from Kanapoi and Allia Bay, Kenya," Nature 376.6541 (August 17, 1995):565-71.
</li>
<li>
B. Wood and M. Collard, "The human genus," Science 284.5411 (April 2, 1999):65-71. See also Human Evolution at the Smithsonian Institution, https://www.mnh.si.edu/anthro/humanorigins/ha/a_tree.html.
</li>
<li>
Y Kimura, "Examining time trends in the Oldowan technology at Beds I and II, Olduvai Gorge," Journal of Human Evolution 43.3 (September 2002):291-321.
</li>
<li>
A.M. MacLarnon and G.P Hewitt, "The evolution of human speech: The role of enhanced breathing control," American Journal of Physical Anthropology 109.3:341-63.
</li>
<li>
Dennis O'Neil, " Evolution of Modern Humans: Early Archaic Homo sapiens," https://anthro.palomar.edu/homo2/mod_homo_1.htm.
</li>
<li>
T.D. White et al., "Pleistocene Homo sapiens from Middle Awash, Ethiopia," Nature 423 (12 June 2003): 742-747. See also The Middle Awash Research Group, "Immediate predecessor of modern humans found in Africa; 160,000 year old Ethiopian fossils are first homo sapiens," June 2003, https://www.berkeley.edu/news/media/releases/2003/06/11_bones-background.shtml.
</li>
<li>
D. Nadel et al., "Stone Age hut in Israel yields world's oldest evidence of bedding," PNAS [Proceedings of the National Academy of Sciences of the United States] 101.17 (April 27, 2004): 6821-6826, published online April 16, 2004, https://intl.pnas.org/cgi/content/full/101/17/6821.
</li>
<li>
O. Soffer, J. N. Adovasio, and D. C. Hyland, "The 'Venus' Figurines: Textiles, Basketry, Gender and Status in the Upper Paleolithic," Current Anthropology 41 (August/October 2000).
</li>
<li>
Dennis O'Neil, " Evolution of Modern Humans: Early Modern Human Culture," https://anthro.palomar.edu/homo2/mod_homo_5.htm.
</li>
<li>
Bar-Yosef, O. 2002, "The Upper Paleolithic revolution," Annual Review of Anthropology 31: 363-393.
</li>
<li>
H. Pringle, "Neolithic Agriculture: The Slow Birth of Agriculture," Science Vol. 282. no. 5393 (November 18, 1998):1446.
</li>
<li>
Cuneiform Digital Library Initiative https://early-cuneiform.humnet.ucla.edu.
</li>
<li>
E. Tunis, Wheels: A Pictorial History (Baltimore, MD: Johns Hopkins University Press, 2002).
</li>
<li>
McGraw-Hill Encyclopedia of Science & Technology, 9th Edition (New York: McGraw-Hill Professional, 2002).
</li>
<li>
Computer History Museum, Timeline, https://www.computerhistory.org/timeline/timeline.php.
</li>
</ul>
</div>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 110},
width = window.innerWidth*0.7 - margin.left - margin.right,
height = window.innerHeight*0.7 - margin.top - margin.bottom;
var superscript = "⁰¹²³⁴⁵⁶⁷⁸⁹",
formatPower = function(d) { return (d + "").split("").map(function(c) { return superscript[c]; }).join(""); };
/*
* value accessor - returns the value to encode for a given data object.
* scale - maps value to a visual display encoding, such as a pixel position.
* map function - maps from data value to display value
* axis - sets up axis
Time before Present,Time to Next Event,Event,
*/
// setup x
var xValue = function(d) { return d["Time before Present"];}, // data -> value
xScale = d3.scale.log().range([width,0]), // value -> display
xMap = function(d) { return xScale(xValue(d));}, // data -> display
xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(10,function(d){ return 10 + formatPower(Math.round(Math.log(d)/Math.LN10)); });
// setup y
var yValue = function(d) { return d["Time to Next Event"];}, // data -> value
yScale = d3.scale.log().range([height, 0]), // value -> display
yMap = function(d) { return yScale(yValue(d));}, // data -> display
yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(10,function(d){ return 10 + formatPower(Math.round(Math.log(d)/Math.LN10)); });
// setup fill color
var cValue = function(d) { return "ONE";},
color = d3.scale.category10();
// add the graph canvas to the body of the webpage
var svg = d3.select(".viz").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// add the tooltip area to the webpage
var tooltip = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// load data
d3.csv("data.csv", function(error, data) {
// change string (from CSV) into number format
data.forEach(function(d) {
d["Event"] = d["Event"];
d["Time before Present"] = +d["Time before Present"];
d["Time to Next Event"] = +d["Time to Next Event"];
// console.log(d);
});
var index = "";
d3.select("#selector").property("selectedIndex", index)
.on("change", function(d) {
index = this.value
update();
})
// don't want dots overlapping axis, so add in buffer to data domain
xScale.domain([d3.min(data, xValue)-5, d3.max(data, xValue)+5]);
yScale.domain([d3.min(data, yValue)-5, d3.max(data, yValue)+5]);
// x-axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label ubuntu")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Time before Present");
// y-axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label ubuntu")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Time to Next Event");
// draw dots
svg.selectAll(".dot")
.data(data)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("cx", xMap)
.attr("cy", yMap)
.style("stroke-width",0)
// .style("fill", function(d) { return color(cValue(d));})
.style("fill", function(d) { return "#D30000";})
.on("mouseover", function(d) {
var target = d3.select(this);
target.transition()
.duration(750)
.attr("r", function(){ return 10; });
tooltip.transition().delay(500)
.duration(200)
.style("opacity", .9);
tooltip.html("<h5 class='large oswald'>"+d["Event"]+"</h5>" + "<div><span class='huge tulpen'>" + commaSeparateNumber(yValue(d))
+ "</span><span class='numberLabel ubuntu'>Years until next event</span></div><div> <span class='huge tulpen'>" + commaSeparateNumber(xValue(d)) + "</span><span class='numberLabel ubuntu'>Years ago</span></div>")
.style("left", (d3.event.pageX + 5) + "px")
.style("top", (d3.event.pageY - 40) + "px");
})
.on("mouseout", function(d) {
var target = d3.select(this);
target.transition()
.duration(750)
.attr("r", function(){ return 5; });
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
function update(){
switch(index){
case "Linear":
xScale = d3.scale.linear().range([width,0]); // value -> display
yScale = d3.scale.linear().range([height, 0]); // value -> display
xAxis = d3.svg.axis().scale(xScale).orient("bottom");
yAxis = d3.svg.axis().scale(yScale).orient("left");
break;
case "Log":
xScale = d3.scale.log().range([width,0]); // value -> display
yScale = d3.scale.log().range([height, 0]); // value -> display
xAxis = d3.svg.axis().scale(xScale).orient("bottom").ticks(10,function(d){ return 10 + formatPower(Math.round(Math.log(d)/Math.LN10)); });
yAxis = d3.svg.axis().scale(yScale).orient("left").ticks(10,function(d){ return 10 + formatPower(Math.round(Math.log(d)/Math.LN10)); });
break;
default:
xScale = d3.scale.linear().range([width,0]); // value -> display
yScale = d3.scale.linear().range([height, 0]); // value -> display
break;
}
;
var dots = svg.selectAll(".dot");
// dots.exit().remove();
// draw dots
// update the scales
xScale.domain([d3.min(data, xValue)-1, d3.max(data, xValue)+1]);
yScale.domain([d3.min(data, yValue)-1, d3.max(data, yValue)+1]);
d3.selectAll(".x.axis")
.transition().delay(40).ease('quad').duration(500)
.call(xAxis);
/*
xAx.selectAll(".tick text")
.text(null)
.filter(powerOfTen)
.text(10);
xAx.selectAll(".tick text")
.append("tspan")
.attr("dy", "-.7em")
.text(function(d) { return Math.round(Math.log(d) / Math.LN10); });
.append("tspan")
.attr("dy", "-.7em")
.text(function(d) { return Math.round(Math.log(d) / Math.LN10); });
*/
d3.selectAll(".y.axis")
.transition().delay(40).ease('cubic').duration(500)
.call(yAxis);
dots.transition()
.delay(function (d,i){ return 500 + (i * 30);}).ease('quad').duration(500)
.attr("cx", xMap)
.attr("cy", yMap)
.style("fill", function(d) { return "#D30000" /*color(cValue(d))*/;})
.style("opacity", 0.7)
.attr("stroke-width", 0)
}
});
function commaSeparateNumber(val){
while (/(\d+)(\d{3})/.test(val.toString())){
val = val.toString().replace(/(\d+)(\d{3})/, '$1'+','+'$2');
}
return val;
}
function powerOfTen(d) {
return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1;
}
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js