Public
Edited
Mar 27, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
overlayLayer = () => {
return new deck.TextLayer({
id: 'overlay-layer',
data: [
{
text: 'Filecoin Provider Power Growth',
position: [ -200, -120 ],
size: 24
},
{
text: dateFns.format(viewof elapsed.value, 'yyyy MMM dd'),
position: [ -50, 115 ],
size: 32
},
{
text: 'Provider.Quest',
position: [ 160, -135 ],
size: 14
}
],
getPosition: d => d.position,
getText: d => d.text,
getSize: d => d.size,
getColor: [ 255, 255, 255, 255 ],
getTextAnchor: 'start'
})
}
Insert cell
Insert cell
deck = require.alias({
// optional dependencies
h3: {}
})('deck.gl@latest/dist.min.js')
Insert cell
Insert cell
Insert cell
initialViewState = ({
latitude: 30,
longitude: 25,
zoom: 1.05,
bearing: 0,
pitch: 0,
minZoom: 1,
maxZoom: 20
})
Insert cell
deckgl = {
const myDeck = new deck.DeckGL({
container,
map: mapboxgl,
mapboxAccessToken: '',
// This token is for demo-purpose only and rotated regularly. Get your token at https://www.mapbox.com
mapboxApiAccessToken: 'pk.eyJ1IjoidWJlcmRhdGEiLCJhIjoiY2pudzRtaWloMDAzcTN2bzN1aXdxZHB5bSJ9.2bkj3IiRC8wj3jLThvDGdA',
mapStyle: 'mapbox://styles/mapbox/dark-v9',
initialViewState,
controller: true,
views: [
new deck.MapView({
id: 'map-view'
}),
new deck.OrthographicView({
id: 'ortho-view'
})
],
layers: [
scatterplotLayer(),
overlayLayer()
],
layerFilter: ({ layer, viewport }) => {
if (viewport.id === 'map-view' && layer.id === 'scatterplot-layer') return true
if (viewport.id === 'ortho-view' && layer.id === 'overlay-layer') return true
return false
}
})
return Object.assign(myDeck, {
update(sliderValue) {
// console.log('Jim update', sliderValue)
myDeck.setProps({ layers: [
scatterplotLayer(),
overlayLayer()
] })
}
})
}
Insert cell
scatterplotLayer = () => {
const elapsedValue = viewof elapsed.value
// console.log('Jim elapsedValue', elapsedValue)
return new deck.ScatterplotLayer({
id: 'scatterplot-layer',
data: geotaggedEvents,
getPosition: d => d.location,
getRadius: d => {
return (d.level + 1) * 50 * 1000 // 50-1500 km
},
getFillColor: d => {
if (d.date > (elapsedValue - 7 * 24 * 60 * 60 * 1000) &&
d.date <= elapsedValue) {
const alpha = 255 - 255 * (elapsedValue - d.date) / (7 * 24 * 60 * 60 * 1000)
const green = Math.min(255, 255 * d.age / (3 * 30 * 24 * 60 * 60 * 1000)) // red -> yellow over 3 months
return [255, green, 0, alpha]
} else {
return [0, 0, 0, 0]
}
},
updateTriggers: {
getFillColor: `${elapsedValue}`
}
})
}
Insert cell
deckgl.update(elapsed)
Insert cell
Insert cell
Insert cell
providerEvents = (await fetch(url)).json()
Insert cell
geotaggedEvents = {
const geotaggedEvents = []
for (const { provider, locations, events } of providerEvents) {
const firstEventDate = Number(d3.isoParse(events[0].date))
for (const { date, level } of events) {
const eventDate = Number(d3.isoParse(date)) - Math.floor(Math.random() * 24 * 60 * 60 * 1000) // randomize over 24 hours
geotaggedEvents.push({
date: eventDate,
age: Math.max(0, eventDate - firstEventDate),
level,
location: locations[Math.floor(Math.random() * locations.length)]
})
}
}
return geotaggedEvents.sort(({ date: a}, { date: b }) => a - b)
}
Insert cell
startTime = geotaggedEvents[0].date
Insert cell
endTime = geotaggedEvents[geotaggedEvents.length - 1].date
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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