Published
Edited
May 21, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
crimeBars.addSignalListener("offenseSelect", function(name, value){
if (value == null)
mutable type = null
else
mutable type = value.Offense
})
Insert cell
Insert cell
mutable type = null
Insert cell
Insert cell
bSelection = {
if(isEmpty(type)){
return Array.from(new Set(vanCrime2.map(d=> d.offense)))
} else {
return type}}
Insert cell
function isEmpty(obj){
for (var prop in obj){
return false;
}
return true;
}
Insert cell
Insert cell
viewof crimeTime = V({
width: 600,
height: 200,
config: {
background: "white"
},
data: {values: vanCrime2},

mark: "line",
selection: {timeBrush: { type: "interval", encodings: ["x"]}
},

encoding: {
x: {field: "Date", type: "temporal"},
y: {field: "*", type: "quantitative", aggregate: "count"},
color: {field: "Offense Category", type: "nominal", scale: {domain: Array.from(new Set(vanCrime2.map(d => d['Offense Category']))), range: ["#4e79a7","#f28e2c","#e15759","#76b7b2"]}}
}
})
Insert cell
Insert cell
crimeTime.addSignalListener("timeBrush", function(name, value){
if (value == null)
mutable time = null
else
mutable time = value
})
Insert cell
mutable time = null
Insert cell
Insert cell
epochParse = d3.timeParse("%Q");
Insert cell
Insert cell
dateFormat = d3.timeFormat("%m/%d/%y")
Insert cell
Insert cell
timeParse = d3.timeParse("%m/%d/%y")
Insert cell
TSelection = {
if(isEmpty(mutable time)){
return d3.extent(vanCrime2, d => dateFormat(timeParse(d.Date)))
} else {
return time.Date.map(d=>dateFormat(epochParse(d)))
}}
Insert cell
Insert cell
Insert cell
Insert cell
viewof CrimeMap = {
let container = DOM.element('div', { style: `width:${width}px;height:${width/2}px` });
yield container
let map = L.map(container);
let osmLayer = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png', {
attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
let VanAreasLayer = L.geoJson(vanAreas, { //instantiates a new geoJson layer using built in geoJson handling
weight: 2, //Attributes of polygons including the weight of boundaries and colors of map.
color: "#432",
}).bindPopup(function (Layer) { //binds a popup when clicking on each polygon to access underlying data
return Layer.feature.properties.NAME;
}).addTo(map); //Adds the layer to the map.
//This function formats our geojson file to be commensurate with leaflet. Geojson files are formatted using
//[lon, lat], we need to reverse this. we are creating an arrray of "feature(s)", that hold two lat lon coordinates
// and we reverse them. We then concatenate (or add on) final value which is the intensity. This is the strength of
// of each of these points. This heat map works by overlapping points and the added intensity of each dot changes the // color based on hot spots.
let crimePoints = vanCrime.features.map(feature =>
feature.geometry.coordinates.slice().reverse().concat([0.5]));
//We add this layer to the map.
let crimeLayer = heatLayer(crimePoints).addTo(map);
map.fitBounds(VanAreasLayer.getBounds());
}
Insert cell
Insert cell
Insert cell
Insert cell
vanCrimeFiltered = vanCrime.features.filter( d=> bSelection.includes(d.properties.Offense))
.filter(d=> timeParse(d.properties.Date) >= timeParse(TSelection[0]) &&
timeParse(d.properties.Date) <=timeParse(TSelection[1]))
Insert cell
Insert cell
FilteredGeoCrimes={
return new Object({type: "FeatureCollection", features: vanCrimeFiltered})
}
Insert cell
Insert cell
Insert cell
// html`<div style="
// background: #fff;
// display: grid;
// height: ${screen.height / screen.width * 100}vw;
// grid-template-areas:
// 'a b'
// 'a b'
// 'c b'
// 'c b';
// grid-gap: 10px;
// ">
// <div name="a" style="grid-area:a;border:solid 1px #ccc;">${viewof crimeBars}</div>
// <div name="b" style="grid-area:b;border:solid 1px #ccc;">${viewof CrimeMap}</div>
// <div name="c" style="grid-area:c;border:solid 1px #ccc;">${viewof crimeTime}</div>
// </div>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md` ## Loading and Preparing Data`
Insert cell
vanCrime = FileAttachment("vanCrime.json").json()
Insert cell
vanAreas = FileAttachment("VanAreas.json").json()
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more