Skip to content

Instantly share code, notes, and snippets.

@renauld94
Created October 22, 2018 09:53
Show Gist options
  • Select an option

  • Save renauld94/ba7aa36c76d337d52d1e137bdd2ea410 to your computer and use it in GitHub Desktop.

Select an option

Save renauld94/ba7aa36c76d337d52d1e137bdd2ea410 to your computer and use it in GitHub Desktop.
fresh block
license: mit
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Sanisphere coverage pharmacies and Universe">
<meta name="author" content="Simon Renauld>nan
<link rel="icon" href="favicon.icon">
<title>Sanisphere Coverage</title>
<!--.Leaflet, Dynamic Charting, Crossfilter, DataTables, MarkerCluster, core JavaScript -->
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="bower_components/crossfilter/crossfilter.min.js" charset="utf-8"></script>
<script src="bower_components/dcjs/dc.min.js" charset="utf-8"></script>
<script src="bower_components/leaflet.markercluster/leaflet.markercluster.js"></script>
<script src="plugins/L.D3SvgOverlay.min.js"></script>
<script src="plugins/leaflet-bing-layer.js"></script>
<script src="plugins/leaflet-search.js"></script>
<script type="text/javascript" src="plugins/labs-common.js"></script>
<script type="text/javascript" src="geojson/ward.js"></script>
<!-- Datasets SHAPEFILES to geojson-->
<script src="pharmacy.geojson.js"></script>
<script src="hospital.geojson.js"></script>
<!-- Bootstrap core CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Leaflet, Dynamic Charting, Crossfilter, DataTables, MarkerCluster, core CSS -->
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<link rel="stylesheet" href="bower_components/dcjs/dc.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css" integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA==" crossorigin=""/>
<link rel="stylesheet" href="bower_components/leaflet.markercluster/dist/MarkerCluster.Default.css" />
<link rel="stylesheet" href="css/leaflet-search.css" />
<link rel="stylesheet" href="css/style.css" />
<style>
.leaflet-marker-icon {
color: #fff;
font-size: 16px;
line-height: 16px;
text-align: center;
vertical-align: middle;
box-shadow: 2px 1px 4px rgba(0,0,0,0.3);
border-radius: 8px;
border:1px solid #fff;
}
.search-tip b {
color: #fff;
}
.pharmacy.search-tip b,
.pharmacy.leaflet-marker-icon {
background: #f6f
}
.hospital.search-tip b,
.hospital.leaflet-marker-icon {
background: #66f
}
.search-tip {
white-space: nowrap;
}
.search-tip b {
display: inline-block;
clear: left;
float: right;
padding: 0 8px;
margin-left: 4px;
}
</style>
<style>
.info { padding: 6px 8px; font: 14px/16px Arial, Helvetica, sans-serif; background: white; background: rgba(255,255,255,0.8); box-shadow: 0 0 15px rgba(0,0,0,0.2); border-radius: 5px; } .info h4 { margin: 0 0 5px; color: #777; }
.legend { text-align: left; line-height: 28px; color: #555; } .legend i { width: 18px; height: 18px; float: left; margin-right: 8px; opacity: 0.7; }</style>
</head>
<body>
<!-- Custom styles for this template -->
<link href="css/construxn.css" rel="stylesheet">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class='col-md-7'>
<div class="col-md-15">
</div>
<div class='row'>
<div id='map'></div>
</div>
</div>
</style>
</div>
<div class='col-md-2' id="District-chart">
<h6>District
<a class="reset" href="javascript:zipcodeChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
</h6>
</div>
<div class='col-md-3'>
<div class='row col-md-12' id="permit_type-chart">
<h6>City
<a class="reset" href="javascript:permitTypesChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
</h6>
</div>
<div class='row col-md-12' id="city-chart">
<h6>Province
<a class="reset" href="javascript:citiesChart.filterAll();dc.redrawAll();" style="display: none;">reset</a>
</h6>
</div>
</div>
<script type="text/javascript">
//////////////////////////////////////////////////////////////////////////////////////////////////
// Create a new group to which we can (later) add or remove our markers / spots on the map
var markersLayer = new L.LayerGroup(); // NOTE: Layer is created here!
/////////////////////////////////////////////////////
// Create a new cluster group to which we can (later) add or remove our markers / spots on the map
var clusterLayer = new L.MarkerClusterGroup();
////////////////////////////////////////////////////////////////////////////////////////////
// Set up the base map tile layers (this is the terrain, imagery, etc)
///////////////////////////////////////////////////////////////////////////////////////////
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> ',
maxZoom: 18
});
var cartodb_light = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: 'Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a> ',
maxZoom:18
});
var cartodb_dark = L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',{
attribution: 'Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>',
maxZoom:18
});
// Our basemaps (tile layers)
var baseMaps = {
"OpenStreetMap": cartodb_light,
"Esri Basemaps": cartodb_dark,
"OpenStreetMap": osm
};
// Our overlays
var overlays = {
"Clustered Markers": clusterLayer,
"Individual Markers": markersLayer
};
//////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize the Leaflet map and set an initial location and zoom level
////////////////////////////////////////////////////////////////////////////////////////////////////
var map = L.map('map', {
center: [10.762622, 106.660172],
zoom: 10,
layers: [cartodb_light, clusterLayer]
}),
///////////////////////////////////////////////////////////////
/// ADD HOSPITAL AND PHARMACIES SEARCH MULTI LAYER
/////////////////////////////////////////////////////////////////
geojsonOpts = {
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: L.divIcon({
className: feature.properties.amenity,
iconSize: L.point(16, 16),
html: feature.properties.amenity[0].toUpperCase(),
})
}).bindPopup(feature.properties.amenity+'<br><b>'+feature.properties.name_full+'<br><b>'
+feature.properties.id+'</b>');
}
};
var poiLayers = L.layerGroup([
L.geoJson(pharmacy, geojsonOpts),
L.geoJson(hospital, geojsonOpts)
])
.addTo(map);
L.control.search({
layer: poiLayers,
initial: false,
propertyName: 'name_full',
buildTip: function(text, val) {
var type = val.layer.feature.properties.amenity;
return '<a href="#" class="'+type+'">'+text+'<b>'+type+'</b></a>';
}
})
.addTo(map);
var ward = [];
var wardOverlay = L.d3SvgOverlay(function(sel, proj) {
var upd = sel.selectAll('path').data(ward);
upd.enter()
.append('path')
.attr('d', proj.pathFromGeojson)
.attr('stroke', 'red')
.attr('fill-opacity', '0.2');
upd.attr('stroke-width', 1 / proj.scale);
});
/////////////////////////////////////////////////////////
// control that shows state info on hover of the ward
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info');
this.update();
return this._div;
};
info.update = function (props) {
this._div.innerHTML = '<h4>Geography</h4>' + (props ?
'<b>' + props.ADM2_NAME + '</b><br />'+ props.ADM3_NAME + '</b><br />' : 'Hover over a ward');
};
info.addTo(map);
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
geojson = L.geoJson(warddata, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////// DISPLAY and PROJECT GEOJSON SHAPEFILES WARDS AND DISTRICTS
////////////////////////////////////////////////////////////////////////////////////////////////////////////
var province = [];
var provinceOverlay = L.d3SvgOverlay(function(sel, proj) {
var upd = sel.selectAll('path').data(province);
upd.enter()
.append('path')
.attr('d', proj.pathFromGeojson)
.attr('stroke', 'black')
.attr('fill-opacity', '0.1');
upd.attr('stroke-width', 1 / proj.scale);
});
//////////////////////// Add the control base layers to the map ////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//L.control.layers(baseMaps, overlays).addTo(map);
L.control.layers(baseMaps, overlays).addTo(map);
L.control.layers({"province": provinceOverlay, "ward": wardOverlay}).addTo(map);
d3.json("geojson/ward.geo.json", function(data) { ward = data.features; wardOverlay.addTo(map) });
d3.json("geojson/province.geo.json", function(data) { province = data.features; provinceOverlay.addTo(map) });
////////////////////////CHARTS!!!//////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize our dc.js charts, passing the DOM Id in which we want the chart rendered as an argument
var citiesChart = dc.rowChart("#city-chart");
var zipcodeChart = dc.rowChart("#District-chart");
var permitTypesChart = dc.rowChart("#permit_type-chart");
// A common color for all of the bar and row charts
var commonChartBarColor = '#b3d9ff';
// This is where we will hold our crossfilter data
var xdata = null;
var all = null;
var cities = null;
var locations = null;
// Called when dc.js is filtered (typically from user click interaction)
var onFilt = function(chart, filter) {
updateMap(locations.top(Infinity));
};
// Updates the displayed map markers to reflect the crossfilter dimension passed in
var updateMap = function(locs) {
// clear the existing markers from the map
markersLayer.clearLayers();
clusterLayer.clearLayers();
locs.forEach( function(d, i) {
if (d.mapped_location.latitude!=null && d.mapped_location.latitude!=undefined) {
// add a Leaflet marker for the lat lng and insert the application's stated purpose in popup
var mark = L.marker([d.mapped_location.latitude, d.mapped_location.longitude]).bindPopup(d.purpose);
markersLayer.addLayer(mark);
clusterLayer.addLayer(mark);
}
});
};
// d3's JSON call to grab the JSON data
d3.json("http://data.nashville.gov/resource/3h5w-q8b7.json?", function(error, data) {
// used by d3's dateFormat to parse the date correctly
var dateFormat = d3.time.format("%Y-%m-%dT%H:%M:%S");
// add map markers to map layer
data.forEach( function(d,i) {
d.date_e = dateFormat.parse(d.date_entered);
d.date_i = dateFormat.parse(d.date_issued);
// create a map marker if the lat lng is present
if (d.mapped_location.latitude!=null && d.mapped_location.latitude!=undefined) {
d.ll = L.latLng(d.mapped_location.latitude, d.mapped_location.longitude);
var mark = L.marker([d.mapped_location.latitude, d.mapped_location.longitude]);
markersLayer.addLayer(mark);
clusterLayer.addLayer(mark);
}
});
// Construct the charts
xdata = crossfilter(data);
all = xdata.groupAll();
// Define the crossfilter dimensions
cities = xdata.dimension(function (d) { return d.city; });
locations = xdata.dimension(function (d) { return d.ll; });
var zipcodes = xdata.dimension(function (d) { return d.zip; });
var permitTypes = xdata.dimension(function (d) { return d.permit_type_description; });
// Start constructing the charts and setting each chart's options
citiesChart.width($('#city-chart').innerWidth()-30)
.height(250)
.colors(commonChartBarColor)
.margins({top: 10, left: 20, right: 10, bottom: 20})
.group(cities.group())
.dimension(cities)
.elasticX(true)
.on("filtered", onFilt);
zipcodeChart.width($('#District-chart').innerWidth()-30)
.height(window.innerHeight - 50)
.colors(commonChartBarColor)
.margins({top: 10, left: 10, right: 10, bottom: 20})
.group(zipcodes.group())
.dimension(zipcodes)
.elasticX(true)
.on("filtered", onFilt);
permitTypesChart.width($('#permit_type-chart').innerWidth()-30)
.height(400)
.colors(commonChartBarColor)
.margins({top: 10, left: 20, right: 10, bottom: 20})
.group(permitTypes.group())
.dimension(permitTypes)
.elasticX(true)
.on("filtered", onFilt);
dc.renderAll();
});
</script>
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment