Skip to content

Instantly share code, notes, and snippets.

@michellemho
Last active February 11, 2018 18:41
Show Gist options
  • Save michellemho/d8d9270390a84e1883b4949a645ded39 to your computer and use it in GitHub Desktop.
Save michellemho/d8d9270390a84e1883b4949a645ded39 to your computer and use it in GitHub Desktop.
Flotsam+Jetsam
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Flotsam and Jetsam</title>
<!-- Include Leaflet 1.2.0 Library -->
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<!-- Fonts -->
<link href='https://fonts.googleapis.com/css?family=Oswald:300,400,600,700' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
<!-- Include cartodb.js Library -->
<script src="https://cdn.rawgit.com/CartoDB/cartodb.js/@4.0.0-alpha.28/carto.js"></script>
<style>
* { margin:0; padding:0; }
#timeline {
background: white;
position: absolute;
left: 25%;
padding: 15px;
bottom: 10px;
height: 30px;
width: 600px;
display: flex;
align-items: center;
z-index: 1000000;
border-style: solid;
border-width: 1px;
border-color: #381a00;
font-family: 'Oswald', cursive;
font-size: x-large;
color: #381a00;
}
#timeline input {
flex: 1;
}
#timeline label {
font-size: 12px;
margin-left: 20px;
}
html { box-sizing:border-box; height:100%; }
body { background: lightgray; height:100%; font-family:"Open sans", Helvetica, Arial, sans-serif; }
#container { display:flex; width:100%; height:100%; background: black;}
#map { flex:1; margin:10px; }
#widgets { width:300px; margin:10px 10px 10px 0; }
.widget { background:white; padding:10px; margin-bottom:10px; }
.widget h1 { font-size:1.2em; }
.leaflet-popup-content-wrapper {
background: lightgray
}
.leaflet-popup-content-wrapper .leaflet-popup-content {
background: lightgray;
font-family: 'Oswald', cursive;
font-size: medium;
color: #381a00;
}
.leaflet-popup-tip {
background: lightgray;
}
#map {
border-style: solid;
border-width: 1px;
border-color: #381a00;
}
</style>
</head>
<body>
<div id="container">
<div id="map"></div>
</div>
<div id="timeline">
<input id="timeSlider" type="range" value="0" step="1" />
<label id="dateValue" />
</div>
<script>
// Is this an italian restaurant? Because man, is this some spaghetti code :D
const dateValue = document.querySelector('#dateValue');
const timeSlider = document.querySelector('#timeSlider');
const table = 'large_sample_processed_1';
let timeSeriesData;
function iso(t) {
return t.toISOString().substring(0,10);
}
function countries_at(t) {
var year;
if (t === undefined) {
// Please don't judge me
year = '2017-12-01';
} else {
year = t
}
t = new Date(year);
console.log(t);
var sql = `SELECT * FROM ${table} WHERE date = '${iso(t)}'::date`;
console.log(sql);
return sql
}
function input_date (offset) {
return new Date(timeSeriesData.bins[timeSlider.value].start * 1000);
}
function updateDate (e) {
dateValue.innerHTML = input_date();
}
var source = new carto.source.SQL(countries_at());
function inputChange () {
source.setQuery(countries_at(input_date()));
}
timeSlider.oninput = updateDate;
timeSlider.addEventListener('change', inputChange);
// 1. Setting up the Leaflet Map
var map = L.map('map').setView([38, 145], 6);
L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/dark_all/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '&copy;<a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>, &copy;<a href="https://carto.com/attribution">CARTO</a>'
}).addTo(map);
// 2 Defining a carto.Client
var client = new carto.Client({
apiKey: 'fake',
username: 'michellemho-carto'
});
// 3. Displaying on the map
// 3.1 Defining the layer
var fullDataset = new carto.source.Dataset('large_sample_processed_1');
var style = new carto.style.CartoCSS(`
#layer {
marker-width: 5;
marker-fill: ramp([magnitude], colorbrewer(YlGn), quantiles(5));
marker-fill-opacity: 1;
marker-line-color: #FFFFFF;
marker-line-width: 0;
marker-line-opacity: 1;
// marker-type: ellipse;
marker-placement: point;
marker-file: url('http://hockeyhumanitarian.org/wp-content/themes/hha/assets/img/Entypo/arrow-long-right.svg');
marker-allow-overlap: true;
marker-transform: rotate([angle],0,0);
}
`);
var countries = new carto.layer.Layer(source, style, {
featureOverColumns: ['magnitude', 'angle']
});
client.addLayer(countries);
// 3.3. Adding the layers to the map
client.getLeafletLayer().addTo(map);
var popup = L.popup();
countries.on('featureOver', function (featureEvent) {
popup.setLatLng(featureEvent.latLng);
popup.setContent(`Magnitude: ${Math.round(100*featureEvent.data.magnitude)/100} m/s \n Angle: ${Math.round(featureEvent.data.angle)} degrees`);
popup.openOn(map);
});
countries.on('featureOut', function (featureEvent) {
popup.removeFrom(map);
});
// 4 Creating a TimeSeries widget
// 4.1 Defining a TimeSeries dataview, the second parameter is the column we want to aggregate.
var timeSeries = new carto.dataview.TimeSeries(fullDataset, 'date', {
aggregation: 'day'
});
// 4.2 Listening to data changes on the dataview
timeSeries.on('dataChanged', function (newData) {
timeSeriesData = newData;
timeSlider.min = 1;
timeSlider.max = 25;
console.log(timeSlider.max)
updateDate();
});
// Listen to timeSeries status, currently we are showing a console.log but looks like a good place to display a loader!
timeSeries.on('statusChanged', function (newStatus, error) {
});
// 4.3 Adding the dataviews to the client
client.addDataview(timeSeries);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment