Skip to content

Instantly share code, notes, and snippets.

@Thanaporn-sk
Created January 13, 2020 05:01
Show Gist options
  • Save Thanaporn-sk/99f72a4af8f0b64c8fbca1ec6f90d4c3 to your computer and use it in GitHub Desktop.
Save Thanaporn-sk/99f72a4af8f0b64c8fbca1ec6f90d4c3 to your computer and use it in GitHub Desktop.
Geological Timescale v4
license: mit

geo-timescale

geo-timescale on GitHub

A modular D3.js-based geologic time scale that utilizes data from the Paleobiology Database.

To use, simply include timescale.js and timescale.css in your HTML document, and initialize into the div of your choice with timescale.init("id-of-div").

D3 v5 version

Transtition animations are now concurrent. Unfortunately because the way the new d3.hierarchy partition function works, "interval_hash" no longer works the same way as in the previous version.

Funding

Development supported by NSF EAR-0949416.

forked from JulesBlm's block: Geological Timescale v4

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.timescale {
font-family: Helvetica, sans-serif;
font-weight: 100;
font-size: 0.8em;
color:#333;
cursor: pointer;
}
rect {
stroke: #fff;
stroke-width:1px;
}
.abbr {
display:none;
}
#l0 {
fill:#fff !important;
}
line {
stroke:#777;
}
.level1 {
font-size: 1em;
}
.level2 {
font-size: 0.9em;
}
.level3 {
font-size: 0.75em;
}
.level4 {
font-size: 0.65em;
}
.level5 {
font-size: 0.6em;
}
</style>
<body>
<div id="geoTime"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script type="text/javascript">
/*
TODO
FIX HASH, accesable from external
Time ticks for level 4 periods when zoomed to level 3
concurrent transitions
*/
// Via http://stackoverflow.com/questions/14167863/how-can-i-bring-a-circle-to-the-front-with-d3
// Necessary for highlighting time intervals properly
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
// Via https://stackoverflow.com/questions/38224875/replacing-d3-transform-in-d3-v4
function getTranslation(transform) {
// Create a dummy g for calculation purposes only. This will never
// be appended to the DOM and will be discarded once this function
// returns.
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
// Set the transform attribute to the provided string value.
g.setAttributeNS(null, "transform", transform);
// consolidate the SVGTransformList containing all transformations
// to a single SVGTransform of type SVG_TRANSFORM_MATRIX and get
// its SVGMatrix.
const matrix = g.transform.baseVal.consolidate().matrix;
// As per definition values e and f are the ones for the translation.
return [matrix.e, matrix.f];
}
const timescale = (function() {
const width = 960;
const height = 130;
// Initialize data
const data = { oid: 0, nam: "Geologic Time", children: [] };
const interval_hash = { 0: data };
let currentInterval;
let dragStart;
let transformStart;
return {
"init": function(div) {
let newX = 0.01;
const drag = d3.drag()
.subject(function() {
// const t = d3.select(".timescale g");
return {x: newX, y: 0};
})
.on("start", function() {
dragStart = event.pageX;
transformStart = getTranslation(d3.select(".timescale").select("g").attr("transform"));
d3.event.sourceEvent.stopPropagation();
})
.on("drag", function() {
currentDrag = event.pageX;
newX = (dragStart - currentDrag);
d3.select(".timescale").select("g")
.attr("transform", function() {
return `translate(${[ parseInt(transformStart[0] + -newX), 0 ]}) scale(${parseInt(d3.select(".timescale").style("width"))/961})`;
});
});
// Add class timescale to whatever div was supplied
d3.select("#" + div).attr("class", "timescale");
// Create the SVG for the chart
const time = d3.select("#" + div).append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
// Move whole tick SVG group down 125px
const scale = time.append("g")
.attr("id", "tickBar")
.attr("transform", "translate(0,125)");
// Create a new d3 partition layout
const partition = d3.partition()
.size([width, height])
.padding(0);
// Load the time scale data
d3.json("intervals.json").then(function(result) {
// Construct hierarchy into '' by oid's from paleoJSON
result.records.forEach(i => {
const result = i;
result.children = [];
result.pid = result.pid || 0; // Check if result is not a highest level period
result.abr = result.abr || result.nam.charAt(0);
result.mid = parseInt((result.eag + result.lag) / 2); //length of period
result.total = result.eag - result.lag;
interval_hash[result.oid] = result;
interval_hash[result.pid].children.push(result);
})
const root = d3.hierarchy(data)
.sum(d => (d.children.length === 0) ? d.total + 0.117 : 0 ); //? add time for Holocene
partition(root);
const rectGroup = time.append("g")
.attr("id", "rectGroup");
// Create the rectangles
rectGroup.selectAll("rect")
.data( root.descendants() )
.enter().append("rect")
.attr("x", function(d) { return d.x0; })
.attr("y", function(d) { return d.y0; })
.attr("width", function(d) { return d.x1 - d.x0; })
.attr("height", function(d) { return d.y1 - d.y0; })
.attr("fill", function(d) { return d.data.col || "#000"; })
.attr("id", function(d) { return "t" + d.data.oid; })
.style("opacity", 0.83)
.call(drag)
.on("click", function(d) { timescale.goTo(d); });
// Scale bar for the bottom of the graph
const scaleBar = scale.selectAll("rect")
.data(root.descendants());
const hash = scaleBar.enter().append("g")
.attr("class", function(d) { return "tickGroup s" + d.data.lvl})
.attr("transform", function(d) { return `translate(${d.x0}, 0)`});
hash.append("line")
.attr("x1", 0)
.attr("y1", 7.5)
.attr("x2", 0)
.attr("y2", 12)
.style("stroke-width", "0.05em");
hash.append("text")
.attr("x", 0)
.attr("y", 20)
.style("text-anchor", function(d) { return (d.data.eag !== 0.0117) ? "middle" : "end"; })
.style("font-size", "0.65em")
.style("fill", "#000")
.text(function(d) { return d.data.eag; });
// Create a tick for year 0
const now = scale.append("g")
.data([{x0: width, y0: 0 }])
.attr("class", "tickGroup s1 s2 s3 s4 s5")
.attr("transform","translate(960, 0)");
now.append("line")
.attr("x1", 0)
.attr("y1", 7.5)
.attr("x2", 0)
.attr("y2", 12)
.style("stroke-width", "0.05em");
now.append("text")
.attr("x", 0)
.attr("y", 20)
.attr("id", "now")
.style("fill", "white")
.style("text-anchor", "end")
.style("font-size", "0.65em")
.style("fill", "#777")
.text("0");
const textGroup = time.append("g")
.attr("id", "textGroup");
// Add the full labels
textGroup.selectAll("fullName")
.data( root.descendants() )
.enter().append("text")
.text(function(d) { return d.data.nam; })
.attr("x", 1)
.attr("y", function(d) { return d.y0 + 15;})
.attr("width", function() { return this.getComputedTextLength(); })
.attr("height", function(d) { return d.y1 - d.y0; })
.attr("class", function(d) { return "fullName level" + d.data.lvl; })
.attr("id", function(d) { return "l" + d.data.oid; })
.attr("x", function(d) { return timescale.labelX(d); })
.on("click", function(d) { timescale.goTo(d); });
// Add the abbreviations
textGroup.selectAll("abbrevs")
.data( root.descendants() )
.enter().append("text")
.attr("x", 1)
.attr("y", function(d) { return d.y0 + 15; })
.attr("width", 30)
.attr("height", function(d) { return d.y1 - d.y0; })
.text(function(d) { return d.data.abr; }) //charAt(0)
.attr("class", function(d) { return "abbr level" + d.data.lvl; })
.attr("id", function(d) { return "a" + d.data.oid; })
.attr("x", function(d) { return timescale.labelAbbrX(d); })
.on("click", function(d) { timescale.goTo(d); });
// Position the labels for the first time
timescale.goTo(root);
// console.log(root)
// Remove the Geologic time abbreviation
d3.select(".abbr.levelundefined").remove();
// Open to Phanerozoic
// timescale.goTo(root.children[2]);
}); // End PaleoDB json callback
//attach window resize listener to the window
d3.select(window).on("resize", timescale.resize);
// Size time scale to window
timescale.resize();
},
// Calculates x-position for label abbreviations
"labelAbbrX": function(d) {
// const rectWidth = d.x1 - d.x0;
// rectX = d.x0;
var rectWidth = parseFloat(d3.select("#t" + d.data.oid).attr("width")),
rectX = parseFloat(d3.select("#t" + d.data.oid).attr("x"));
let labelWidth = d3.select("#a" + d.data.oid).node().getComputedTextLength();
if (rectWidth - 8 < labelWidth) {
d3.select("#a" + d.data.oid).style("display", "none");
}
return rectX + (rectWidth - labelWidth) / 2;
},
"labelX": function(d) {
const rectWidth = d.x1 - d.x0;
rectX = d.x0;
let labelWidth;
try {
labelWidth = d3.select("#l" + d.data.oid).node().getComputedTextLength();
} catch(err) {
labelWidth = 25;
}
// Hide full names if they are too small for their rectangles
if (rectWidth - 10 < labelWidth) {
d3.select("#l" + d.data.oid).style("display", "none");
} else {
d3.select("#a" + d.data.oid).style("display", "none");
}
return rectX + (rectWidth - labelWidth) / 2;
},
// Zooms the graph to a given time interval
// Accepts a data point or a named interval
"goTo": function(d) {
// console.group("goTo", d);
if (typeof d == "string") {
let d = d3.selectAll('rect').filter(e => e.nam === d );
d = d[0][0].__data__;
} else if (d.children) {
// console.log("clicked node has children!")
if (d.children.length < 1) {
const d = d.data.parent;
}
} else {
// console.log("clicked node has NO children!")
// let d = d;
}
// console.groupEnd()
// Stores the currently focused time interval for state restoration purposes
timescale.currentInterval = d;
d3.selectAll(".fullName")
.style("display", "block");
d3.selectAll(".abbr")
.style("display", "block");
// Adjust the bottom scale
const depth = (d.depth !== 'undefined') ? parseInt(d.depth) + 1 : 1;
d3.selectAll(".scale").style("display", "none");
d3.selectAll(".tickGroup").style("display", "none");
d3.selectAll(".s" + depth).style("display", "block");
const x = d3.scaleLinear()
.range([5, width])
.domain([d.x0, d.x1]);
// Define transition for concurrent animation
const t = d3.transition()
.duration(300)
.ease(d3.easeLinear);
// Transition the rectangles
d3.selectAll("rect").transition(t)
.attr("x", function(d) { return x(d.x0); })
.attr("width", function(d) { return x(d.x1) - x(d.x0); })
// Transition tick groups
d3.selectAll(".tickGroup").transition(t)
.attr("transform", function(d) {
d3.select(this).selectAll("text").style("text-anchor", "middle");
if (x(d.x0) === 5) {
d3.select(this).select("text")
.style("text-anchor", "start");
} else if (d.x0 === width) {
d3.select(this).select("text")
.style("text-anchor", "end");
}
if (typeof x(d.x0) === 'number') {return `translate(${x(d.x0)}, 0)`}
});
// Move the full names, to keep animation concurrent labelX has to be calculated inside to goTo function
d3.selectAll(".fullName").transition(t)
.attr("x", function(d) {
const rectWidth = x(d.x1) - x(d.x0),
rectX = x(d.x0);
let labelWidth;
try {
labelWidth = d3.select("#l" + d.data.oid).node().getComputedTextLength(); //this?
} catch(err) {
labelWidth = 25;
}
if (rectWidth - 8 < labelWidth) {
d3.select("#l" + d.data.oid).style("display", "none");
} else {
d3.select("#a" + d.data.oid).style("display", "none");
}
return rectX + (rectWidth - labelWidth) / 2;
})
.attr("height", function(d) { return d.y1 - d.y0; })
//Move the abbreviations
d3.selectAll(".abbr").transition(t)
.attr("x", function(d) {
const rectWidth = x(d.x1) - x(d.x0),
rectX = x(d.x0);
let abbrevWidth = d3.select("#a" + d.data.oid).node().getComputedTextLength();
if (rectWidth - 8 < abbrevWidth) {
d3.select("#a" + d.data.oid).style("display", "none");
}
return rectX + (rectWidth - abbrevWidth) / 2;
})
.attr("height", function(d) { return d.y1 - d.y0; })
.on("end", function() {
d3.selectAll(".fullName").style("fill", "#333");
d3.selectAll(".abbr").style("fill", "#333");
});
// Center whichever interval was clicked
d3.select("#l" + d.data.oid).transition(t)
.attr("x", 430);
// Position all the parent labels in the middle of the scale
if (d.parent !== null) {
const depth = d.depth;
let loc = "d.parent";
for (let i=0; i < depth; i++) {
const parent = eval(loc).data.nam;
d3.selectAll('.abbr').filter(d => d.data.nam === parent ).transition(t)
.attr("x", 430);
d3.selectAll('.fullName').filter(d => d.data.nam === parent ).transition(t)
.attr("x", 430);
loc += ".parent";
}
d3.selectAll('.abbr').filter(d => d.data.nam === parent).transition(t)
.attr("x", 430);
d3.selectAll('.fullName').filter(d => d.data.nam === parent).transition(t)
.attr("x", 430);
}
timescale.resize();
},
// Highlight a given time interval
// "highlight": function(d) {
// d3.selectAll("rect").style("stroke", "#fff");
// if (d.cxi) {
// let id = d.cxi;
// d3.selectAll("rect#t" + d.cxi).style("stroke", "#000").moveToFront();
// d3.selectAll("#l" + d.cxi).moveToFront();
// } else if (typeof d == "string") {
// let id = d3.selectAll('rect').filter(function(e) {
// return e.nam === d;
// }).attr("id");
// id = id.replace("t", "");
// } else {
// let id = d3.select(d).attr("id");
// id = id.replace("p", "");
// }
// d3.selectAll(`rect#t"${id}`).style("stroke", "#000").moveToFront();
// d3.selectAll("#l" + id).moveToFront();
// d3.selectAll(".abbr").moveToFront();
// },
// Unhighlight a time interval by resetting the stroke of all rectangles
"unhighlight": function() {
d3.selectAll("rect").style("stroke", "#fff");
},
"resize": function() {
d3.select(".timescale g")
.attr("transform", function() {
return `scale(${parseInt(d3.select(".timescale").style("width"))/961})`;
});
d3.select(".timescale svg")
.style("width", function() { return d3.select(".timescale").style("width"); })
.style("height", function() { return parseInt(d3.select(".timescale").style("width")) * 0.25 + "px"; });
}
/* Interval hash can be exposed publically so that the time scale data can be used
for other things, such as maps */
// https://github.com/d3/d3-hierarchy/issues/58
// "interval_hash": interval_hash,
// Method for getting the currently zoomed-to interval - useful for preserving states
// "currentInterval": currentInterval
}
})();
timescale.init("geoTime");
</script>
{
"records": [
{"oid":753,"typ":"int","nam":"Archean","lvl":1,"pid":0,"col":"#F0047F","lag":2500,"eag":4000,"rid":[15443]},
{"oid":752,"typ":"int","nam":"Proterozoic","lvl":1,"pid":0,"col":"#F73563","lag":541,"eag":2500,"rid":[47900]},
{"oid":751,"typ":"int","nam":"Phanerozoic","lvl":1,"pid":0,"col":"#9AD9DD","lag":0,"eag":541,"rid":[47900]},
{"oid":760,"typ":"int","nam":"Eoarchean","lvl":2,"pid":753,"col":"#DA037F","lag":3600,"eag":4000,"rid":[15443]},
{"oid":759,"typ":"int","nam":"Paleoarchean","lvl":2,"pid":753,"col":"#F444A9","lag":3200,"eag":3600,"rid":[15443]},
{"oid":758,"typ":"int","nam":"Mesoarchean","lvl":2,"pid":753,"col":"#F768A9","lag":2800,"eag":3200,"rid":[15443]},
{"oid":757,"typ":"int","nam":"Neoarchean","lvl":2,"pid":753,"col":"#F99BC1","lag":2500,"eag":2800,"rid":[15443]},
{"oid":756,"typ":"int","nam":"Paleoproterozoic","lvl":2,"pid":752,"col":"#F74370","lag":1600,"eag":2500,"rid":[47900]},
{"oid":755,"typ":"int","nam":"Mesoproterozoic","lvl":2,"pid":752,"col":"#FDB462","lag":1000,"eag":1600,"rid":[47900]},
{"oid":754,"typ":"int","nam":"Neoproterozoic","lvl":2,"pid":752,"col":"#FEB342","lag":541,"eag":1000,"rid":[47900]},
{"oid":3,"typ":"int","nam":"Paleozoic","abr":"Pz","lvl":2,"pid":751,"col":"#99C08D","lag":252.2,"eag":541,"rid":[47900]},
{"oid":2,"typ":"int","nam":"Mesozoic","abr":"Mz","lvl":2,"pid":751,"col":"#67C5CA","lag":66,"eag":252.2,"rid":[47900]},
{"oid":1,"typ":"int","nam":"Cenozoic","abr":"Cz","lvl":2,"pid":751,"col":"#F2F91D","lag":0,"eag":66,"rid":[47900]},
{"oid":770,"typ":"int","nam":"Siderian","lvl":3,"pid":756,"col":"#F74F7C","lag":2300,"eag":2500,"rid":[47900]},
{"oid":769,"typ":"int","nam":"Rhyacian","lvl":3,"pid":756,"col":"#F75B89","lag":2050,"eag":2300,"rid":[47900]},
{"oid":768,"typ":"int","nam":"Orosirian","lvl":3,"pid":756,"col":"#F76898","lag":1800,"eag":2050,"rid":[47900]},
{"oid":767,"typ":"int","nam":"Statherian","lvl":3,"pid":756,"col":"#F875A7","lag":1600,"eag":1800,"rid":[47900]},
{"oid":766,"typ":"int","nam":"Calymmian","lvl":3,"pid":755,"col":"#FDC07A","lag":1400,"eag":1600,"rid":[47900]},
{"oid":765,"typ":"int","nam":"Ectasian","lvl":3,"pid":755,"col":"#F3CC8A","lag":1200,"eag":1400,"rid":[47900]},
{"oid":764,"typ":"int","nam":"Stenian","lvl":3,"pid":755,"col":"#FED99A","lag":1000,"eag":1200,"rid":[47900]},
{"oid":763,"typ":"int","nam":"Tonian","lvl":3,"pid":754,"col":"#FEBF4E","lag":850,"eag":1000,"rid":[47900]},
{"oid":762,"typ":"int","nam":"Cryogenian","lvl":3,"pid":754,"col":"#FECC5C","lag":635,"eag":850,"rid":[47900]},
{"oid":761,"typ":"int","nam":"Ediacaran","lvl":3,"pid":754,"col":"#FED96A","lag":541,"eag":635,"rid":[47900]},
{"oid":22,"typ":"int","nam":"Cambrian","abr":"Cm","lvl":3,"pid":3,"col":"#7FA056","lag":485.4,"eag":541,"rid":[47900]},
{"oid":21,"typ":"int","nam":"Ordovician","abr":"O","lvl":3,"pid":3,"col":"#009270","lag":443.4,"eag":485.4,"rid":[47900]},
{"oid":20,"typ":"int","nam":"Silurian","abr":"S","lvl":3,"pid":3,"col":"#B3E1B6","lag":419.2,"eag":443.4,"rid":[47900]},
{"oid":19,"typ":"int","nam":"Devonian","abr":"D","lvl":3,"pid":3,"col":"#CB8C37","lag":358.9,"eag":419.2,"rid":[47900]},
{"oid":18,"typ":"int","nam":"Carboniferous","abr":"C","lvl":3,"pid":3,"col":"#67A599","lag":298.9,"eag":358.9,"rid":[47900]},
{"oid":17,"typ":"int","nam":"Permian","abr":"P","lvl":3,"pid":3,"col":"#F04028","lag":252.2,"eag":298.9,"rid":[47900]},
{"oid":16,"typ":"int","nam":"Triassic","abr":"Tr","lvl":3,"pid":2,"col":"#812B92","lag":201.3,"eag":252.2,"rid":[47900]},
{"oid":15,"typ":"int","nam":"Jurassic","abr":"J","lvl":3,"pid":2,"col":"#34B2C9","lag":145,"eag":201.3,"rid":[47900]},
{"oid":14,"typ":"int","nam":"Cretaceous","abr":"K","lvl":3,"pid":2,"col":"#7FC64E","lag":66,"eag":145,"rid":[47900]},
{"oid":26,"typ":"int","nam":"Paleogene","abr":"Pg","lvl":3,"pid":1,"col":"#FD9A52","lag":23.03,"eag":66,"rid":[47900]},
{"oid":25,"typ":"int","nam":"Neogene","abr":"Ng","lvl":3,"pid":1,"col":"#FFE619","lag":2.588,"eag":23.03,"rid":[47900]},
{"oid":12,"typ":"int","nam":"Quaternary","lvl":3,"pid":1,"col":"#F9F97F","lag":0,"eag":2.588,"rid":[47900]},
{"oid":1111,"typ":"int","nam":"Terreneuvian","lvl":4,"pid":22,"col":"#8CB06C","lag":521,"eag":541,"rid":[47900]},
{"oid":1110,"typ":"int","nam":"Series 2","lvl":4,"pid":22,"col":"#99C078","lag":509,"eag":521,"rid":[47900]},
{"oid":1109,"typ":"int","nam":"Series 3","lvl":4,"pid":22,"col":"#A6CF86","lag":497,"eag":509,"rid":[47900]},
{"oid":780,"typ":"int","nam":"Furongian","lvl":4,"pid":22,"col":"#B3E095","lag":485.4,"eag":497,"rid":[47900]},
{"oid":31,"typ":"int","nam":"Early Ordovician","lvl":4,"pid":21,"col":"#1A9D6F","lag":470,"eag":485.4,"rid":[47900]},
{"oid":30,"typ":"int","nam":"Middle Ordovician","lvl":4,"pid":21,"col":"#4DB47E","lag":458.4,"eag":470,"rid":[47900]},
{"oid":29,"typ":"int","nam":"Late Ordovician","lvl":4,"pid":21,"col":"#7FCA93","lag":443.4,"eag":458.4,"rid":[47900]},
{"oid":62,"typ":"int","nam":"Llandovery","lvl":4,"pid":20,"col":"#99D7B3","lag":433.4,"eag":443.4,"rid":[47900]},
{"oid":61,"typ":"int","nam":"Wenlock","lvl":4,"pid":20,"col":"#B3E1C2","lag":427.4,"eag":433.4,"rid":[47900]},
{"oid":60,"typ":"int","nam":"Ludlow","lvl":4,"pid":20,"col":"#BFE6CF","lag":423,"eag":427.4,"rid":[47900]},
{"oid":59,"typ":"int","nam":"Pridoli","lvl":4,"pid":20,"col":"#E6F5E1","lag":419.2,"eag":423,"rid":[47900]},
{"oid":58,"typ":"int","nam":"Early Devonian","lvl":4,"pid":19,"col":"#E5AC4D","lag":393.3,"eag":419.2,"rid":[47900]},
{"oid":57,"typ":"int","nam":"Middle Devonian","lvl":4,"pid":19,"col":"#F1C868","lag":382.7,"eag":393.3,"rid":[47900]},
{"oid":56,"typ":"int","nam":"Late Devonian","lvl":4,"pid":19,"col":"#F1E19D","lag":358.9,"eag":382.7,"rid":[47900]},
{"oid":28,"typ":"int","nam":"Mississippian","lvl":4,"pid":18,"col":"#678F66","lag":323.2,"eag":358.9,"rid":[47900]},
{"oid":27,"typ":"int","nam":"Pennsylvanian","lvl":4,"pid":18,"col":"#99C2B5","lag":298.9,"eag":323.2,"rid":[47900]},
{"oid":773,"typ":"int","nam":"Cisuralian","lvl":4,"pid":17,"col":"#EF5845","lag":272.3,"eag":298.9,"rid":[47900]},
{"oid":772,"typ":"int","nam":"Guadalupian","lvl":4,"pid":17,"col":"#FB745C","lag":259.9,"eag":272.3,"rid":[47900]},
{"oid":771,"typ":"int","nam":"Lopingian","lvl":4,"pid":17,"col":"#FBA794","lag":252.2,"eag":259.9,"rid":[47900]},
{"oid":46,"typ":"int","nam":"Early Triassic","lvl":4,"pid":16,"col":"#983999","lag":247.2,"eag":252.2,"rid":[47900]},
{"oid":45,"typ":"int","nam":"Middle Triassic","lvl":4,"pid":16,"col":"#B168B1","lag":237,"eag":247.2,"rid":[47900]},
{"oid":44,"typ":"int","nam":"Late Triassic","lvl":4,"pid":16,"col":"#BD8CC3","lag":201.3,"eag":237,"rid":[47900]},
{"oid":43,"typ":"int","nam":"Early Jurassic","lvl":4,"pid":15,"col":"#42AED0","lag":174.1,"eag":201.3,"rid":[47900]},
{"oid":42,"typ":"int","nam":"Middle Jurassic","lvl":4,"pid":15,"col":"#80CFD8","lag":163.5,"eag":174.1,"rid":[47900]},
{"oid":41,"typ":"int","nam":"Late Jurassic","lvl":4,"pid":15,"col":"#B3E3EE","lag":145,"eag":163.5,"rid":[47900]},
{"oid":40,"typ":"int","nam":"Early Cretaceous","lvl":4,"pid":14,"col":"#8CCD57","lag":100.5,"eag":145,"rid":[47900]},
{"oid":39,"typ":"int","nam":"Late Cretaceous","lvl":4,"pid":14,"col":"#A6D84A","lag":66,"eag":100.5,"rid":[47900]},
{"oid":38,"typ":"int","nam":"Paleocene","lvl":4,"pid":26,"col":"#FDA75F","lag":56,"eag":66,"rid":[47900]},
{"oid":37,"typ":"int","nam":"Eocene","lvl":4,"pid":26,"col":"#FDB46C","lag":33.9,"eag":56,"rid":[47900]},
{"oid":36,"typ":"int","nam":"Oligocene","lvl":4,"pid":26,"col":"#FDC07A","lag":23.03,"eag":33.9,"rid":[47900]},
{"oid":35,"typ":"int","nam":"Miocene","lvl":4,"pid":25,"col":"#FFFF00","lag":5.333,"eag":23.03,"rid":[47900]},
{"oid":34,"typ":"int","nam":"Pliocene","lvl":4,"pid":25,"col":"#FFFF99","lag":2.588,"eag":5.333,"rid":[47900]},
{"oid":33,"typ":"int","nam":"Pleistocene","lvl":4,"pid":12,"col":"#FFF2AE","lag":0.0117,"eag":2.588,"rid":[47900]},
{"oid":32,"typ":"int","nam":"Holocene","lvl":4,"pid":12,"col":"#FEF2E0","lag":0,"eag":0.0117,"rid":[47900]},
{"oid":1121,"typ":"int","nam":"Fortunian","lvl":5,"pid":1111,"col":"#99B575","lag":529,"eag":541,"rid":[47900]},
{"oid":1120,"typ":"int","nam":"Stage 2","lvl":5,"pid":1111,"col":"#A6BA80","lag":521,"eag":529,"rid":[47900]},
{"oid":1119,"typ":"int","nam":"Stage 3","lvl":5,"pid":1110,"col":"#A6C583","lag":514,"eag":521,"rid":[47900]},
{"oid":1118,"typ":"int","nam":"Stage 4","lvl":5,"pid":1110,"col":"#B3CA8E","lag":509,"eag":514,"rid":[47900]},
{"oid":1117,"typ":"int","nam":"Stage 5","lvl":5,"pid":1109,"col":"#B3D492","lag":504.5,"eag":509,"rid":[47900]},
{"oid":1116,"typ":"int","nam":"Drumian","lvl":5,"pid":1109,"col":"#BFD99D","lag":500.5,"eag":504.5,"rid":[47900]},
{"oid":1087,"typ":"int","nam":"Guzhangian","lvl":5,"pid":1109,"col":"#CCDFAA","lag":497,"eag":500.5,"rid":[47900]},
{"oid":1114,"typ":"int","nam":"Paibian","lvl":5,"pid":780,"col":"#CCEBAE","lag":494,"eag":497,"rid":[47900]},
{"oid":1113,"typ":"int","nam":"Jiangshanian","lvl":5,"pid":780,"col":"#D9F0BB","lag":489.5,"eag":494,"rid":[47900]},
{"oid":1112,"typ":"int","nam":"Stage 10","lvl":5,"pid":780,"col":"#E6F5C9","lag":485.4,"eag":489.5,"rid":[47900]},
{"oid":559,"typ":"int","nam":"Tremadocian","lvl":5,"pid":31,"col":"#33A97E","lag":477.7,"eag":485.4,"rid":[47900]},
{"oid":1010,"typ":"int","nam":"Floian","lvl":5,"pid":31,"col":"#41B087","lag":470,"eag":477.7,"rid":[47900]},
{"oid":1079,"typ":"int","nam":"Dapingian","lvl":5,"pid":30,"col":"#66C092","lag":467.3,"eag":470,"rid":[47900]},
{"oid":556,"typ":"int","nam":"Darriwilian","lvl":5,"pid":30,"col":"#74C69C","lag":458.4,"eag":467.3,"rid":[47900]},
{"oid":1009,"typ":"int","nam":"Sandbian","lvl":5,"pid":29,"col":"#8CD094","lag":453,"eag":458.4,"rid":[47900]},
{"oid":1008,"typ":"int","nam":"Katian","lvl":5,"pid":29,"col":"#99D69F","lag":445.2,"eag":453,"rid":[47900]},
{"oid":192,"typ":"int","nam":"Hirnantian","lvl":5,"pid":29,"col":"#A6DBAB","lag":443.4,"eag":445.2,"rid":[47900]},
{"oid":191,"typ":"int","nam":"Rhuddanian","lvl":5,"pid":62,"col":"#A6DCB5","lag":440.8,"eag":443.4,"rid":[47900]},
{"oid":190,"typ":"int","nam":"Aeronian","lvl":5,"pid":62,"col":"#B3E1C2","lag":438.5,"eag":440.8,"rid":[47900]},
{"oid":189,"typ":"int","nam":"Telychian","lvl":5,"pid":62,"col":"#BFE6D1","lag":433.4,"eag":438.5,"rid":[47900]},
{"oid":188,"typ":"int","nam":"Sheinwoodian","lvl":5,"pid":61,"col":"#BFE6C3","lag":430.5,"eag":433.4,"rid":[47900]},
{"oid":785,"typ":"int","nam":"Homerian","lvl":5,"pid":61,"col":"#CCEBD1","lag":427.4,"eag":430.5,"rid":[47900]},
{"oid":185,"typ":"int","nam":"Gorstian","lvl":5,"pid":60,"col":"#CCECDD","lag":425.6,"eag":427.4,"rid":[47900]},
{"oid":184,"typ":"int","nam":"Ludfordian","lvl":5,"pid":60,"col":"#D9F0DF","lag":423,"eag":425.6,"rid":[47900]},
{"oid":3001,"typ":"int","nam":"Pridoli","lvl":5,"pid":59,"col":"#E6F5E1","lag":419.2,"eag":423,"rid":[47900]},
{"oid":183,"typ":"int","nam":"Lochkovian","lvl":5,"pid":58,"col":"#E5B75A","lag":410.8,"eag":419.2,"rid":[47900]},
{"oid":182,"typ":"int","nam":"Pragian","lvl":5,"pid":58,"col":"#E5C468","lag":407.6,"eag":410.8,"rid":[47900]},
{"oid":181,"typ":"int","nam":"Emsian","lvl":5,"pid":58,"col":"#E5D075","lag":393.3,"eag":407.6,"rid":[47900]},
{"oid":180,"typ":"int","nam":"Eifelian","lvl":5,"pid":57,"col":"#F1D576","lag":387.7,"eag":393.3,"rid":[47900]},
{"oid":179,"typ":"int","nam":"Givetian","lvl":5,"pid":57,"col":"#F1E185","lag":382.7,"eag":387.7,"rid":[47900]},
{"oid":178,"typ":"int","nam":"Frasnian","lvl":5,"pid":56,"col":"#F2EDAD","lag":372.2,"eag":382.7,"rid":[47900]},
{"oid":177,"typ":"int","nam":"Famennian","lvl":5,"pid":56,"col":"#F2EDC5","lag":358.9,"eag":372.2,"rid":[47900]},
{"oid":55,"typ":"int","nam":"Tournaisian","lvl":5,"pid":28,"col":"#8CB06C","lag":346.7,"eag":358.9,"rid":[5954]},
{"oid":54,"typ":"int","nam":"Visean","lvl":5,"pid":28,"col":"#A6B96C","lag":330.9,"eag":346.7,"rid":[5954]},
{"oid":53,"typ":"int","nam":"Serpukhovian","lvl":5,"pid":28,"col":"#BFC26B","lag":323.2,"eag":330.9,"rid":[5954]},
{"oid":52,"typ":"int","nam":"Bashkirian","lvl":5,"pid":27,"col":"#99C2B6","lag":315.2,"eag":323.2,"rid":[5954]},
{"oid":51,"typ":"int","nam":"Moscovian","lvl":5,"pid":27,"col":"#B3CBB9","lag":307,"eag":315.2,"rid":[5954]},
{"oid":50,"typ":"int","nam":"Kasimovian","lvl":5,"pid":27,"col":"#BFD0C5","lag":303.7,"eag":307,"rid":[5954]},
{"oid":49,"typ":"int","nam":"Gzhelian","lvl":5,"pid":27,"col":"#CCD4C7","lag":298.9,"eag":303.7,"rid":[5954]},
{"oid":151,"typ":"int","nam":"Asselian","lvl":5,"pid":773,"col":"#E36350","lag":295.5,"eag":298.9,"rid":[5954]},
{"oid":150,"typ":"int","nam":"Sakmarian","lvl":5,"pid":773,"col":"#E36F5C","lag":290.1,"eag":295.5,"rid":[5954]},
{"oid":149,"typ":"int","nam":"Artinskian","lvl":5,"pid":773,"col":"#E37B68","lag":279.3,"eag":290.1,"rid":[5954]},
{"oid":148,"typ":"int","nam":"Kungurian","lvl":5,"pid":773,"col":"#E38776","lag":272.3,"eag":279.3,"rid":[5954]},
{"oid":717,"typ":"int","nam":"Roadian","lvl":5,"pid":772,"col":"#FB8069","lag":268.8,"eag":272.3,"rid":[9184]},
{"oid":146,"typ":"int","nam":"Wordian","lvl":5,"pid":772,"col":"#FB8D76","lag":265.1,"eag":268.8,"rid":[5954]},
{"oid":145,"typ":"int","nam":"Capitanian","lvl":5,"pid":772,"col":"#FB9A85","lag":259.9,"eag":265.1,"rid":[5954]},
{"oid":716,"typ":"int","nam":"Wuchiapingian","lvl":5,"pid":771,"col":"#FCB4A2","lag":254.2,"eag":259.9,"rid":[9184]},
{"oid":715,"typ":"int","nam":"Changhsingian","lvl":5,"pid":771,"col":"#FCC0B2","lag":252.2,"eag":254.2,"rid":[9184]},
{"oid":653,"typ":"int","nam":"Induan","lvl":5,"pid":46,"col":"#A4469F","lag":251.2,"eag":252.2,"rid":[47900]},
{"oid":652,"typ":"int","nam":"Olenekian","lvl":5,"pid":46,"col":"#B051A5","lag":247.2,"eag":251.2,"rid":[47900]},
{"oid":139,"typ":"int","nam":"Anisian","lvl":5,"pid":45,"col":"#BC75B7","lag":242,"eag":247.2,"rid":[47900]},
{"oid":138,"typ":"int","nam":"Ladinian","lvl":5,"pid":45,"col":"#C983BF","lag":237,"eag":242,"rid":[47900]},
{"oid":137,"typ":"int","nam":"Carnian","lvl":5,"pid":44,"col":"#C99BCB","lag":228,"eag":237,"rid":[47900]},
{"oid":136,"typ":"int","nam":"Norian","lvl":5,"pid":44,"col":"#D6AAD3","lag":208.5,"eag":228,"rid":[47900]},
{"oid":135,"typ":"int","nam":"Rhaetian","lvl":5,"pid":44,"col":"#E3B9DB","lag":201.3,"eag":208.5,"rid":[47900]},
{"oid":134,"typ":"int","nam":"Hettangian","lvl":5,"pid":43,"col":"#4EB3D3","lag":199.3,"eag":201.3,"rid":[47900]},
{"oid":133,"typ":"int","nam":"Sinemurian","lvl":5,"pid":43,"col":"#67BCD8","lag":190.8,"eag":199.3,"rid":[47900]},
{"oid":132,"typ":"int","nam":"Pliensbachian","lvl":5,"pid":43,"col":"#80C5DD","lag":182.7,"eag":190.8,"rid":[47900]},
{"oid":131,"typ":"int","nam":"Toarcian","lvl":5,"pid":43,"col":"#99CEE3","lag":174.1,"eag":182.7,"rid":[47900]},
{"oid":130,"typ":"int","nam":"Aalenian","lvl":5,"pid":42,"col":"#9AD9DD","lag":170.3,"eag":174.1,"rid":[47900]},
{"oid":129,"typ":"int","nam":"Bajocian","lvl":5,"pid":42,"col":"#A6DDE0","lag":168.3,"eag":170.3,"rid":[47900]},
{"oid":128,"typ":"int","nam":"Bathonian","lvl":5,"pid":42,"col":"#B3E2E3","lag":166.1,"eag":168.3,"rid":[47900]},
{"oid":127,"typ":"int","nam":"Callovian","lvl":5,"pid":42,"col":"#BFE7E5","lag":163.5,"eag":166.1,"rid":[47900]},
{"oid":126,"typ":"int","nam":"Oxfordian","lvl":5,"pid":41,"col":"#BFE7F1","lag":157.3,"eag":163.5,"rid":[47900]},
{"oid":125,"typ":"int","nam":"Kimmeridgian","lvl":5,"pid":41,"col":"#CCECF4","lag":152.1,"eag":157.3,"rid":[47900]},
{"oid":124,"typ":"int","nam":"Tithonian","lvl":5,"pid":41,"col":"#D9F1F7","lag":145,"eag":152.1,"rid":[47900]},
{"oid":123,"typ":"int","nam":"Berriasian","lvl":5,"pid":40,"col":"#8CCD60","lag":139.8,"eag":145,"rid":[47900]},
{"oid":122,"typ":"int","nam":"Valanginian","lvl":5,"pid":40,"col":"#99D36A","lag":132.9,"eag":139.8,"rid":[47900]},
{"oid":121,"typ":"int","nam":"Hauterivian","lvl":5,"pid":40,"col":"#A6D975","lag":129.4,"eag":132.9,"rid":[47900]},
{"oid":120,"typ":"int","nam":"Barremian","lvl":5,"pid":40,"col":"#B3DF7F","lag":125,"eag":129.4,"rid":[47900]},
{"oid":119,"typ":"int","nam":"Aptian","lvl":5,"pid":40,"col":"#BFE48A","lag":113,"eag":125,"rid":[47900]},
{"oid":118,"typ":"int","nam":"Albian","lvl":5,"pid":40,"col":"#CCEA97","lag":100.5,"eag":113,"rid":[47900]},
{"oid":117,"typ":"int","nam":"Cenomanian","lvl":5,"pid":39,"col":"#B3DE53","lag":93.9,"eag":100.5,"rid":[47900]},
{"oid":116,"typ":"int","nam":"Turonian","lvl":5,"pid":39,"col":"#BFE35D","lag":89.8,"eag":93.9,"rid":[47900]},
{"oid":115,"typ":"int","nam":"Coniacian","lvl":5,"pid":39,"col":"#CCE968","lag":86.3,"eag":89.8,"rid":[47900]},
{"oid":114,"typ":"int","nam":"Santonian","lvl":5,"pid":39,"col":"#D9EF74","lag":83.6,"eag":86.3,"rid":[47900]},
{"oid":113,"typ":"int","nam":"Campanian","lvl":5,"pid":39,"col":"#E6F47F","lag":72.1,"eag":83.6,"rid":[47900]},
{"oid":112,"typ":"int","nam":"Maastrichtian","lvl":5,"pid":39,"col":"#F2FA8C","lag":66,"eag":72.1,"rid":[47900]},
{"oid":111,"typ":"int","nam":"Danian","lvl":5,"pid":38,"col":"#FDB462","lag":61.6,"eag":66,"rid":[47900]},
{"oid":743,"typ":"int","nam":"Selandian","lvl":5,"pid":38,"col":"#FEBF65","lag":59.2,"eag":61.6,"rid":[47900]},
{"oid":110,"typ":"int","nam":"Thanetian","lvl":5,"pid":38,"col":"#FDBF6F","lag":56,"eag":59.2,"rid":[47900]},
{"oid":109,"typ":"int","nam":"Ypresian","lvl":5,"pid":37,"col":"#FCA773","lag":47.8,"eag":56,"rid":[47900]},
{"oid":108,"typ":"int","nam":"Lutetian","lvl":5,"pid":37,"col":"#FCB482","lag":41.3,"eag":47.8,"rid":[47900]},
{"oid":107,"typ":"int","nam":"Bartonian","lvl":5,"pid":37,"col":"#FDC091","lag":38,"eag":41.3,"rid":[47900]},
{"oid":106,"typ":"int","nam":"Priabonian","lvl":5,"pid":37,"col":"#FDCDA1","lag":33.9,"eag":38,"rid":[47900]},
{"oid":105,"typ":"int","nam":"Rupelian","lvl":5,"pid":36,"col":"#FED99A","lag":28.1,"eag":33.9,"rid":[47900]},
{"oid":104,"typ":"int","nam":"Chattian","lvl":5,"pid":36,"col":"#FEE6AA","lag":23.03,"eag":28.1,"rid":[47900]},
{"oid":103,"typ":"int","nam":"Aquitanian","lvl":5,"pid":35,"col":"#FFFF33","lag":20.44,"eag":23.03,"rid":[47900]},
{"oid":102,"typ":"int","nam":"Burdigalian","lvl":5,"pid":35,"col":"#FFFF41","lag":15.97,"eag":20.44,"rid":[47900]},
{"oid":101,"typ":"int","nam":"Langhian","lvl":5,"pid":35,"col":"#FFFF4D","lag":13.82,"eag":15.97,"rid":[47900]},
{"oid":100,"typ":"int","nam":"Serravallian","lvl":5,"pid":35,"col":"#FFFF59","lag":11.62,"eag":13.82,"rid":[47900]},
{"oid":99,"typ":"int","nam":"Tortonian","lvl":5,"pid":35,"col":"#FFFF66","lag":7.246,"eag":11.62,"rid":[47900]},
{"oid":98,"typ":"int","nam":"Messinian","lvl":5,"pid":35,"col":"#FFFF73","lag":5.333,"eag":7.246,"rid":[47900]},
{"oid":97,"typ":"int","nam":"Zanclean","lvl":5,"pid":34,"col":"#FFFFB3","lag":3.6,"eag":5.333,"rid":[47900]},
{"oid":96,"typ":"int","nam":"Piacenzian","lvl":5,"pid":34,"col":"#FFFFBF","lag":2.588,"eag":3.6,"rid":[47900]},
{"oid":741,"typ":"int","nam":"Gelasian","lvl":5,"pid":33,"col":"#FFEDB3","lag":1.806,"eag":2.588,"rid":[47900]},
{"oid":740,"typ":"int","nam":"Calabrian","lvl":5,"pid":33,"col":"#FFF2BA","lag":0.781,"eag":1.806,"rid":[47900]},
{"oid":923,"typ":"int","nam":"Middle Pleistocene","lvl":5,"pid":33,"col":"#FFF2C7","lag":0.126,"eag":0.781,"rid":[15443]},
{"oid":922,"typ":"int","nam":"Late Pleistocene","lvl":5,"pid":33,"col":"#FFF2D3","lag":0.0117,"eag":0.126,"rid":[15443]},
{"oid":3002,"typ":"int","nam":"Holocene","lvl":5,"pid":32,"col":"#FEF2E0","lag":0,"eag":0.0117,"rid":[47900]}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment