Skip to content

Instantly share code, notes, and snippets.

@jonsadka
Last active January 17, 2017 05:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonsadka/e4e5d77d791dcb622f8b628f08adecef to your computer and use it in GitHub Desktop.
Save jonsadka/e4e5d77d791dcb622f8b628f08adecef to your computer and use it in GitHub Desktop.
Mapping LA Part 2
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src='https://api.mapbox.com/mapbox-gl-js/v0.31.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v0.31.0/mapbox-gl.css' rel='stylesheet' />
<style>
/* apply a natural box layout model to all elements, but allowing components to change */
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin:0;position:fixed;top:0;right:0;bottom:0;left:0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: #1A2D37;
font-size: 12px;
}
#map {
position:absolute;
width: 100%;
height: 100%;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
}
#property-card {
position: fixed;
height: 400px;
width: 300px;
top: 8px;
left: 8px;
border-radius: 4px;
background-color: #F2F2F4;
overflow: scroll;
}
.section {
background-color: #FFFFFF;
border-radius: 4px;
margin: 8px;
padding: 5px;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="property-card"></div>
<script>
function buildUrl(url, queryParams) {
url += '?';
queryParams.forEach(function(param){
url += `${param}&`
})
return url.slice(0, -1);
}
</script>
<script>
//Setup mapbox-gl map
mapboxgl.accessToken = 'pk.eyJ1Ijoiam9uc2Fka2EiLCJhIjoiY2l4ejkzM3FuMDA0bzMycDl2ZXE0cGw2byJ9.YVf_mtIw3xABynhjwojKQg';
const map = new mapboxgl.Map({
center: [-118.4, 34],
container: 'map', // id of the container
pitch: 40,
scrollZoom: true,
style: 'mapbox://styles/jonsadka/cixzpqzbj003g2srjakw769o5',
zoom: 9
})
map.addControl(new mapboxgl.NavigationControl())
function project(d) {
const position = getLatLong(d);
if (position) {
return map.project(position);
}
}
function getLatLong(d) {
const longitude = +d.center_lon || (+d.location_1 || {}).longitude;
const latitude = +d.center_lat || (+d.location_1 || {}).latitude;
if (longitude && latitude) {
return new mapboxgl.LngLat(longitude, latitude);
}
}
const container = map.getCanvasContainer();
const canvas = d3.select(container).append('canvas').node();
const boundingBox = document.body.getBoundingClientRect();
canvas.width = boundingBox.width;
canvas.height = boundingBox.height;
const context = canvas.getContext('2d');
const url06To16 = 'https://data.lacounty.gov/resource/hvzm-fn38.json';
d3.queue()
.defer(d3.json, buildUrl(url06To16, [
'$where=units > 22', '$limit=20000', 'yearbuilt=1989'
]))
.await(initialRender)
let diagram;
function initialRender(error, propertyData) {
if (error) return console.warn(error);
console.log(
propertyData.length,
propertyData[0],
getLatLong(propertyData[0]),
project(propertyData[0])
)
propertyData.map(function(property){
const point = project(property);
if (point) {
property.computed = property.computed || {};
property.computed.x = point.x;
property.computed.y = point.y;
}
return property;
})
const voronoi = d3.voronoi()
.x(function(d){ return d.computed.x})
.y(function(d){ return d.computed.y});
diagram = voronoi(propertyData);
// Initial render
render(propertyData);
// re-render our visualization whenever the view changes
map.on('viewreset', function() {
context.clearRect(0, 0, boundingBox.width, boundingBox.height);
propertyData.map(function(property){
const point = project(property);
if (point) {
property.computed = property.computed || {};
property.computed.x = point.x;
property.computed.y = point.y;
}
return property;
})
diagram = voronoi(propertyData);
render(propertyData);
})
map.on('move', function() {
context.clearRect(0, 0, boundingBox.width, boundingBox.height);
propertyData.map(function(property){
const point = project(property);
if (point) {
property.computed = property.computed || {};
property.computed.x = point.x;
property.computed.y = point.y;
}
return property;
})
diagram = voronoi(propertyData);
render(propertyData);
})
let lastProperty;
map.on('mousemove', function(event) {
const voronoiCell = diagram.find(event.point.x, event.point.y);
const propertyCard = document.getElementById('property-card');
if (lastProperty !== voronoiCell.data.propertylocation) {
lastProperty = voronoiCell.data.propertylocation;
var content = document.createElement('div');
content.innerText = lastProperty;
content.className = 'section';
propertyCard.append(content);
propertyCard.scrollTop = propertyCard.scrollHeight;
}
})
}
function render(data) {
const propertyValues = data.reduce(function(_propertyValues, property){
if (property.roll_totlandimp) {
_propertyValues.push(+property.roll_totlandimp);
}
return _propertyValues;
}, []);
const propertyValueColor = d3.scaleLog()
.range(['hsl(62,100%,90%)', 'hsl(228,30%,20%)'])
.domain([d3.quantile(propertyValues, .01), d3.quantile(propertyValues, .99)])
.interpolate(d3.interpolateHcl);
context.clearRect(0, 0, boundingBox.width, boundingBox.height);
data.forEach(function(property, idx) {
context.strokeStyle = '#F2F2F4';
if (property.computed) {
context.fillStyle = propertyValueColor(+property.roll_totlandimp);
context.beginPath();
context.arc(property.computed.x, property.computed.y, 4, 0, Math.PI * 2);
context.fill();
context.stroke();
}
})
}
</script>
</body>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment