Published
Edited
Feb 20, 2022
1 star
Insert cell
# Birmingham Ward Map with javascript Action on Selection
The purpose of this notebook is to draw a map from public data and demonstrate execution of a javascript code (not just a hyperlink) upon ward selection.

This can be expanded to select from a table using data from the selected ward.

Thanks to @mootari for some help, see
https://observablehq.com/@mootari/vega-lite-input-widget
Insert cell
html`<h2 id = "outputField">Placeholder for selected ward data</h2>`
Insert cell
viewof selection = {
// The field that should become the selection value.
const selectionField = "properties";
const bhamMap = vl.markGeoshape({"strokeWidth": "2", "stroke": "White",})
.data(bhamWardBoundaries)
.params([
{ name: "selected", select: { type: "point", fields: [selectionField]} },
])
// .transform({
// "calculate": "'https://www.google.com/search?q=' + datum.properties.WD21NM", "as": "url"
// })
.encode(
vl.tooltip({"field": "properties.WD21NM"}),
// This would be the alternative - to follow a hyperlink
//vl.href({"field": "url", "type": "nominal"})
)
.width(500)
.height(500);

// .render() returns a Promise that resolves to the chart element.
const element = await bhamMap.render();
// The whole Vega view instance.
const view = element.value;
// Wrap the Vega element so that we can set our own .value property.
const input = html`<div>${element}`;

// Listen to selection changes.
view.addSignalListener("selected", (signal, selection) => {
// Vega rewrites "." in the field path to "\."
const key = selectionField.replace(".", "\\.");
const items = selection[key];
// Update the viewof value and notify the Observable Runtime.
input.value = items[0].WD21NM
const outputField = document.querySelector('#outputField');
outputField.innerHTML = items[0].WD21CD + ":" + items[0].WD21NM;
//outputField.style.display = 'none';
input.dispatchEvent(new Event("input"));
});

return input;
}
Insert cell
// Ward to Local Authority District (December 2021) Lookup in the United Kingdom
// Downloaded from https://geoportal.statistics.gov.uk/documents/ons::ward-to-local-authority-district-december-2021-lookup-in-the-united-kingdom/about
wardToLAsWorkbook = FileAttachment("WD21_LAD21_UK_LU.xlsx").xlsx()

Insert cell
// Filter the local authority lookup to just those for Birmingham
bhamWardToLAs = wardToLAsWorkbook.sheet(0, { headers: true }).filter(d => d.LAD21NM === 'Birmingham')
Insert cell
// Simplify the above object array to just get just the ward code from each object
bhamWardCodes = bhamWardToLAs.map(({ WD21CD }) => WD21CD)
Insert cell
// Ward Boundaries (December 2021) BSC (Super Generalised - not high res)
// Downloaded from https://geoportal.statistics.gov.uk/datasets/ons::wards-december-2021-uk-bsc/about
ukWardBoundaries = FileAttachment("Wards_(December_2021)_UK_BSC.geojson").json()
Insert cell
// Birmimngham ward boundaries, i.e. UK boundaries where the ward code is a Birmingham ward code

bhamWardBoundaries = ukWardBoundaries.features.filter(feature => bhamWardCodes.includes(feature.properties.WD21CD))
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