Skip to content

Instantly share code, notes, and snippets.

@alexanderankin
Last active January 11, 2019 11:17
Show Gist options
  • Select an option

  • Save alexanderankin/486fd12d6514b60afc7beecd72a95d54 to your computer and use it in GitHub Desktop.

Select an option

Save alexanderankin/486fd12d6514b60afc7beecd72a95d54 to your computer and use it in GitHub Desktop.
Browse Regions for Comparison by Census Attributes between years.
# browse-regions-compare-census-gist
[
{
"id": 0,
"text": "rent"
},
{
"id": 1,
"text": "ami"
},
{
"id": 2,
"text": "Aachen"
},
{
"id": 3,
"text": "Aaliyah"
},
{
"id": 4,
"text": "Aaron"
},
{
"id": 5,
"text": "Abbas"
},
{
"id": 6,
"text": "Abbasid"
},
{
"id": 7,
"text": "Abbott"
},
{
"id": 8,
"text": "Abby"
},
{
"id": 9,
"text": "Abdul"
},
{
"id": 10,
"text": "Abe"
},
{
"id": 11,
"text": "Abel"
},
{
"id": 12,
"text": "Abelard"
},
{
"id": 13,
"text": "Abelson"
},
{
"id": 14,
"text": "Aberdeen"
},
{
"id": 15,
"text": "Abernathy"
},
{
"id": 16,
"text": "Abidjan"
},
{
"id": 17,
"text": "Abigail"
},
{
"id": 18,
"text": "Abilene"
},
{
"id": 19,
"text": "Abner"
},
{
"id": 20,
"text": "Abraham"
},
{
"id": 21,
"text": "Abram"
},
{
"id": 22,
"text": "Abrams"
},
{
"id": 23,
"text": "Absalom"
},
{
"id": 24,
"text": "Abuja"
},
{
"id": 25,
"text": "Abyssinia"
},
{
"id": 26,
"text": "Abyssinian"
},
{
"id": 27,
"text": "Ac"
},
{
"id": 28,
"text": "Acadia"
},
{
"id": 29,
"text": "Acapulco"
},
{
"id": 30,
"text": "Accenture"
},
{
"id": 31,
"text": "Accra"
},
{
"id": 32,
"text": "Acevedo"
},
{
"id": 33,
"text": "Achaean"
},
{
"id": 34,
"text": "Achebe"
},
{
"id": 35,
"text": "Achernar"
},
{
"id": 36,
"text": "Acheson"
},
{
"id": 37,
"text": "Achilles"
},
{
"id": 38,
"text": "Aconcagua"
},
{
"id": 39,
"text": "Acosta"
},
{
"id": 40,
"text": "Acropolis"
},
{
"id": 41,
"text": "Acrux"
},
{
"id": 42,
"text": "Actaeon"
},
{
"id": 43,
"text": "Acton"
},
{
"id": 44,
"text": "Acts"
},
{
"id": 45,
"text": "Acuff"
},
{
"id": 46,
"text": "Ada"
},
{
"id": 47,
"text": "Adam"
},
{
"id": 48,
"text": "Adams"
},
{
"id": 49,
"text": "Adan"
},
{
"id": 50,
"text": "Adana"
}
]
[
{
"id": 0,
"text": 2010
},
{
"id": 1,
"text": 2016
}
]
[
{
"year": 2010,
"field": "rent",
"value": "high"
},
{
"year": 2010,
"field": "ami",
"value": "low"
},
{
"year": 2016,
"field": "rent",
"value": "higher"
},
{
"year": 2016,
"field": "ami",
"value": "high"
}
]
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Browse Regions Click Compare Census</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<!-- Select stuff -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<!-- Leaflet stuff -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.4.0/dist/leaflet.css"
integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.4.0/dist/leaflet.js"
integrity="sha512-QVftwZFqvtRNi0ZyCtsznlKSWOStnDORoefr1enyq5mVL4tmKB3S/EnC3rRJcxCPavG10IcrVGSmPh6Qw5lwrg=="
crossorigin=""></script>
<script src="/script.js"></script>
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div class="container-fluid">
<div class="row mt-5">
<div class="col-sm-5"> <!-- map stuff -->
<h4>Click on a region.</h4>
<div id="media-container" class="mt-3 mb-3">
<div class="d-inline p-3">
<label>Currently Selected:</label>
<span id="selected-region" class="p-2" style="background-color: #eee; border-radius: 10px;">None</span>
<script>
function setRegion(region) {
window.region = region;
$('#selected-region').text(region);
}
</script>
</div>
</div>
<div id="map-container" style="height: 400px;"></div>
<h3 id="error" class="hidden"></h3>
</div><!-- end map stuff -->
<div class="col-sm-7"><!-- interface stuff -->
<div class="row justify-content-between">
<div class="col-6">
<h4>pick No 1 census year</h4>
<div class="m-3">
<select id="sel-census-1" class="c-select census sel-skinny"></select>
<!-- <button id="clr-census-1" type="button" class="btn btn-light btn-sm">clear</button> -->
</div>
</div>
<div class="col-6">
<h4>pick No 2 census year</h4>
<div class="m-3">
<select id="sel-census-2" class="c-select census sel-skinny"></select>
<!-- <button id="clr-census-2" type="button" class="btn btn-light btn-sm">clear</button> -->
</div>
</div>
</div>
<h4 class="mt-5 mb-2">Select Census Fields to compare</h4>
<div class="m-3 d-inline">
<label class="mr-3">Select Fields</label>
<select id="sel-fields" class="c-select sel-medium"></select>
</div>
<div id="comparison-table"></div>
</div><!-- end interface stuff -->
</div>
</div>
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
$(async function () {
// init map
var middlePgh = { lat: 40.4479, lng: -79.9491 };
var mapContainer = document.getElementById('map-container');
var map = L.map(mapContainer, { center: middlePgh, zoom: 10 });
// add streets
var layer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(map);
layer.addTo(map);
// add regions
var geojson = await fetch('regions.geojson').then(body => body.text());
// TDD lmao
var error = false;
try {
geojson = JSON.parse(geojson);
} catch (e) { error = true; }
if (error) {
var errorEl = $('#error');
errorEl.removeClass('hidden');
errorEl.text('regions is not a json yet');
return;
}
// proof
alert(geojson);
});
$(async function () {
// get options and fill in census id/name
var censuses = await fetch('census-files.json').then(body => body.json());
$('#sel-census-1').select2({
data: censuses,
placeholder: '',
allowClear: true
});
$('#sel-census-2').select2({
data: censuses,
placeholder: '',
allowClear: true
});
// get options and fill in fields id/name
var fields = await fetch('census-fields.json').then(body => body.json());
$('#sel-fields').select2({
data: fields,
multiple: true,
maximumSelectionLength: 10
});
/**
* A Note on Schema/Querying here:
*
* I expect that primary entity in DB will be year of census b/c sources.
*
* I expect that there are more fields than max cols for one table, so also
* values table with relationship many-to-one census year & unique in field
* name + year.
*
* In order to get field values, select from years where year is one of the
* two, joining with fields to get the two years' fields.
*
* results look like:
* +------+-------+--------+
* | year | field | value |
* +------+-------+--------+
* | 2010 | rent | high |
* | 2010 | ami | low |
* | 2016 | rent | higher |
* | 2016 | ami | high |
* +------+-------+--------+
*
* the table we want is:
*
* +------+-------+--------+
* | year | 2010 | 2016 |
* +------+-------+--------+
* | rent | high | higher |
* | ami | low | high |
* +------+-------+--------+
*
* This it turns out is weird and made for illegible code
*/
$('#sel-fields').on('change', async function(event) {
// this is just the field names ['rent', 'ami']
var fields = $('#sel-fields').select2('data')
.map(f => f.text)
.sort(sortLowerCaseStrings);
// this needs to be generated with querystring stuff (maybe $)
var qs = 'region=region1&census1=1&census2=2&field=rent&field=ami';
var rows = await fetch('field-values.json?' + qs)
.then(body => body.json());
// adjust for the table we want
// TODO clean this up, i gave up and started making html.
var years = rows.map(r => r.year).filter((v, i, a) => a.indexOf(v) === i);
var trs = fields.map(function (field) {
var rowHtml = '<td>' + field + '</td><td>' + years.map(year => {
// get the value for this year and field
var value = rows
.filter(r => r.year === year && r.field === field).pop();
// un-necessary check of undefined
return value && value.value
? value.value
: '';
}).join('</td><td>') + '</td>';
return rowHtml;
}).join('</tr><tr>');
trs = '<tr>' + trs + '</tr>';
var tableHtml = `
<table class="mt-3 table table-bordered table-hover">
<thead>
<tr>
<th>Year</th>
<th>${years[0]}</th>
<th>${years[1]}</th>
</tr>
</thead>
<tbody>
${trs}
</tbody>
</table>
`;
// reset and refill table div
$('#comparison-table').html('');
$('#comparison-table').html(tableHtml);
});
});
function sortLowerCaseStrings(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return a > b ? 1 : b > a ? -1 : 0;
}
select.sel-skinny {
width: 100px;
}
select.sel-medium {
width: 50%;
}

should probably figure out how to detect clicks on geojson layer

should probably figure out how to center map on searched up layer from searchable select field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment