Public
Edited
Sep 26, 2024
1 fork
Importers
16 stars
Insert cell
Insert cell
Insert cell
Insert cell
dynamic.map((point, i) => {return {point, letter: String.fromCodePoint(font_embedding[i].point)}})
Insert cell
viewof restart = html`<button>restart</button>`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
block_descriptions = d3.rollup(blocks, d => d[0].block, k => k.range)
Insert cell
JSON.stringify(blocks_to_show)
Insert cell
Insert cell
block_lookup = {
// Of just the current points.
const z = new Map()
for (let d of blocks_to_show) {
const label = blocks.filter(block => block.range == d)[0].block
for (const point of block_points(d)) {
z.set(point, label)
}
}
return z
}
Insert cell
md`Font size. No reason to change this, I don't think.`
Insert cell
w = 16
Insert cell
colorize = d3.scaleOrdinal(d3.schemeDark2);
Insert cell
font_embedding =
{
const raw = get_embeddings(fonts, UNICODE_POINTS)
const seen = new Set()
return raw.filter(d => {
const key = _arrayBufferToBase64(d.data)
if (seen.has(key)) {return false}
seen.add(key)
return true
})
}
Insert cell
_arrayBufferToBase64 = function( buffer ) {
//copied
var binary = '';
var bytes = new Uint8Array( buffer );
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCodePoint( bytes[ i ] );
}
return window.btoa( binary );
}

Insert cell
block_points = function(range_string) {
return d3.range(...range_string.split("-").map(e => parseInt(e, 16)))
}
Insert cell
UNICODE_POINTS = blocks_to_show.map((d) => block_points(d)).flat()
Insert cell
blocks = d3.json("https://gist.githubusercontent.com/panayotoff/a50f8a4dcf6b9444979ec5b10ea53bdd/raw/26ba1583de2a316a8290f49c70c3a380ac9bb4ad/unicode-blocks.json")
Insert cell
String.fromCodePoint(parseInt("1F600", 16))
Insert cell
import {checkbox, slider} from "@jashkenas/inputs"
Insert cell
Insert cell
dynamic = {
restart;

const umap = new UMAP({
nComponents: 2,
minDist: 0.2,
nNeighbors: 15
}),
nEpochs = umap.initializeFit(font_embedding.map((d) => d.data));

for (let i = 0; i < nEpochs; i++) {
umap.step();
if (i % 1 === 0) yield umap.getEmbedding();
}
yield umap.getEmbedding();
}
Insert cell
point_yielder = function*(fonts = ['Georgia'], points, cols = 1, exportable = false) {
const buffer = DOM.canvas(w*5/4 * cols, w*5/4)
// yield buffer
const ctx = buffer.getContext("2d")
const vals = []
ctx.fillStyle = "black";
for (let font of fonts) {
ctx.font = `${w}px ${font}`
for (let i of points) {
//if (i % 100 == 0) {yield i}
ctx.clearRect(0, 0, w*2*cols, w*2)
for (let x in d3.range(cols)) {
ctx.fillText(String.fromCodePoint(i), x*w, w)
vals.push({
point: i,
data: image_vector(ctx, w),
font: font
})
i++;
}
}
//yield html`${buffer}`
}
yield vals
}
Insert cell
//current = point_yielder(["Georgia", "Times New Roman", "Arial", "Helvetica", "Comic Sans"], UNICODE_POINTS)
Insert cell
function image_vector(ctx, w, color_downsample = 3) {
const output = new Uint8Array(w * w * 2)
const d = ctx.getImageData(0, w/4, w, w*5/4).data
for (let i of d3.range(output.length/2)) {
output[i*2] = d[i*4 + 3]
output[i*2 + 1] = d[i*4 + i % 3]

}
return output
}
Insert cell
d3 = require('d3@^5', "d3-array@^2.2")
Insert cell
UMAP = (await require("umap-js@1.3.1")).UMAP
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