-
Hi everyone, I'm using deck.gl in Observable for an interactive map with two layers: A geoJsonLayer for the base map. To make this variable reactive, I wrapped the entire DeckGL definition in a Generators.observe. While this works, it introduces significant delays (screen updates occur about 500ms after clicking). The console also shows warnings like:
Here’s a simplified version of my code for reference: import deck from "npm:deck.gl";
// import { showIxpDetails } from "./components/my-scripts.js";
const {DeckGL, GeoJsonLayer, IconLayer } = deck;
const world_map = FileAttachment("./data/world-map.json").json()
const ixp_metadata = FileAttachment("./data/raw/metadata.json").json()
import { interpolateViridis } from "d3-scale-chromatic";
import { scaleSequentialSqrt } from "d3-scale"; Interactive Mapfunction showIxpDetails(data, ixp_id,{width} = {}) {
const ixpData = data.filter(d => d.ixp_id === ixp_id);
// Create an array of text entries from the data
const textEntries = ixpData.map(d =>
`ID: ${d.ixp_id}
Name: ${d.name}
Long Name: ${d.long_name}
City: ${d.city}
Country: ${d.country}
Net Count: ${d.net_count}`
);
return Plot.plot({
height: 200,
width,
marks: [
Plot.frame({
stroke: "black",
strokeWidth: 2,
dy: 250
}),
Plot.text(textEntries, {
frameAnchor: "middle",
textAnchor: "middle",
fontSize: 25,
dy: 250
})
]
});
} // Layer definitions
const geoJsonLayer = new GeoJsonLayer({
id: 'GeoJsonLayer',
data: world_map,
lineWidthMinPixels: 1.5,
getFillColor: [160, 160, 180, 200],
getLineColor: [255,255,255, 100],
getLineWidth: 20,
});
const colorScale = scaleSequentialSqrt()
.domain([0, 100])
.range([0, 1]);
const ixpLayer = new IconLayer({
id: 'ixpLayer',
data: ixp_metadata,
getColor: d => {
const colorString = interpolateViridis(colorScale(d.net_count));
const rgb = colorString.match(/[A-Za-z0-9]{2}/g).map(x => parseInt(x, 16));
return rgb;
},
getIcon: d => 'marker',
getPosition: d => [d.long, d.lat],
getSize: 30,
iconAtlas: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.png',
iconMapping: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/website/icon-atlas.json',
pickable: true
}); // Create an observable value for the selected IXP
const selected_ixp = Generators.observe(notify => {
// Initialize with no selection
notify(-1);
const interactiveWorldMap = new DeckGL({
container,
initialViewState: {
longitude: 0,
latitude: 30,
zoom: 1
},
controller: true,
getTooltip: ({object}) => object &&
`${object.name} (${object.long_name}) - ${object.net_count} Networks`,
onClick: (info, event) => {
if (info.object) {
notify(info.object.ixp_id);
}
},
getCursor: ({isHovering}) => isHovering ? 'pointer' : 'grab',
layers: [geoJsonLayer, ixpLayer]
});
// Cleanup function
return () => {
interactiveWorldMap.finalize();
container.innerHTML = "";
};
}); <div class="grid grid-cols-3">
<div class="card grid-colspan-2">
<div style="padding: 1rem;">
<h2>Worldwide IXPs</h2>
<h3>Zoom and scroll, or hold down Shift to rotate.</h3>
</div>
<figure style="max-width: none; position: relative;">
<div id="container" style="border-radius: 8px; overflow: hidden; height: 620px; margin: 0 0;">
</div>
</figure>
</div>
<div class="card grid-colspan-1">
${resize((width) => showIxpDetails(ixp_metadata, selected_ixp, {width}))}
</div>
</div> My Questions:
I’d greatly appreciate any feedback or suggestions! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
You can try to use |
Beta Was this translation helpful? Give feedback.
I have found the cause!
This seems to be the intended behaviour according to deck.gl devs as it has a delay "...so that the event doesn't fire when double clicking". Setting
controller: {doubleClickZoom: false},
removes this delay.Source: visgl/deck.gl#3783 (comment)