Public
Edited
Nov 6
Insert cell
Insert cell
container = html `<div style="height:800px;"></div>`
Insert cell
fragmentShader = `
precision highp float;
varying vec4 vColor;
varying vec2 vPosition;
void main(void) {
float distToCenter = length(vPosition);
gl_FragColor = vec4(vColor.rgb, vColor.a);
// Should be the last Fragment shader instruction that updates gl_FragColor
gl_FragColor = picking_filterPickingColor(gl_FragColor);
}`;
Insert cell
vertexShader = `
attribute vec3 positions;
attribute vec3 instancePositions;
attribute vec3 instancePositions64Low;
attribute float instanceRadius;
attribute vec4 instanceColors;
varying vec4 vColor;
varying vec2 vPosition;
attribute vec3 customPickingColors;
void main(void) {
vec3 offsetCommon = positions * project_size(instanceRadius);
vec3 positionCommon = project_position(instancePositions, instancePositions64Low);
gl_Position = project_common_position_to_clipspace(vec4(positionCommon + offsetCommon, 1.0));
vPosition = positions.xy;
vColor = instanceColors;
picking_setPickingColor(customPickingColors);
}`
Insert cell
getModel = (gl) => {
// Four corners of the quad
const positions = new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]);
const geometry = new luma.Geometry({
drawMode: gl.TRIANGLE_FAN,
vertexCount: 4,
attributes: {
positions: {size: 2, value: positions}
}
});
const model = new luma.Model(gl, {
vs: vertexShader,
fs: fragmentShader,
geometry,
isInstanced: true,
modules: [deck.picking]
});
return model
}
Insert cell
scatter_instancing = {

class ScatterInstanced extends deck.Layer {
initializeState() {
const {gl} = this.context;

this.setState({
model: getModel(gl)
});
// Register attributes
this.getAttributeManager()
.addInstanced({
instancePositions: {
size: 3,
type: gl.DOUBLE,
transition: true,
accessor: 'getPosition'
},
instanceRadius: {
size: 1,
transition: true,
accessor: 'getRadius',
defaultValue: 1
},
instanceColors: {
size: 4,
normalized: true,
type: gl.UNSIGNED_BYTE,
transition: true,
accessor: 'getColor',
defaultValue: [0, 0, 0, 255],
},
customPickingColors: {
size: 3,
type: gl.UNSIGNED_BYTE,
update: this.calculatePickingColors,
}
});

}
calculatePickingColors (attribute) {
const {data} = this.props;
const {value, size} = attribute;
let i = 0;

let index = 0;
for (const object of data) {
// Use the index index instead of object.id
const pickingColor = this.encodePickingColor(index);
value[index * 3] = pickingColor[0];
value[index * 3 + 1] = pickingColor[1];
value[index * 3 + 2] = pickingColor[2];
index++;
}
}
}
ScatterInstanced.layerName = 'ScatterInstanced';

const layer = new ScatterInstanced({
id: 'scatter-instancing',
data: data_inst,
getPosition: d => [d.x, d.y],
getRadius: d => 10,
getColor: [255, 0, 0],
pickable: true,
});
return layer;
}
Insert cell
Insert cell
deckgl = new deck.DeckGL({
container,
width: '800px',
height: '800px',
views:[new deck.OrthographicView({id: 'ortho'})],
initialViewState: {
target: [0, 50, 0],
zoom: 2,
minZoom: -2
},
controller: {doubleClickZoom: false},
getTooltip: ({object}) => object && {
html: `${object['leiden']}`,
style: {
fontSize: '0.8em',
padding: '5px',
}
},
layers: [scatter_instancing]
});

Insert cell
data_inst = ([
{name: 'dog', 'x': 1, 'y': 1, 'leiden': "dog", 'umap-x': 1, 'umap-y': 1},
{name: 'elephant', 'x': 30, 'y': 30, 'leiden': "elephant", 'umap-x': -20, 'umap-y': -20}
])
Insert cell
Insert cell
Insert cell
deck = require.alias({
// optional dependencies
h3: {}
})('deck.gl@v8-latest/dist.min.js')

// deck = require.alias({
// // optional dependencies
// h3: {}
// })('deck.gl@latest/dist.min.js')
Insert cell
luma = deck && window.luma
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