quakes_data_df = transpose(quakes_data)
// Calculating summary statistics for value boxes
days_since_last = d3.timeDay.count(d3.max(quakes_data_df.map(d => new Date(d.time))), new Date())
quakes_last_24h = quakes_data_df.filter(d =>
new Date(d.time) >= d3.timeDay.offset(new Date(), -1)
).length
last_mag = quakes_data_df[0]?.mag || "N/A"
d3 = require("d3@6")
// Include FontAwesome for icons
html`<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">`
initial_start_date = d3.min(quakes_data_df, d => d.date_only)
initial_end_date = d3.max(quakes_data_df, d => d.date_only)
initial_min_magnitude = 1
// Filtering earthquakes based on the selected criteria
filtered_quakes = {
reset;
return quakes_data_df.filter(d =>
new Date(d.date_only) >= new Date(start_date) &&
new Date(d.date_only) <= new Date(end_date) &&
d.mag >= min_magnitude
);
}
// Adding an event listener for the reset button
resetButton = {
viewof reset.addEventListener("click", () => {
viewof start_date.value = initial_start_date;
viewof end_date.value = initial_end_date;
viewof min_magnitude.value = initial_min_magnitude;
viewof start_date.dispatchEvent(new Event('input'));
viewof end_date.dispatchEvent(new Event('input'));
viewof min_magnitude.dispatchEvent(new Event('input'));
});
return viewof reset;
}
viewof start_date = Inputs.date({
label: "Start Date",
value: initial_start_date,
max: initial_end_date,
min: initial_start_date
})
// Create the end date input
viewof end_date = Inputs.date({
label: "End Date",
value: initial_end_date,
min: initial_start_date,
max: initial_end_date
})
// Create the minimum magnitude range input
viewof min_magnitude = Inputs.range([1, 10], {
step: 0.1,
label: "Min Magnitude",
value: initial_min_magnitude
})
// Create the reset button
viewof reset = html`<button class="reset-button" id="resetButton"><i class="fas fa-redo"></i></button>`
// Custom styles for the reset button
html`<style>
.reset-button {
width: 40px;
height: 40px;
border: none;
background-color: #D5C3C3;
color: #5A5555;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s;
}
.reset-button:hover {
background-color: #AB8787;
}
.reset-button i {
font-size: 15px;
}
</style>`
L = require('leaflet@1.2.0')
// Include Leaflet CSS and custom legend CSS
html`<link href='${resolve('leaflet@1.2.0/dist/leaflet.css')}' rel='stylesheet' />`
html`
<style>
.info.legend {
line-height: 18px;
color: #555;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
padding: 10px;
}
.info.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
`
color_scale = d3.scaleSequential(t => d3.interpolateMagma(1 - t))
.domain([1, 7]);
// Create the map with filtered data
map = {
// Set dimensions
let width = 850;
let height = width / 1.6;
// Create the container for the map
let container = DOM.element('div', {
style: `width: ${width}px; height: ${height}px`
});
yield container;
// Initialize the map
let map = L.map(container).setView([44.4, 16.4], 7);
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Add markers for each filtered earthquake
filtered_quakes.forEach(d => {
L.circleMarker([d.lat, d.lon], {
radius: d3.scaleLinear().domain([1, 7]).range([1, 7])(d.mag),
fillColor: color_scale(d.mag),
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.5
}).addTo(map)
.bindPopup(`
<div style="font-family: 'Montserrat', serif;">
Date: ${d.date_only}<br/>
Time: ${d.time_only}<br/>
Magnitude: ${d.mag.toFixed(2)}<br/>
Depth: ${d.depth} km<br/>
Location: ${d.place}
`);
});
// Add legend to the map
var legend = L.control({position: 'topleft'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [1, 2, 3, 4, 5,6],
labels = [];
div.innerHTML += '<strong style="font-family: Baskerville;">Magnitude</strong><br>';
// Loop through intervals to generate labels with a colored square for each interval
for (var i = 0; i < grades.length; i++) {
div.innerHTML +=
'<i style="background:' + color_scale(grades[i]) + '"></i> ' +
grades[i] + (grades[i + 1] ? '–' + grades[i + 1] + '<br>' : '+');
}
return div;
};
legend.addTo(map);
return map;
}
viewof table = Inputs.table(filtered_quakes, {
columns: [
"date_only",
"time_only",
"mag",
"depth",
"place"
],
header: {
date_only: "Date",
time_only: "Time",
mag: "Magnitude",
depth: "Depth",
place: "Location"
},
width: {
date_only: 150,
time_only: 100,
mag: 80,
depth: 80,
place: 150
},
format: {
depth: x => Number.isInteger(x) ? x.toString() : x.toFixed(2)
},
rows: Infinity,
pagination: true
})
// Custom styles for the table
html`<style>
table {
table-layout: auto;
}
th, td {
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
color: #5A5555;
border-bottom: 1px solid #ddd;
font-family: Baskerville;
font-weight: bold;
}
td {
border-bottom: 1px solid #ddd;
word-wrap: break-word;
font-family: Montserrat;
color: #5A5555;
}
table tr:nth-child(even) {
background-color: #f9f9f9;
}
table tr:hover {
background-color: #D5C3C3;
}
</style>
`
html`<style>
table {
table-layout: auto;
}
th, td {
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
color: #5A5555;
border-bottom: 1px solid #ddd;
font-family: Baskerville;
font-weight: bold;
}
td {
border-bottom: 1px solid #ddd;
word-wrap: break-word;
font-family: Montserrat;
color: #5A5555;
}
table tr:nth-child(even) {
background-color: #f9f9f9;
}
table tr:hover {
background-color: #D5C3C3;
}
</style>
`
html`
<style>
.dashboard-footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #f8f9fa;
color: #5A5555;
text-align: left;
padding: 5px;
font-size: 0.7em;
border-top: 1px solid #eee;
line-height: 1.2;
font-family: Baskerville;
}
.dashboard-footer a {
color: #AB8787;
text-decoration: none;
}
</style>
<footer class="dashboard-footer">
Data source: <a href="https://earthquake.usgs.gov/" target="_blank">USGS</a>.
Note: The data may not reflect real-time conditions due to potential missing earthquakes.
Smaller earthquakes, especially outside the U.S., may not be rapidly reported or located. For more detailed information, please refer to the USGS website. The earthquake data is updated daily at 9:00 AM UTC.
<a href="https://github.com/andabaka/earthquakes" target="_blank">
<i class="fab fa-github"></i> Source Code
</a>
</footer>
`