Published
Edited
Nov 1, 2019
Importers
6 stars
Insert cell
Insert cell
Insert cell
vanMap1 = VegaLite({
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 500,
"height": 300,
"data": {
"values": vanAreaValues2,
"format": {
"type": "topojson",
"feature": "VancouverAreaSize"
}
},
"transform": [{
"lookup": "properties.NAME",
"from": {
"data": {
"values": populations
},
"key": "Area",
"fields": ["Population"]
}
}],
"projection": {
"type": "mercator"
},
"mark": "geoshape",
"encoding": {
"fill": {
"field": "Population",
"type": "quantitative"
},
"stroke": {
"value" : "white"
},
"tooltip":
[
{"field": "properties.NAME", "title": "Name","type": "nominal"},
{"field": "properties.population", "title": "Population", "type": "quantitative"}
]
}
})
Insert cell
vanMapGeoJson = VegaLite({
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"width": 500,
"height": 300,
"data": {
"values": vanAreas,
"format": {
"type": "json",
"property": "features"
}
},
"transform": [{
"lookup": "properties.NAME",
"from": {
"data": {
"values": populations
},
"key": "Area",
"fields": ["Population"]
}
}],
"projection": {
"type": "mercator"
},
"mark": "geoshape",
"encoding": {
"fill": {
"field": "Population",
"type": "quantitative"
},
"stroke": {
"value" : "white"
},
"tooltip":
[
{"field": "properties.NAME", "title": "Name","type": "nominal"},
{"field": "properties.population", "title": "Population", "type": "quantitative"}
]
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md `This is now using a flat structure to avoid the vega-lite issues with nested objects.`
Insert cell
viewof crimeTotals2 = embed({
"data": {
"values": vanCrime2,
},
selection:
{
"highlight": {"type": "single", "empty": "none", "on": "mouseover"},
"select": {"type": "multi"}
},
mark: "bar",
// transform: [
// {filter: {field: "properties.NEIGHBOURHOOD", oneOf: areaselection2.properties.NAME}}
// ],
encoding: {
color: {
condition: {
// scale: { "range": ['#ff0000', '#00aaff']},
field: "Offense Type",
title: "Offense Type",
selection: "select",
type: "nominal"
},
value: "lightgray"
},
"tooltip":
[
{"field": "Offense Type", "title": "Offense Type","type": "nominal"},
{"field": ".Offense", "title": "Offense","type": "nominal"},
// {"field": "properties.NEIGHBOURHOOD", "title": "Neighbourhood", "type": "nominal"}
],
x: {aggregate: "count", field: "Offense Type",type: "quantitative"},
y: {field: "Offense Type", type: "nominal"}
}
})
Insert cell
areaSelection = Generators.observe(notify => {
const areaSelection = (name, value) => notify(value);
vanMapGrey.addSignalListener("areaSelection", areaSelection);
notify(vanMapGrey.signal("areaSelection"));
return (areaSelection) => vanMapGrey.removeSignalListener("areaSelection", areaSelection);
})
Insert cell
selected = {
let newArray=areaSelection.properties;
return newArray;
}
Insert cell
areaselection2 = {
let anames=[];
if(isEmpty(areaSelection)){
return ["Central Business District","West End","Strathcona","Grandview-Woodland","Mount Pleasant","Fairview","Kensington-Cedar Cottage","Stanley Park","Marpole","Kitsilano","Sunset","Oakridge","Kerrisdale","Hastings-Sunrise","Victoria-Fraserview","South Cambie","Killarney","Riley Park","Dunbar-Southlands","Renfrew-Collingwood", "Arbutus Ridge","Musqueam","West Point Grey","Shaughnessy"]
} else {
console.log(areaSelection.properties.NAME);
let anames=areaSelection;
return anames;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
md `This is a dot map of non-violent crimes in Vancouver in June 2016.`
Insert cell
Insert cell
Insert cell
Insert cell
md `Now let's add in a couple of barcharts with crime totals. And add a brush from the Offense Type. I have to make a separate legend for each chart - coming later!`
Insert cell
vanCrimeTotalsType = VegaLite({
hconcat: [
{
"width": 200,
"height": 100,
"data": {
"values": vanCrime2,
"format":
{
type: "json",
"property": "features",
}
},
selection:
{
"highlight": {"type": "single", "empty": "none", "on": "mouseover"},
"select": {"type": "multi"}
},
mark: "bar",
encoding: {
color: {
condition: {
// scale: { "range": ['#ff0000', '#00aaff']},
field: "Offense Type",
title: "Offense Type",
selection: "select",
type: "nominal"
},
value: "lightgray"
},
"tooltip":
[
{"field": "Offense Type", "title": "Offense Type","type": "nominal"},
{"field": "Offense", "title": "Offense","type": "nominal"},
// {"field": "properties.NEIGHBOURHOOD", "title": "Neighbourhood", "type": "nominal"}
],
x: {aggregate: "count", field: "Offense Type",type: "quantitative"},
y: {field: "Offense Type", type: "nominal"}


},
},
{
"width": 200,
"height": 100,
"data": {
"values": vanCrime,
"format":
{
type: "json",
"property": "features",
}
},
selection:
{
"highlight": {"type": "single", "empty": "none", "on": "mouseover"},
"select": {"type": "multi"}
},
mark: "bar",
size: {field: "properties.Offense", type: "quantitative"},
encoding: {
color: {
condition: {
field: "Offense Type",
scale: { "range": ['#ff0000', '#00aaff']},
title: "Offense Type",
selection: "select",
type: "nominal"
},
value: "lightgray"
},
//"tooltip":
// [
// {"field": "properties.Offense Type", "title": "Offense Type","type": "nominal"},
// {"field": "properties.Offense", "title": "Offense","type": "nominal"},
// {"field": "properties.NEIGHBOURHOOD", "title": "Neighbourhood", "type": "nominal"}
// ]
x: {aggregate: "count", field: "Offense",type: "quantitative"},
y: {field: "Offense", type: "nominal"}

},
}]
})
Insert cell
vanCrimeTotalsOffense = VegaLite({
"width": 300,
"height": 100,
"data": {
"values": vanCrime,
"format":
{
type: "json",
"property": "features",
}
},
"selection": {
"highlight": {"type": "single", "empty": "none", "on": "mouseover"},
"select": {"type": "multi"}
},
mark: "bar",
size: {field: "properties.Offense", type: "quantitative"},
encoding: {
color: {
"condition":
{
"selection": "select",
field: "properties.Offense",
type: "nominal",
scale:
{
"domain": ['Break and Enter Commercial', 'Break and Enter Residential/Other', 'Mischief', 'Other Theft', 'Theft from Vehicle', 'Theft of Bicycle', 'Theft of Vehicle'],
"range": ['#FF0000', '#FF8C00', '#FFD700', '#B22222', '#1E90FF', '#7FFFD4', '#3CB371']
}
},
value: "lightgray"
},
// scale:
// {
// "domain": ['Break and Enter Commercial', 'Break and Enter Residential/Other', 'Mischief', 'Other Theft', 'Theft from Vehicle', 'Theft of Bicycle', 'Theft of Vehicle'],
// "range": ['#FF0000', '#FF8C00', '#FFD700', '#B22222', '#1E90FF', '#7FFFD4', '#3CB371']
// },
x: {aggregate: "count", field: "properties.Offense",type: "quantitative"},
y: {field: "properties.Offense", type: "nominal"}
}
})
Insert cell
md `And now the final test. can i get this to render in the api view? Let's try the example. It appears i have to extract the values from the crime csv into a flatter array?`
Insert cell
vl.markCircle({size: 15, opacity: 1})
.data(vanCrime2)
.project(
vl.projection('mercator')
)
.encode(
vl.longitude().fieldQ('lng'),
vl.latitude().fieldQ('lat'),
vl.color().fieldN('Offense Type'),
)
.width(width)
.height(Math.floor(width / 1.75))
.autosize({type: 'fit-x', contains: 'padding'})
.config({view: {stroke: null}})
.render()
Insert cell
md `And now adding the layers of the area values of the neighbourhoods. This is truly compact code. I wonder if the api will let me configure colours more effectively.`
Insert cell
Insert cell
viewof crimeTotals ={
const brush = vl.selectInterval().encodings('*');
const click = vl.selectMulti().encodings('color');
const crimeSelect = vl.selectMulti().fields('Offense Type');
const scale = {
domain: ['Non-vehicular', 'Vehicular'],
range: ['#00aaff', '#ff0000']
};
const bars = new vl.markBar()
.data(vanCrime2)
.encode(
vl.color().value('lightgray')
.if(crimeSelect, vl.color().fieldN('Offense Type').scale(scale).title('Offense Type')),
vl.x().count(),
vl.y().fieldN('Offense Type').scale({domain: scale.domain}).title('Offense Type')
)
.width(300)
.height(50)
.select(crimeSelect)
.render();
bars.value = crimeSelect;
return(bars);
}
Insert cell
crimesSelected = Generators.observe(notify => {
const crimesSelected = (name, value) => notify(value);
crimeTotals.addSignalListener("crimesSelected", crimesSelected);
notify(crimeTotals.signal("crimesSelected"));
return () => crimeTotals.removeSignalListener("crimesSelected", crimesSelected);
})
Insert cell
Insert cell
md `let's make an array that collects all the appropriate data (populations, densities) into the one array for simpflification.`
Insert cell
Insert cell
d3 = require("d3@5")
Insert cell
import {vl} from '@vega/vega-lite-api'
Insert cell
import {vanPopCleaned} from '@drlynb/vancouver-mapping-102'
Insert cell
import {vanAreaValues} from '@drlynb/vancouver-mapping-102'
Insert cell
import {populations} from '@drlynb/vancouver-mapping-102'
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
embed = require('vega-embed@3')
Insert cell
VegaLite = require('vega-embed@6')
Insert cell
Insert cell
function isEmpty( obj ) {
for ( var prop in obj ) {
return false;
}
return true;
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more