Published
Edited
Aug 22, 2021
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`# Code`
Insert cell
selected_player = {
var selected_player = 'Select Player'
if (selected_col !== null){
selected_player = selected_col.replace('_',' ')
}
return selected_player
}
Insert cell
Insert cell
function reactiveValue(container, name, value) {
return {
get() {
return value;
},
set(v) {
value = v;
container.dispatchEvent(new CustomEvent("input", {detail: {name, value}}));
return value;
}
};
}
Insert cell
mutable is_fullscreen = false
Insert cell
container = html `<div style="height:${inst_height}px"></div>`
Insert cell
inst_height = {
var inst_height
if (orientation === 'Portrait'){
inst_height = 850
} else {
inst_height = 850
}
return inst_height
}
Insert cell
// {
// let container = html`<div style='height:1050px' id='container'></div>`;
// yield container;
// cgm({
// network,
// viz_width: 900,
// viz_height: 900,
// container
// });
// }
Insert cell
Insert cell
Insert cell
network = FileAttachment("shot_chart_heatmap@4.json").json()
Insert cell
Insert cell
// CGM = require(await FileAttachment("clustergrammer-gl.0.19.0.packd.js").url())
CGM = require(await FileAttachment("clustergrammer-gl.0.22.0.packd.js").url())
Insert cell
d3 = require("d3@5")
Insert cell
import {slider, select} from '@jashkenas/inputs'
Insert cell
selection_type = Generators.observe(notify => {

const mousemove = () => notify(cgm.params.tooltip.tooltip_type);
viewof cgm.addEventListener("click", mousemove);
notify(cgm.params.tooltip.tooltip_type);
return () => viewof cgm.removeEventListener("mousemove", mousemove);
})
Insert cell
mutable selected_row = Generators.observe(notify => {
const mouse_click = () => {

if (cgm.params.tooltip.tooltip_type === 'row-label'){
var inst_name = cgm.params.int.mouseover.row.name
if (selection != inst_name){
mutable selection = 'grid-point'
} else {
mutable selection = 'category'
}
}
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
mutable selected_col = Generators.observe(notify => {
const mouse_click = () => {

if (cgm.params.tooltip.tooltip_type === 'col-label'){
var inst_name = cgm.params.int.mouseover.col.name
if (selection != inst_name){
mutable selection = inst_name
} else {
mutable selection = 'category'
}
}
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
dendro_selections = Generators.observe(notify => {

const mousemove = () => {
if (cgm.params.tooltip.tooltip_type.includes('dendro')){
mutable selection = 'category'
}

notify(cgm.params.dendro.selected_clust_names)
}
viewof cgm.addEventListener("click", mousemove);
notify(cgm.params.dendro.selected_clust_names);

return () => viewof cgm.removeEventListener("mousemove", mousemove);
})
Insert cell
Insert cell
umap_data_ini = d3.csvParse(await FileAttachment("meta_grid@2.csv").text())
Insert cell
opacity_scale = d3.scaleLinear()
.domain([0, 5])
.range([0, 255]);
Insert cell
umap_x_min = Math.min.apply(Math, umap_data_ini.map(function(o) { return parseFloat(o['x']) }))
Insert cell
umap_x_max = Math.max.apply(Math, umap_data_ini.map(function(o) { return parseFloat(o['x']) }))
Insert cell
umap_y_min = Math.min.apply(Math, umap_data_ini.map(function(o) { return parseFloat(o['y']) }))
Insert cell
umap_y_max = Math.max.apply(Math, umap_data_ini.map(function(o) { return parseFloat(o['y']) }))
Insert cell
umap_x_scale = d3.scaleLinear()
.domain([umap_x_min, umap_x_max])
.range([-74, -73]);
Insert cell
umap_y_scale = d3.scaleLinear()
.domain([umap_y_min, umap_y_max])
.range([40, 40.785]);
Insert cell
cat_dict = {
var cat_dict = {}
network.col_nodes.map(x => {
cat_dict[x.name] = x['cat-0']
})
return cat_dict
}
Insert cell
network.cat_colors
Insert cell
// cat_colors = {
// var cat_colors = {}
// var cat_colors_ini = network.cat_colors.row['cat-0']
// var ini_keys = Object.keys(cat_colors_ini)
// ini_keys.map(x => {
// cat_colors[x.split(': ')[1]] = cat_colors_ini[x]
// })
// return cat_colors
// }

cat_colors = ({
'downtown': '#FF0000',
'midrange': '#A9A9A9',
'paint': '#0000FF'
})
Insert cell
mutable selection = 'category'
Insert cell
selected_row_index = network.row_node_names.indexOf(selected_row)
Insert cell
// dimension_data = network.mat[selected_row_index]
Insert cell
selected_col_index
Insert cell
grid_data = network.mat.map(x => x[selected_col_index])
Insert cell
selected_col_index = network.col_node_names.indexOf(selected_col)
Insert cell
umap_data_ini[0]
Insert cell
cat_colors
Insert cell
umap_data = umap_data_ini.map(
x => {
var inst_long = umap_x_scale(parseFloat(x['x']))
var inst_lat = umap_y_scale(parseFloat(x['y']))
var inst_cat = x['Region'] // cat_dict[x['']].split(': ')[1]
var rgb = d3.color(cat_colors[inst_cat])
var inst_color
// console.log(selection)
if (selection === 'category'){
// color by category
var inst_alpha
if (selection_type == 'row-dendro'){
if (dendro_selections.includes(x[''])){
inst_alpha = 255
} else {
inst_alpha = 25
}
} else {
inst_alpha = 255
}
inst_color = [rgb.r, rgb.g, rgb.b, inst_alpha]
} else if (selection === 'grid-point') {
console.log('>>> grid-point!!!!')
// color by category
var inst_alpha
if (x[''] === selected_row){
inst_alpha = 255
} else {
inst_alpha = 25
}
inst_color = [rgb.r, rgb.g, rgb.b, inst_alpha]
} else {
// color by dimension
var inst_index = network.row_node_names.indexOf(x[''])
var inst_data = grid_data[inst_index]
var inst_opacity = opacity_scale(Math.abs(inst_data))

if (inst_data > 0){
inst_color = [255, 0, 0, inst_opacity]
} else {
inst_color = [0, 0, 255, inst_opacity]
}
}
var inst_obj = ({
name: x[''],
position: [inst_long, inst_lat],
food_type: inst_cat,
color: inst_color
})

return inst_obj
}
)
Insert cell
scatter_layer = {

const scatterLayer = new deck.ScatterplotLayer({
data: umap_data,
getPosition: d => d.position,
getFillColor: d => d.color,
getRadius: 2100,
opacity: 0.5,
pickable: true,
autoHighlight: true,
highlightColor: d => [50, 50, 50, 200],
// stroked: true,
// lineWidthMinPixels: 0.05,
onHover: function(info, event){
// if ('object' in info){
// mutable inst_neighborhood = info.object.Neighborhood
// }
},
onClick: function(info, event){
// if ('object' in info){
// if (info.object.name !== selected_station.name){
// // select stations to view paths
// mutable path_types = 'all'
// mutable selected_station = info.object
// } else {
// // turn off paths
// mutable selected_station = {}
// }
// }
}
})

deckgl.setProps({layers: [ scatterLayer]});

return scatterLayer
}
Insert cell
deckgl = {
// // reference for below https://observablehq.com/@tomvantilburg/deckgl-mapbox-and-3d-tiles
// // This is an Observable hack: clear previously generated content
container.innerHTML = '';
return new deck.DeckGL({
container,
initialViewState: {
longitude: inst_lng,
latitude: inst_lat,
zoom: inst_zoom,
minZoom: 9,
maxZoom: 11,
},
controller: true,

getTooltip: ({object}) => {
// return object && `${object.Neighborhood} \n ${object['cross-x']} and ${object['cross-y']}
return object && `${object.name}\n Shot Type: ${object.food_type}` },
// Mapbox settings
// set `map: false` to turn off Mapbox base map
// map: mapboxgl,
// This token is for demo-purpose only and rotated regularly. Get your token at https://www.mapbox.com
// mapboxApiAccessToken: mapbox_token,
mapStyle: 'mapbox://styles/mapbox/light-v9',
});
}
Insert cell
inst_zoom = 9
Insert cell
inst_lng = -73.45
Insert cell
inst_lat = 40.4
Insert cell
deck = require.alias({
// optional dependencies
h3: {},
s2Geometry: {}
})('deck.gl@8.3.7/dist.min.js')
Insert cell
// set table style to full width
html`
<style>
p {
min-width: 100%;
}
`
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