Public
Edited
Jul 11, 2024
Insert cell
Insert cell
Insert cell
{
let height = 4500;
let marginBottom = 30;
let marginTop = 30;
const yAxis = Plot.plot({
width: 40,
height,
marginTop,
marginBottom
});

const chart = Plot.plot({
style: {
backgroundColor: "#222"
},
axis: null,
height,
width: 10000,
margin: 20,
marginLeft: 40,
marginRight: 120,
r: { type: "log", range: [0, 20] },
color: {
type: "diverging",
scheme: "BuRd",
transform: (d) => (aliquots[d] - d) / +d
},
marks: [
Plot.tree(aliquotPaths, {
path: "path",
r: "node:name",
fill: "node:name",
title: "node:name",
textStroke: "#222"
})
]
});
chart.classList.add("chart");

const scrollbar = html`<div class="scrollbar">`;
scrollbar.append(chart);

const div = html`<div class="container">`;
div.append(yAxis, scrollbar);
return div;
}
Insert cell
Insert cell
{
let height = 300;
let marginBottom = 30;
let marginTop = 30;
const yAxis = Plot.plot({
width: 40,
height,
marginTop,
marginBottom
//y: yScale
});
const chart = Plot.plot({
style: {
backgroundColor: "#222"
},
height: 500,
width: 5000,
y: { type: "log" },
color: {
type: "diverging",
scheme: "BuYlRd"
},
marks: [
Plot.link(aliquotLinks, {
x1: "x1",
y1: "y1",
x2: "x2",
y2: "y2",
stroke: "relAbundance",
strokeWidth: 2,
// markerStart: "dot",
opacity: 0.25
})
]
});

chart.classList.add("chart");

const scrollbar = html`<div class="scrollbar">`;
scrollbar.append(chart);

const div = html`<div class="container">`;
div.append(yAxis, scrollbar);
return div;
}
Insert cell
Insert cell
aliquotPaths = {
let reverseMap = groupValues(aliquots);
let paths = [];
let addPaths = (num, prefix = "") => {
if (!reverseMap[num]) {
paths.push({
path: prefix + num,
name: num
});
} else {
for (let child of reverseMap[num]) {
if (+child !== +num) {
addPaths(child, "" + prefix + num + "/");
}
}
}
};
// return reverseMap;
addPaths(1);
// addPaths(6);
// addPaths(28);
// addPaths(496);
return paths;
//return _.range(n).map((k) => (primes.has(k) ? 1 : aliquot(k)));
}
Insert cell
aliquots = getAliquots(701)
Insert cell
function aliquotSequence(n) {
let seq = [n];
let k = aliquot(n);
while (!seq.includes(k)) {
seq.push(k);
k = aliquot(k);
if (k > Number.MAX_SAFE_INTEGER) {
break;
}
}
return seq;
}
Insert cell
function getAliquots(n) {
let primes = new Set(getPrimes(n));
let aliquots = {};
for (let i = 1; i <= n; i++) {
if (primes.has(i)) {
aliquots[i] = 1;
} else if (unboundedAliquots.includes(i)) {
aliquots[i] = -1;
} else {
let k = i;
while (!aliquots[k]) {
let a = aliquot(k);
if (a > Number.MAX_SAFE_INTEGER) {
break;
}
aliquots[k] = a;
k = a;
}
}
}
return aliquots;
}
Insert cell
function groupValues(map) {
let result = {};
for (let [key, value] of Object.entries(map)) {
if (!result[value]) {
result[value] = [];
}
result[value].push(key);
}
return result;
}
Insert cell
unboundedAliquots = [
276, 306, 396, 552, 564, 660, 696, 780, 828, 888, 966, 996, 1074, 1086, 1098,
1104, 1134, 1218, 1302, 1314, 1320, 1338, 1350, 1356, 1392, 1398, 1410, 1464,
1476, 1488, 1512, 1560, 1572, 1578, 1590, 1632, 1650, 1662, 1674, 1722, 1734,
1758, 1770, 1806, 1836
]
Insert cell
perfectNumbers = [6, 28, 496, 8128, 33550336]
Insert cell
tooBigAliquots = [702, 840, 978, 990]
Insert cell
// TODO formula based on prime decomposition
function aliquot(n) {
return _.sum(factors(n));
}
Insert cell
import { factors, getPrimes } from "@tesseralis/math"
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