Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof cPlotDensity = {
const selectType = vl
.selectPoint("selected_pt")
.on("click") // select on click
.fields("Offense") // select all crimes of the same type
//.resolve("intersect")
.toggle(true); // allow for multi-select (on by default) with shift-click

const selectBrush = vl.
selectInterval()
//.encodings('x')
.resolve("intersect");


const sPlotFaceted = vl
.markCircle({ stroke: "black", strokeWidth: 1 })
.width(400)
.params(selectBrush,selectType)
.title({
text: "NonViolent Crime Totals by Neighbourhoods Summer 2016",
subtitle: headerString
})
// .title(headerString)
.data(crimeDensityTotal)

.transform(
vl.filter({ field: "NEIGHBOURHOOD", oneOf: mapSelections }),
//vl.filter(selectType),
vl.joinaggregate({ op: "count", field: "datum.Offense", as: "Ctotals" })
)
.encode(
vl.facet({ field: "Offense Type", type: "ordinal" }),
vl
.size()
.fieldQ("population")
.legend({ orient: "right" })
.scale({ domain: [0, 50000] }),
vl.tooltip([
{ field: "Offense", type: "nominal" },
{
field: "Offense",
type: "quantitative",
aggregate: "count",
title: "Total"
},
{ field: "NEIGHBOURHOOD", type: "nominal" },
{
field: "population",
type: "quantitative",
title: "Population"
},
{
field: "density",
type: "quantitative",
title: "Density",
format: ".3f"
},
{
title: "Overall Crime rate (crimes/person)",
type: "quantitative",
field: "Ctotals",
format: ".2f"
}
]),
vl.opacity()
.value(0.1)
.if(selectType, vl.value(.9)),
vl
.y()
.fieldQ("sqm")
.title("Square M per person")
.scale({ domain: [0, 500] }),
vl
.x()
.fieldQ("Offense")
.aggregate("count")
.scale({ type: "log" })
.title("Total Crimes"),
vl
.color()
.scale({ range: OffenseCatColors })
.legend({ orient: "right" })
.if( selectBrush, vl.fieldN("Offense Category")).value("lightgrey")
);

const crimeTotals = vl
.markBar()
.width(250)
.data(crimeDensityTotal)
.params(selectType)
.title("Crime Total Offenses Summer 2016")
.transform(
vl.filter({ field: "NEIGHBOURHOOD", oneOf: mapSelections }),
//vl.filter(selectType),
vl.filter(selectBrush)
)
.encode(
vl.y().fieldN("Offense").scale({ domain: OffenseTypes }),
vl.x().fieldQ("*").aggregate("count"),
//.scale({ domain: [0, 4400] })
vl.color().fieldN("Offense Category").scale({ range: OffenseCatColors }),
vl.opacity().if(selectType, vl.value(0.99)).value(0.1), // if point selected, use opacity 0.7, otherwise 0.1
);

const crimeRatios = vl
.markBar()
.width(250)
.data(crimeDensityTotal)
// .params(selectType)
.title("Crime Totals by Category and Neighbourhood")
.transform(
vl.filter({ field: "NEIGHBOURHOOD", oneOf: mapSelections }),
vl.filter(selectType),
vl.filter(selectBrush)//
//vl.calculate(vl.count({ field: "*", aggregate: "count" })).as("cpRatio")
)
.encode(
vl.y().fieldN("NEIGHBOURHOOD"),
vl.x().fieldQ("Offense").aggregate("count"),
//.scale({ domain: [0, 4400] })
vl.color().fieldN("Offense Category").scale({ range: OffenseCatColors })
// .if(selectedBar, vl.fieldN("Offense Category"))
// .value("grey"), // if point selected, use default color, otherwise grey
//vl.opacity().if(selectType, vl.value(0.99)).value(0.4) // if point selected, use opacity 0.7, otherwise 0.1
);

return vl
.vconcat(sPlotFaceted, vl.hconcat(crimeTotals, crimeRatios))
.render();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
clicked = Generators.observe((notify) => {
const clicked = (event, { datum }) => notify(datum);
threeCViews.addEventListener("click", clicked);
return () => threeCViews.removeEventListener("click", clicked);
})
Insert cell
Insert cell
vOffenses = Array.from(new Set(vanCrime2.map((d) => d.Offense)))
Insert cell
Insert cell
Insert cell
#### Getting the `nHood` selection from the map to filter the charts
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mutable selectedString = ""
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
timeParse = d3.timeParse("%m/%d/%y")
Insert cell
dateFormat = d3.timeFormat("%m/%d/%y")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
heatLayer = L, require('leaflet.heat').catch(() => L.heatLayer)
Insert cell
embed = require("vega-embed@6")
Insert cell
mutable selectedMap = ["warmgreys"]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
vanAreas = FileAttachment("VanAreas.json").json()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
async function crimeRatesList(carray)
{
let i=0;
let j=0;
let k=0;
let z=0;
let nullIndx=0;
const cleanedCRates=[];
let ca = deepCopy(carray);
let cRates = deepCopy(crimeRates); // the neighbourhood stats
let hCrimes = [];
let oCrimes = [];
let tempO =[];
let tempC =[{name:" ",total:0}];

let curCrime ="";
for(i=0;i < cRates.length;i++) //set up all the basic data in the neighbourhood areas
{
j=0;
while (j < vanAreas.features.length)
{
if (cRates[i].name == vanAreas.features[j].properties.NAME)
{
cRates[i].density = +vanAreas.features[j].properties.density;
cRates[i].population = +vanAreas.features[j].properties.population;
cRates[i].sqm = vanAreas.features[j].properties.localArea/vanAreas.features[j].properties.population;
};
j++;
}
}
// now iterate through the list of all crimes, find the neighbourhood and the offense type
// and calculate totals and rates as # crimes/population

//hCrimes = ca.filter(el => el.NEIGHBOURHOOD === "Sunset");
let catName = '';
let cat={};
let obj={};
let cType = "";

//for(i=0;i<cRates.length;i++)
for(i=0;i<cRates.length;i++)
{
hCrimes = ca.filter(el => el.NEIGHBOURHOOD === cRates[i].name);
//console.log(hCrimes[i]);
//console.log(crimeProps[8]);
for (j=0;j<crimeProps.length;j++)
{
oCrimes = hCrimes.filter( d => d.Offense === crimeProps[j].o);
//console.log(crimeProps[j].o, " ", crimeProps[j].ccat, " ", crimeProps[j].ctype, " ",oCrimes.length);
cRates[i].ctotal += oCrimes.length;
//console.log(cRates[i].ctotal);
cRates[i].crimes[j].cnt = oCrimes.length;
cRates[i].crimes[j].oname = crimeProps[j].o;
cRates[i].crimes[j].cat = crimeProps[j].ccat;
cRates[i].crimes[j].type = crimeProps[j].ctype;
cRates[i].crimes[j].crimeRate = cRates[i].crimes[j].cnt/cRates[i].population
cRates[i].crimes[j].percentOfCrimes = cRates[i].crimes[j].cnt/cRates[i].ctotal;
}
console.log(cRates[i].name);
if(Object.is(cRates[i].name,null))
{
nullIndx = i;
console.log(nullIndx);
const cleanedCRates = cRates.slice(0,nullIndx);
console.log(cleanedCRates);
cRates = cleanedCRates;
}
}
return(cRates);
}
Insert cell
Insert cell
Insert cell
allCrimeRates =
{
let i=0;
let j=0;
let k=0;
let runs =0;
let cnt=0;
let oCnt =0;
let c=0;
let tempC = [];
const test = [];
let len = crimeAreaTotals.length;
const newCR = crimeAreaTotals.map((d) => ({ ...d, Area: d.name }));

// areaCrimeCrimeRate is the ratio of all of crimes in this area (area total) to population.
// areaOffenseRatio is the % this offense is of all crimes in this area.
for ( i=0;i<newCR.length;i++ )
{
for (k=0;k<newCR[i].crimes.length; k++)
{
//console.log("i: ",i, " K: ", k, " cnt: " , cnt);
if (newCR[i].name != null)
{
test[cnt] = {area: newCR[i].name, pop: newCR[i].population};
//test[cnt].area = newCR[i].name;
test[cnt].population = newCR[i].population;
test[cnt].density = newCR[i].density;
test[cnt].areaTotal = newCR[i].ctotal;
if( test[cnt].population >0)
test[cnt].areaCrimeRate = test[cnt].areaTotal/test[cnt].population;
else
test[cnt].areaCrimeRate = undefined;
test[cnt].offense = newCR[i].crimes[k].oname;
test[cnt].offenseCnt = newCR[i].crimes[k].cnt;
test[cnt].offenseCat = newCR[i].crimes[k].cat;
//console.log(test[cnt].area," , ", test[cnt].offense, ", ", test[cnt].offenseCat);
test[cnt].offenseType = newCR[i].crimes[k].type;
test[cnt].areaOffenseRatio = test[cnt].offenseCnt/test[cnt].areaTotal;
test[cnt].areaOffenseCrimeRate = test[cnt].offenseCnt/test[cnt].population;
cnt++;
}
}
}
// now we will calculate the proper rates.
//overallOffenseRate is the rate over all offenses of this kind over all meighbourhoods.
//hCrimes = ca.filter(el => el.NEIGHBOURHOOD === "Sunset");
for (i=0;i<vOffenses.length; i++)
{
oCnt=0;
tempC = test.filter(el => el.offense === vOffenses[i]);
//console.log("Offense: ", vOffenses[i]);
for( j=0;j<tempC.length;j++)
{
oCnt += tempC[j].offenseCnt;
//console.log(tempC[j].area, ": ", "Number: ", tempC[j].offenseCnt, "Running Total: ", oCnt);
};
for( j=0;j<tempC.length;j++)
{
tempC[j].overallOffenseTotal = oCnt;
//console.log(tempC[j].area, ": ", "Number: ", tempC[j].offenseCnt, "Running Total: ", oCnt);
};
}
return(test);
}
Insert cell
Insert cell
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