Public
Edited
Nov 18, 2023
Insert cell
Insert cell
Insert cell
Insert cell
viewof dashboard = {
const magBarChart = vl
.markBar()
.encode(
vl.x().fieldQ("magnitude").bin({ maxbins: 30 }).title("Magnitude"),
vl.y().count().title(null)
);

const magBarChartLayer = vl
.layer(
magBarChart.params(brush)
.encode(vl.color().value('lightgrey')),
magBarChart.transform(vl.filter(brush))
)
.title("Number of Events by Magnitude")
.data(earthquakes)
.width(width * 0.40)
.height(200);

const depthBarChart = vl
.markBar()
.encode(
vl.x().fieldQ("depth").bin({ maxbins: 30 }).title("Depth"),
vl.y().count().title(null)
);

const depthBarChartLayer = vl
.layer(
depthBarChart.params(brush)
.encode(vl.color().value('lightgrey')),
depthBarChart.transform(vl.filter(brush))
)
.title("Events by Depth (km)")
.data(earthquakes)
.width(width * 0.40)
.height(200);

const eventsPerHour = vl
.markLine()
.encode(
vl.x().fieldT("origintime").timeUnit("hoursdatemonth").title("Date"),
vl.y().count().title(null)
);

const eventsPerHourLayer = vl
.layer(
eventsPerHour.encode(vl.color().value('lightgrey')),
eventsPerHour.transform(vl.filter(brush))
)
.title("Events per Hour")
.data(earthquakes)
.width(width - 40)
.height(150);

return vl
.vconcat(vl.hconcat(
vl.vconcat(magBarChartLayer, depthBarChartLayer), map_view), eventsPerHourLayer)
.resolve({scale: {size: 'independent'}})
.render();
}
Insert cell
selected
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
map_view = {
// base map of New Zealand
const map = vl.markGeoshape({fill: '#ddd', stroke: '#fff', strokeWidth: 1})
.data(vl.topojson(topo).feature('nzl_subunits'))

const circles = vl.markCircle({
fillOpacity: 0.30,
color: "#54E1AE",
stroke: "#008246",
strokeWidth: 1,
strokeOpacity: 0.7
})
.data(earthquakes)
.transform(vl.filter(brush))
.encode(
vl.latitude().fieldQ('latitude'),
vl.longitude().fieldQ('longitude'),
vl.size().fieldQ('magnitude').scale({type: 'pow', range:[0,700]}).legend({title: 'Magnitude'}),
vl.tooltip([{field: 'origintime', type: 'temporal'},
{field: 'magnitude', format: '.1f'},
{field: 'depth', format: '.2f'}])
)
return vl.layer(map, circles)
.project(
vl.projection('transverseMercator').rotate([188, 40.5]).translate(width*0.15,250).scale(1500)
)
.width(width*0.45)
.height(500)
}
Insert cell
brush = vl.selectInterval().name('brush').encodings('x').resolve('intersect')
Insert cell
signal = 'brush'
Insert cell
selected = Generators.observe((notify) => {
const selected = (selection, predicates) => {
const within = earthquakes.filter(d => {
for (const [key, [min, max]] of Object.entries(predicates))
if (isNaN(+d[key]) || d[key] < min || d[key] > max)
return false;
return true;
})
notify(within);
}
dashboard.addSignalListener(signal, selected);
return () => dashboard.removeEventListener(signal, selected);
})
Insert cell
Insert cell
topo = FileAttachment("nz-topo.json").json()
Insert cell
earthquakes = FileAttachment("earthquakes.csv").csv({typed: true})
Insert cell
import {vl} from '@vega/vega-lite-api-v5'
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