Public
Edited
Jun 22
Insert cell
Insert cell
Insert cell
topo = FileAttachment("chicagoNeighborhoods.json").json()
Insert cell
crimes = FileAttachment("chicago_crimes_april_2025@1.csv").csv({typed: true}).then(function (data) {
// The date has a special formating not automatically detected by d3,
// so we need to parse it using UTC rather than local time
const parseDate = d3.utcParse("%m/%d/%Y %I:%M:%S %p");
data.forEach(function(d) {
d.Date = parseDate(d.Date);
});
return data;
})
Insert cell
top_view = {
const map = vl.markGeoshape({ fill: "#ddd", stroke: "#fff", strokeWidth: 1 })
.data(vl.topojson(topo).feature("chicago_neighborhoods"))

const circles = vl.markCircle({
size: 50,
opacity: 0.8
})
.data(crimes)
.transform(vl.filter(brush))
.encode(
vl.latitude().fieldQ("Latitude"),
vl.longitude().fieldQ("Longitude"),
vl.color().fieldN("Primary Type"),
vl.tooltip([
{ field: "Primary Type", type: "nominal", title: "Tipo de Crime" },
{ field: "Date", type: "temporal", format: "%d/%m/%Y %H:%M", title: "Data e Hora" }
])
)

return vl.layer(map, circles)
.project(vl.projection("mercator"))
.width(width * 0.40)
.height(500)
}

Insert cell
viewof dashboard = {

const barras = vl.markBar()
.encode(
vl.x().fieldN('Primary Type').title('Primary Type'),
vl.y().count().title(null),
vl.color().fieldN('Primary Type').title('Crime Type')
)

const barrasLayer = vl.layer(
barras.params(brush).encode(vl.color().value("lightgrey")),
barras.transform(vl.filter(brush))
)
.title("Number of Crimes by Type")
.data(crimes)
.width(300)
.height(200)

const linhas = vl.markLine()
.data(crimes)
.transform(vl.filter(brush))
.encode(
vl.x().fieldT("Date").timeUnit("monthdate").title("Date (month-date)"),
vl.y().count().title(null),
vl.color().fieldN("Primary Type")
)
.width(300)
.height(200)
.title("Number of Crimes by Day")
return vl.hconcat(top_view, vl.vconcat((barras, barrasLayer), linhas)).title({text: "Crimes in Chicago in April 2025", fontSize: 26}) .render()
}
Insert cell
crimes
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
import {vl} from '@vega/vega-lite-api-v5'
Insert cell
brush = vl.selectInterval().name('brush').encodings('x').resolve("intersect")
Insert cell
signal = 'brush'
Insert cell
selected = Generators.observe((notify) => {
const select = selectionValue => {
if (!selectionValue) {
notify(crimes);
return;
}
const filtered = crimes.filter(d => d["Primary Type"] === selectionValue["Primary Type"]);
notify(filtered);
};

dashboard.addSignalListener(signal, select);

return () => dashboard.removeSignalListener(signal, select);
})

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