Published
Edited
Nov 14, 2021
Insert cell
Insert cell
view = md`${container()}`
Insert cell
format = d3.format(".1f")
Insert cell
function updateFilters(e) {

const visibleMarkers = []
layerList[0].eachLayer(function(layer) {
if(e.target.getBounds().contains(layer.getLatLng()))
visibleMarkers.push(layer.publicid);
//add layer.publicid to some array visibleMarkers
})
idDimension.filterFunction(function(d) {
return visibleMarkers.indexOf(d) > -1;
});
dc.redrawAll();
}
Insert cell
dataset = d3.csv('https://gist.githubusercontent.com/emanueles/301057974a02cf8446e42c1e46c9c742/raw/0ed6d119afbc5eeddc7f763d3708fc1829d22c9f/earthquakes.csv').then(function(data){
let parseDate = d3.utcParse("%Y-%m-%dT%H:%M:%S")
data.forEach(function(d){
d.dtg = parseDate(d.origintime.substr(0,19));
d.magnitude = +d.magnitude;
d.depth = Math.round(+d.depth);
});
return data;
})
Insert cell
facts = crossfilter(dataset)
Insert cell
dateDimension = facts.dimension( d => d.dtg)
Insert cell
magDimension = facts.dimension(d => Math.round((d.magnitude + Number.EPSILON) * 10) / 10)
Insert cell
magDimensionCount = magDimension.group()
Insert cell
depthDimension = facts.dimension( d => d.depth)
Insert cell
depthDimensionCount = depthDimension.group()
Insert cell
hourDimension = facts.dimension(d => d3.timeHour(d.dtg))
Insert cell
hourDimensionCount = hourDimension.group()
Insert cell
buildvis = {
magnitudeChart.width(480)
.height(150)
.margins({top: 10, right: 10, bottom: 20, left:40})
.dimension(magDimension)
.group(magDimensionCount)
.transitionDuration(500)
.gap(56)
.centerBar(true)
.x(d3.scaleLinear().domain([0, 8]))
.elasticY(true)
.on("filtered", function(chart,filter){
updateMarkers()
})
depthChart.width(480)
.height(150)
.margins({top: 10, right: 10, bottom: 20, left:40})
.dimension(depthDimension)
.group(depthDimensionCount)
.transitionDuration(500)
.centerBar(true)
.gap(1)
.x(d3.scaleLinear().domain([0, 100]))
.elasticY(true)
.on("filtered", function(chart,filter){
updateMarkers()
})
timeChart.width(960)
.height(150)
.transitionDuration(500)
.margins({top: 10, right: 10, bottom: 20, left:40})
.dimension(hourDimension)
.group(hourDimensionCount)
.brushOn(false)
.elasticY(true)
.x(d3.scaleTime().domain(d3.extent(dataset, d => d.dtg)))
dataTable.width(960)
.height(800)
.dimension(dateDimension)
.group(d => "List of all earthquakes corresponding to the filters")
.size(5)
.columns([
'dtg',
'magnitude',
'depth',
'latitude',
'longitude'])
.sortBy(d => d.dtg)
.order(d3.ascending)
dc.renderAll()
updateMarkers()
}
Insert cell
circlesLayer = L.layerGroup().addTo(map)
Insert cell
circleScale = d3
.scaleLinear()
.domain([0, magDimension.top(1)[0].magnitude])
.range([0, 50000])
Insert cell
circles = {
let markers = d3.map();
dataset.forEach(function(d) {
let circle = L.circle([d.latitude, d.longitude], circleScale(d.magnitude), {
color: '#fd8d3c',
weight: 2,
fillColor: '#fecc5c',
fillOpacity: 0.5
});
circle.bindPopup("Magnitude: " + format(d.magnitude) + "<br>Time: " + d.dtg);
circle.publicid = d.publicid; //para a interação na outra direção
markers.set(d.publicid, circle);
});
return markers;
}
Insert cell
layerList = []
Insert cell
idDimension = facts.dimension(d=>d.publicid)
Insert cell
idGrouping = idDimension.group()
Insert cell
function updateMarkers(){
let ids = idGrouping.all()
let todisplay = new Array(ids.length) //preallocate array to be faster
let mc = 0; //counter of used positions in the array
for (let i = 0; i < ids.length; i++) {
let tId = ids[i];
if(tId.value > 0){ //when an element is filtered, it has value > 0
todisplay[mc] = circles.get(tId.key)
mc = mc + 1
}
}
todisplay.length = mc; //resize the array so Leaflet does not complain
if (layerList.length == 1) {
layerList[0].clearLayers() //remove circles in layerGroup
if (map.hasLayer(layerList[0])){
map.removeLayer(layerList[0]) //remove layerGroup if present
}
}
layerList[0] = L.layerGroup(todisplay).addTo(map) //add it again passing the array of markers
}
Insert cell
magnitudeChart = dc.barChart(view.querySelector("#magnitude-chart"))
Insert cell
depthChart = dc.barChart(view.querySelector("#depth-chart"))
Insert cell
timeChart = dc.lineChart(view.querySelector("#time-chart"))
Insert cell
dataTable = dc.dataTable(view.querySelector("#dc-table-graph"))
Insert cell
map = {
view;
let mapInstance = L.map('mapid').setView([-41.05,172.93], 5)
mapInstance.on('moveend', updateFilters)
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors',
maxZoom: 17
}).addTo(mapInstance)
return mapInstance
}
Insert cell
function container() {
return `
<main role="main" class="container">
<div class="row">
<h4> Earthquakes in New Zealand</h4>
</div>
<div class='row'>
<div id="mapid" class="col-6">
</div>
<div class="col-6">
<div id='magnitude-chart'>
<h5> Number of Events by Magnitude</h5>
</div>
<div id='depth-chart'>
<h5> Events by Depth (km) </h5>
</div>
</div>
</div>
<div class='row'>
<div id='time-chart' class="single-col">
<h5> Events per hour </h5>
</div>
</div>
<table class="table table-hover" id="dc-table-graph">
<thead>
<tr class="header">
<th>DTG</th>
<th>Magnitude</th>
<th>Depth</th>
<th>Latitude</th>
<th>Longitude</th>
</tr>
</thead>
</table>
<p>Earthquake data via <a href="https://quakesearch.geonet.org.nz/">Geonet</a>.</p>
</main>
`
}
Insert cell
Insert cell
dc = require('dc')
Insert cell
crossfilter = require('crossfilter2')
Insert cell
$ = require('jquery').then(jquery => {
window.jquery = jquery;
return require('popper@1.0.1/index.js').catch(() => jquery);
})
Insert cell
d3 = require('d3@5')
Insert cell
bootstrap = require('bootstrap')
Insert cell
L = require('leaflet@1.6.0')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more