Public
Edited
Apr 2, 2023
Insert cell
Insert cell
arrow = require('@apache-arrow/es5-umd@0.3.1')
Insert cell
Insert cell
scrabble = {
// Get the arrow file from GitHub gist as an ArrayBuffer
const buf = await d3.buffer(url);
// Create an arrow Table with it
return arrow.Table.from([new Uint8Array(buf)]);
}
Insert cell
Insert cell
scrabble.schema.fields.map((d) => d.name)
Insert cell
Insert cell
Insert cell
Insert cell
function columnStats(name) {
// Get the column withe the given name
const column = scrabble.getColumn(name);
// Use it's iterator to find the max and min values
let max = column.get(0), min = max;
for (let value of column) {
if (value > max) max = value;
else if (value < min) min = value;
}
return {max, min, range: max-min};
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
winner_table = scrabble.countBy('winnername')
Insert cell
Insert cell
winner_table.toJSON()
Insert cell
Insert cell
Insert cell
Insert cell
biggest_winners = collectCounts(winner_table).slice(0, 30)
Insert cell
Insert cell
Insert cell
losers = {
const counts = scrabble
.filter(arrow.predicate.col('winnername').eq(winner))
.countBy('losername');
return collectCounts(counts);
}
Insert cell
Insert cell
Insert cell
Insert cell
// Find the winner in the winnername column's dictionary
winner_key = scrabble.getColumn('winnername').dictionary.indexOf(winner)
Insert cell
{
// Look for the winner's key in the indicies and gather all the matches
let result = [], idx = 0;
for (let key of scrabble.getColumn('winnername').indices) {
if (key == winner_key) result.push(idx)
idx++;
}
return result
}
Insert cell
Insert cell
// Render scores from a DataFrame (df) onto an ImageData (image) with a given color (32-bit ABGR)
function plotScores(df, image, color) {
const h = image.height, w = image.width,
image_buf = new Uint32Array(image.data.buffer);
let wscore, lscore, x, y;
df.scan(
// `next` function
// Uses the wscore,lscore accessors assigned in `bind`
(idx) => {
// Map the winner score to a y value
y = h - Math.round((wscore(idx) - stats.winnerscore.min)/stats.winnerscore.range*h);
// Map the loser score to an x value
x = Math.round((lscore(idx) - stats.loserscore.min)/stats.loserscore.range*w);
// Fill that pixel in the image buffer
image_buf[y*w + x] = color;
},
// `bind` function
// uses col's .bind() method to get accessors for winnerscore and loserscore
(batch) => {
wscore = col('winnerscore').bind(batch);
lscore = col('loserscore').bind(batch);
}
);
}
Insert cell
Insert cell
all_scores = {
// Max out at 1 pixel per point
const w = stats.loserscore.range < width ? stats.loserscore.range : width;
const pixels_per_point = w/stats.loserscore.range;
const h = stats.winnerscore.range*pixels_per_point;
const canvas = DOM.canvas(w, h);
const ctx = canvas.getContext("2d");
const image = ctx.createImageData(w, h);
plotScores(scrabble, image, 0xFF000000);
ctx.putImageData(image, 0, 0)
return canvas;
}
Insert cell
Insert cell
Insert cell
filtered = scrabble.filter(col('year').eq(year_filt))
Insert cell
{
const h = all_scores.height, w = all_scores.width;

// Grab the image buffer from "all_scores"
const image = all_scores.getContext("2d").getImageData(0,0,w,h);

// Add some blue dots for the currently selected year
plotScores(filtered, image, 0xFFFF8800)
// Write the image to this coanvas
const canvas = DOM.canvas(w, h);
canvas.getContext("2d").putImageData(image, 0, 0)
return canvas;
}
Insert cell
Insert cell
marlon_and_ben = {
let winner, wscore, lscore, year, result = [];
// Games where Marlon won
const marlon_v_ben = col('winnername').eq('Marlon Hill').and(col('losername').eq('Ben Schoenbrun'));
// Games where Ben won
const ben_v_marlon = col('losername').eq('Marlon Hill').and(col('winnername').eq('Ben Schoenbrun'));
scrabble
.filter(marlon_v_ben.or(ben_v_marlon))
.scan((idx) => {
result.push({'winner': winner(idx), 'wscore': wscore(idx), 'lscore': lscore(idx), 'year': year(idx)});
}, (batch) => {
winner = col('winnername').bind(batch);
wscore = col('winnerscore').bind(batch);
lscore = col('loserscore').bind(batch);
year = col('year').bind(batch);
});
return result;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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