Published
Edited
Aug 19, 2020
2 stars
Also listed in…
maps and geo
Insert cell
Insert cell
Insert cell
Insert cell
// this cell renders the map above!
viewof map = {
// create the DOM element where the map will be rendered and
// make sure to "yield" it before using it with mapboxgl
let container = html`<div style='height:500px;' />`;
yield container;

// create the map object
let map = new mapboxgl.Map({
container,
center: [-98.35, 39.5],
zoom: 3,
style: carto.basemaps.positron // use Carto's dark matter basemap
});

// sets up the zoom & pitch controls
map.addControl(new mapboxgl.NavigationControl());

// creates the vis object which allows for data styling
const viz = rampInterpolateViz();

// the layer is added to the map to render the data overlay
const layer = new carto.Layer('counties', cartoSource, viz);
layer.addTo(map);

// we can attach a callback for the layer "loaded" event
layer.on('loaded', () => {
mutable layerLoaded = true;
});

// as well as on the "updated" event to watch for changes
layer.on("updated", event => {
mutable layerUpdate = event;
});

// enable event listeners on the data overlay
const interactivity = new carto.Interactivity(layer);

// bind a click event listener to our data overlay that
// will display a popup in response to the event
interactivity.on('featureClick', featureEvent => {
const feature = featureEvent.features && featureEvent.features[0];
if (!feature) return;

const {
coordinates,
variables: { name, pctWithoutInternet }
} = feature;
const coords = featureEvent.coordinates;
const html = getPopupHtml(name.value, pctWithoutInternet.value.toFixed(0));

new mapboxgl.Popup()
.setLngLat([coords.lng, coords.lat])
.setHTML(html)
.addTo(map);
});

// change the style of the feature when mousing over it
interactivity.on('featureEnter', featureEvent => {
featureEvent.features.forEach(feature => {
feature.strokeWidth.blendTo(2, 0);
});
});

// change the style of the feature when mousing away from it
interactivity.on('featureLeave', featureEvent => {
featureEvent.features.forEach(feature => {
feature.strokeWidth.reset();
});
});

// Be careful to clean up the map's resources using \`map.remove()\` whenever
// this cell is re-evaluated. (this is an ObservableHQ thing)
invalidation.then(() => {
interactivity.disable();
layer.remove();
map.remove();
mutable layerLoaded = false;
});

container.value = { map, layer, viz };
return container;
}
Insert cell
Insert cell
Insert cell
Insert cell
scrollZoomEnabled = {
if (!map.map) return false;

if (map.map.scrollZoom.isEnabled() && scrollZoom !== "enabled") {
map.map.scrollZoom.disable();
} else {
map.map.scrollZoom.enable();
}

return map.map.scrollZoom.isEnabled();
}
Insert cell
Insert cell
Insert cell
map.layer && setRamp[visClassification](map.layer)
Insert cell
Insert cell
cartoLayer = () =>
new carto.Layer('counties', cartoSource, rampInterpolateViz())
Insert cell
Insert cell
Insert cell
Insert cell
rampInterpolateViz = () =>
new carto.Viz(`
${commonStyles}
color: ramp(linear($${dataField},3,71),pinkyl)
`)
Insert cell
rampQuantilesViz = () =>
new carto.Viz(`
${commonStyles}
color: ramp(globalQuantiles($${dataField}, 5), pinkyl)
`)
Insert cell
rampEqualIntervalsViz = () =>
new carto.Viz(`
${commonStyles}
color: ramp(globalEqIntervals($${dataField}, 5), pinkyl)
`)
Insert cell
rampManualViz = () =>
new carto.Viz(`
${commonStyles}
color: ramp(buckets($${dataField},[20,30,50]),pinkyl)
`)
Insert cell
rampStandardDevViz = () =>
new carto.Viz(`
${commonStyles}
color: ramp(globalStandardDev($${dataField}, 5), tealrose)
`)
Insert cell
Insert cell
setRamp = ({
setRampInterpolate(layer) {
layer.blendToViz(rampInterpolateViz());
},
setRampQuantiles(layer) {
layer.blendToViz(rampQuantilesViz());
},
setRampEqualIntervals(layer) {
layer.blendToViz(rampEqualIntervalsViz());
},
setRampStandardDev(layer) {
layer.blendToViz(rampStandardDevViz());
},
setRampManual(layer) {
layer.blendToViz(rampManualViz());
}
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cartoSource = new carto.source.SQL(query, {
apiKey: cartoApiKey,
username: cartoUser
})
Insert cell
Insert cell
Insert cell
getPopupHtml = (name, value) => `
<div class="map-popup-container">
<p><strong>${name}</strong></p>
<p>Percentage of households without internet access:</p>
<p class="big">${value}%</p>
</div>`
Insert cell
html`<style>
.map-popup-container {
width: 150px;
display: flex;
flex-direction: column;
}
.map-popup-container p {
margin: 0.2rem;
line-height: 0.9rem;
}
.map-popup-container p.big {
margin-top: 0.5rem;
font-weight: bold;
font-size: 2rem;
}
</style>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
carto = {
const c = await require("@carto/carto-vl@1.4.6/dist/carto-vl.min.js");
c.setDefaultAuth({
username: cartoUser,
apiKey: cartoApiKey
});
return c;
}
Insert cell
mapboxgl = {
const gl = await require("mapbox-gl@1.12.0");
if (!gl.accessToken) {
gl.accessToken =
'pk.eyJ1IjoiY2hlbnJpY2siLCJhIjoiLVhZMUZZZyJ9.HcNi26J3P-MiOmBKYHIbxw';
}
return gl;
}
Insert cell
mapboxglCSS = html`<link href='${await require.resolve(
"mapbox-gl@1.12.0/dist/mapbox-gl.css"
)}' rel='stylesheet' />`
Insert cell
import { checkbox, radio } from "@jashkenas/inputs"
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