Public
Edited
May 29
Insert cell
Insert cell
html`
${viewof dropdown_cell}<br>
${viewof dropdown_gene}<br>
${viewof dropdown_img}<br>`
Insert cell
Insert cell
obs_state.dropdown_img.get()
Insert cell
// // directly set observable values and have dropdowns update
// obs_state.dropdown_cell.set('B cell')
// obs_state.dropdown_img.set('DAPI')
Insert cell
function makeResettableDropdown({ key, label, options, resetTriggers, obs_state }) {
const dropdown = Inputs.select(options, {
label,
value: obs_state[key].get()
});

// Input → Observable
dropdown.addEventListener("input", () => {
console.log(`user input: ${key}:`, dropdown.value);
obs_state[key].set(dropdown.value);
console.log("");
});

// Observable → Input
obs_state[key].subscribe(val => {
if (dropdown.value !== val) {
dropdown.value = val;
console.log(`obs input: ${key}:`, val);
}
});

// Reset if triggered by another dropdown
const resetIfNeeded = () => {
if (obs_state.suppressReset.get()) {
console.log(`suppressed: ${key}`);
return;
}

if (obs_state[key].get() !== obs_state[key].getDefault()) {
obs_state.suppressReset.set(true);
console.log(`suppressReset: ${key}: on`);
obs_state[key].set(obs_state[key].getDefault());
obs_state.suppressReset.set(false);
console.log(`suppressReset: ${key}: off`);
} else {
console.log(`already default: ${key}`);
}
};

for (const triggerKey of resetTriggers) {
obs_state[triggerKey].subscribe(resetIfNeeded);
}

return dropdown;
}

Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
viewof container = html `<div style="height:300px"></div>`
Insert cell
deckgl.setProps({
layers: [scatterplotLayer],
})
Insert cell
deckgl.setProps({
initialViewState: {
longitude: -122.402,
latitude: 37.79,
zoom: 13,
pitch: 0,
bearing: 0
},
})
Insert cell
scatterplotLayer = {
return new deck.ScatterplotLayer({
data: [
{position: [-122.402, 37.79], color: [255, 0, 0], radius: 1000}
],
getPosition: d => d.position,
getColor: d => d.color,
getRadius: d => d.radius,
opacity: 0.3
});
}
Insert cell
deckgl = new deck.DeckGL({
container,
controller: true,
})
Insert cell
deck = require.alias({
// optional dependencies
h3: {}
})('deck.gl@latest/dist.min.js')
Insert cell
Insert cell
function Observable(initialValue) {
let value = initialValue;
const subscribers = new Set();

return {
get: () => value,
getDefault: () => initialValue,
set: newValue => {
if (value !== newValue) {
value = newValue;
subscribers.forEach(fn => fn(value));
}
},
subscribe: fn => {
subscribers.add(fn);
fn(value); // Call immediately with current value
return () => subscribers.delete(fn); // Unsubscribe function
}
};
}


Insert cell
obs_state = ({
cell_cat: Observable("default cell cat"),
trx_cat: Observable("default trx cat"),
img_cat: Observable("default img cat"),
dropdown_cell: Observable(""),
dropdown_gene: Observable(""),
dropdown_img: Observable(""),
suppressReset: Observable(false)
})
Insert cell
import { Inputs } from "@observablehq/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