Public
Edited
Aug 4, 2023
Insert cell
Insert cell
Insert cell
function make_dashboard(){

console.log('--- make_dashboard\n--------------------')


// Landscape or Portrait
/////////////////////////////////
// landscape should have flex and display style and have less height

if (orientation === 'landscape'){
var dashboard_html = html`
<div id='dashboard' style="height: 1050px; border:1px;">

<div style="display: flex;">
<div>
<div style="display: flex; margin-top: 20px">
<div style="margin-left: 15px; margin-right: -20px; border:1px; text-align:right;">${viewof map_type} </div>
<div id="meta_dropdown", style="margin-right: 15px; border:1px; text-align:right;">${viewof select_meta_dropdown} </div>
<div style="margin-right: 15px; border:1px; text-align:left;">${viewof cell_min_radius} </div>
</div>
<div style="margin-top: 100px; border:1px ">${container} </div>
</div>
<div style="margin-top:-10px; ">${viewof cgm}</div>
</div>
</div>
`
} else {

var dashboard_html = html`
<div id='dashboard' style="height: 2000px; border:1px;">
<div>
<div>
<div style="display: flex; margin-top: 20px">
<div style="margin-left: 15px; margin-right: -20px; border:1px; text-align:right;">${viewof map_type} </div>
<div id="meta_dropdown", style="margin-right: 15px; border:1px; text-align:right;">${viewof select_meta_dropdown} </div>
<div style="margin-right: 15px; border:1px; text-align:left;">${viewof cell_min_radius} </div>
</div>
<div style="margin-top: 100px; border:1px ">${container} </div>
</div>
<div style="margin-top:-10px; ">${viewof cgm}</div>
</div>
</div>
`
}

// <div style="margin-right: 15px; border:1px; text-align:left;">${viewof cell_opacity} </div>
return dashboard_html
}

Insert cell
orientation = 'portrait'
Insert cell
container = {
console.log('--- make container with id the-container\n---------------------')
return html `<div id='the-container' style="height:800px; width:800px; border-style:solid; border-color:#d3d3d3; border-width:1px; position: relative;"></div>`
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cluster_name = 'leiden'
Insert cell
mutable select_cat = 'all'
Insert cell
Insert cell
Insert cell
Insert cell
check_ini_cat = ini_cat
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cell_metadata = Object.keys(data[0]).filter(x => non_param_cols.includes(x) === false)
Insert cell
meta_data_cols = cell_metadata.concat(all_genes)
Insert cell
all_genes = Object.keys(gex_dict).sort()
Insert cell
mutable selected_clusters = []
Insert cell
zoom = 1
Insert cell
min_zoom = zoom - 1
Insert cell
cell_opacity = 0.9
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
ini_min_radius = 1
Insert cell
viewof cell_min_radius = slider({
value: ini_min_radius,
min: 0.1,
max: 5.0,
precision: 2,
description: "min cell size"
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cell_layer = new deck.ScatterplotLayer({
id: 'cell_layer',
// data: cell_data,
data: data,
getPosition: apply_map_morph,

getFillColor: d => {
var inst_color = [50, 50, 50, 255]
if (select_meta === 'none'){

// default coloring
////////////////////////////////////////
inst_color = [50, 50, 50, 100]

} else if (select_meta === cluster_name) {
if (selected_clusters.length === 0){
// single cluster
///////////////////
var rgb = d3.color(cat_colors[d[select_meta]])
inst_color = [rgb.r, rgb.g, rgb.b, 255 * cat_opacity]
} else {
// multiple clusters
/////////////////////
if (selected_clusters.includes(d[cluster_name])){
var rgb = d3.color(cat_colors[d[select_meta]])
inst_color = [rgb.r, rgb.g, rgb.b, 255 * cat_opacity]
} else {
inst_color = [50, 50, 50, 10]
}
}
} else if (select_meta === 'mean-gene') {

// mean gene expression
////////////////////////////////////////
inst_color = [0, 0, 0, 255]
} else {
// single gene expression
////////////////////////////////////////
if (all_genes.includes(select_meta)){
if (d.name in gex_dict[select_meta]){
var inst_expression = gex_dict[select_meta][d.name]
var inst_opacity = opacity_scale(inst_expression)
inst_color = [255, 0, 0, inst_opacity]
} else {
inst_color = [100, 100, 100, 0]
}
}
}
return inst_color
},
getRadius: cell_radius,
pickable: is_pickable,
highlightColor: d => [50, 50, 50],
radiusMinPixels: cell_min_radius,
opacity: cell_opacity,
updateTriggers: {
getFillColor: [select_meta, selected_clusters],
getPosition: map_type,
},
transitions: transitions,
onClick: (info, event) => {
if (mutable selected_clusters[0] !== info.object[cluster_name]){
mutable select_meta = cluster_name
mutable selected_clusters = [info.object[cluster_name]]
d3.select('#meta_dropdown').select('select').node().value = 'none'
} else {
mutable select_meta = cluster_name
mutable selected_clusters = []
d3.select('#meta_dropdown').select('select').node().value = cluster_name
}
}
})
Insert cell
Insert cell
Insert cell
layers = [cell_layer]
Insert cell
Insert cell
deckgl.setProps({layers: layers});
Insert cell
Insert cell
flipY = false
Insert cell
view = new deck.OrthographicView({id: 'ortho', flipY: flipY})
Insert cell
Insert cell
deckgl = {
console.log('--- deckgl\n----------')
var deckgl = new deck.DeckGL({
container,
width: '800px',
height: '800px',
top: '175px',
views:[view],
initialViewState: initial_view_state,
// controller: true,
controller: {doubleClickZoom: false},
// getTooltip: ({object}) => {
// return object &&
// `${object['name']}`
// // `pos: ${object.x}, ${object['y']}\n`
// },
getTooltip: ({object}) => object && {
html: `${object[cluster_name]}`,
style: {
fontSize: '0.8em',
padding: '5px',
}
},
// onViewStateChange: ({viewState}) => {
// debounced_something(viewState)
// return viewState
// },
// onClick: ({info}) => {
// console.log(info)
// return info
// }
});

// // shift downwards
// console.log('wait to move down move down')
// console.log('is empty', d3.select('#the-container').empty())
// d3.select('#the-container div').style('top', '150px')
// d3.select('#the-container canvas').style('top', '150px')

return deckgl
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
gex_opacity_contrast_scale = 1
Insert cell
opacity_scale = d3.scaleLinear()
.domain([0, meta_max * gex_opacity_contrast_scale])
.range([0, 255])
Insert cell
meta_max = {
var meta_max
if (select_meta in gex_dict){
meta_max = d3.max(Object.values(gex_dict[select_meta]))
} else if (select_meta === 'mean-gene') {

// set up calculation of mean gene max
meta_max = 0
} else {
meta_max = 0
}
return meta_max
}
Insert cell
Insert cell
Insert cell
col_selection = Generators.observe(notify => {

const mousemove = () => {
if (cgm.params.tooltip.tooltip_type === 'col-dendro'){
mutable select_meta = cluster_name
mutable dendro_selected_genes = []
mutable selected_clusters = cgm.params.dendro.selected_clust_names.map(x => x.replace(cluster_name + '-', ''))
}

}
viewof cgm.addEventListener("click", mousemove);
notify(cgm.params.dendro.selected_clust_names.map(x => x.replace(cluster_name + '-', '')));

return () => viewof cgm.removeEventListener("mousemove", mousemove);
})
Insert cell
Insert cell
heatmap_row = Generators.observe(notify => {
const mouse_click = () => {

// clicking gene row
//////////////////////////////
if (cgm.params.tooltip.tooltip_type === 'row-label'){
var inst_name = cgm.params.int.mouseover.row.name
mutable dendro_selected_genes = []
mutable select_meta = inst_name
d3.select('#meta_dropdown').select('select').node().value = inst_name
}
notify(cgm.params.int.mouseover.row.name)
}
viewof cgm.addEventListener("click", mouse_click);
notify(cgm.params.int.mouseover.row.name);

return () => viewof cgm.removeEventListener("mousemove", mouse_click);
})
Insert cell
heatmap_col = Generators.observe(notify => {
const mouse_click = () => {

// clicking cluster col
//////////////////////////////
if (cgm.params.tooltip.tooltip_type === 'col-label'){
mutable select_meta = cluster_name
mutable dendro_selected_genes = []
mutable selected_clusters = [cgm.params.int.mouseover.col.name.replace(cluster_name + '-', '')]
}
notify([cgm.params.int.mouseover.col.name])
}
viewof cgm.addEventListener("click", mouse_click);
notify([cgm.params.int.mouseover.col.name]);

return () => viewof cgm.removeEventListener("mousemove", mouse_click);
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// CGM = require(await FileAttachment("clustergrammer-gl.0.24.1.packd.js").url())
CGM = require(await FileAttachment("clustergrammer-gl.0.25.0.packd.js").url())
Insert cell
pako = require('pako/dist/pako.min.js')
Insert cell
import {slider, select} 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