Published
Edited
May 28, 2018
4 forks
14 stars
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
in_circle = ([x, y]) => x*x + y*y + 0.25 < x + y
Insert cell
Insert cell
Insert cell
Insert cell
halton = function halton (index, base) {
let fraction = 1;
let result = 0;
while (index > 0) {
fraction /= base;
result += fraction * (index % base);
index = ~~(index / base); // floor division
}
return result;
}
Insert cell
Insert cell
positional = function positional (number, base) {
const result = [];
while (number > 0) {
result.push(number % base);
number = ~~(number / base); // floor division
}
return result.reverse();
}
Insert cell
Insert cell
Insert cell
cube_points = n => d3.range(100, 100 + n).map(
i => [halton(i, 2), halton(i, 3), halton(i, 5)])
Insert cell
Insert cell
{
function* gen() {
for (let i = 100;; i++)
yield [halton(i, 2), halton(i, 3), halton(i, 5)];
}
const g = gen();
while (true)
yield Promises.delay(1000, g.next().value);
}
Insert cell
Insert cell
Insert cell
Insert cell
npts = 4000
Insert cell
data = [...Array(npts).keys()].map(
d => [halton(d, base1), halton(d, base2)])
Insert cell
coloring = (d, i) => d3.interpolatePurples(Math.pow(i/npts, 5))
Insert cell
plot = () => {
const svgwidth = Math.min(width, 600);
const margin = 20;
const svg = d3.select(DOM.svg(svgwidth, svgwidth));

const x = d3.scaleLinear()
.domain([0, 1])
.range([margin, svgwidth-margin]);
const y = d3.scaleLinear()
.domain([0, 1])
.range([svgwidth-margin, margin]);
const dots = svg.append("g").selectAll("circle")
.data(data.slice().reverse())
.enter().append("circle")
.attr("cx", d=>x(d[0]))
.attr("cy", d=>y(d[1]))
.attr("fill", coloring)
.attr("r", svgwidth / 150);
return svg.node();
}
Insert cell
plot()
Insert cell
Insert cell
Insert cell
randfloat = {
// Use a Multiply With Carry PRNG, with an XOR-shift successor
// Both from Numerical Recipes, 3rd Edition [H1, G1]
const prng = function* prng(seed) {
if (seed == null) seed = +new Date;

// these two numbers were arbitrarily chosen
let z, x = 3395989511 ^ seed, y = 1716319410 ^ seed;

while (true) {
x = 62904 * (x & 0xffff) + (x >>> 16);
y = 41874 * (y & 0xffff) + (y >>> 16);
z = (x << 16) + y;
z ^= z >>> 13; z ^= z << 17; z ^= z >>> 5;
yield z;
}
}
const POW_NEG_26 = Math.pow(2, -26);
const POW_NEG_27 = Math.pow(2, -27);

return function* randfloat(seed) {
const p = prng(seed);
while (true) {
const low_bits = p.next().value >>> 6;
const high_bits = p.next().value >>> 5;
yield (high_bits + low_bits * POW_NEG_26) * POW_NEG_27;
}
}
}
Insert cell
prngdata = {
const r = randfloat();
return d3.range(npts).map(d => [r.next().value, r.next().value]);
}
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