Skip to content

Instantly share code, notes, and snippets.

@rouleur rouleur/Readme.md
Last active Aug 29, 2015

Embed
What would you like to do?
Ulam Spiral

###Ulam Spiral with D3.js

Ulam Spiral is a way of visualising prime numbers. We start with 1 in center and continue writing numbers in a rectangular spiral. Above, numbers in yellow are prime numbers. The spiral can be thought to demonstrate prime numbers are not "that random".

For more info about Ulam Spiral you can check the Wikipedia page or this Youtube video

<!DOCTYPE html>
<html>
<head>
<title>Ulam Spiral with D3.js</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.4.13/d3.min.js" charset="utf-8"></script>
</head>
<body bgcolor="gray">
<div id="graph" style="width: 960px; height: 500px;margin-left: auto; margin-right: auto;"></div>
</body>
<script>
var width = 960;
var height = 500;
var svg = d3.select("#graph").append("svg")
.attr("width", width)
.attr("height", height);
var dx = 20;
var dy = 20;
x0 = width / 2;
y0 = height / 2;
var size = 100;
function generateBaseArray(n) {
var result = [];
for (var i = 1; i < n; i++) {
result.push(i);
result.push(i);
result.push(-i);
result.push(-i);
}
return result;
}
var cornerCoordsForX = generateBaseArray(size);
var cornerCoordsForY = generateBaseArray(size);
cornerCoordsForX.unshift(0);
cornerCoordsForY.unshift(0, 0);
var Position = function (x, y) {
this.x = x;
this.y = y;
}
var graphData = [];
for (var i = 0; i < size; i++) {
if (graphData.length > 2) {
var last = graphData[graphData.length - 1];
if (last.x > cornerCoordsForX[i]) {
var dif = last.x - cornerCoordsForX[i];
for (var j = 1; j < dif; j++) {
graphData.push(new Position(last.x - j, cornerCoordsForY[i]));
}
}
if (last.x < cornerCoordsForX[i]) {
var dif = last.x - cornerCoordsForX[i];
for (var j = 1; j < -dif; j++) {
graphData.push(new Position(last.x + j, cornerCoordsForY[i]));
}
}
if (last.y > cornerCoordsForY[i]) {
var dif = last.y - cornerCoordsForY[i];
for (var j = 1; j < dif; j++) {
graphData.push(new Position(cornerCoordsForX[i], last.y - j));
}
}
if (last.y < cornerCoordsForY[i]) {
var dif = last.y - cornerCoordsForY[i];
for (var j = 1; j < -dif; j++) {
graphData.push(new Position(cornerCoordsForX[i], last.y + j));
}
}
}
graphData.push(new Position(cornerCoordsForX[i], cornerCoordsForY[i]));
}
var primes = [];
function isPrime(n) {
if (n == 1) return false;
var checkPoint = Math.sqrt(n);
for (var i = 0; primes[i] <= checkPoint; i++) {
if (n % primes[i] == 0) {
return false;
}
}
primes.push(n);
return true;
}
function fontSize(i) {
if (i > 998) {
return "8px";
} else if (i > 98) {
return "9px";
} else if (i > 8) {
return "10px";
} else {
return "11px";
}
}
var text = svg.selectAll("text")
.data(graphData)
.enter()
.append("text");
var textLabels = text
.attr("x", function (d) {
return d.x * dx + width / 2;
})
.attr("y", function (d) {
return d.y * dy + height / 2;
})
.text(function (d, i) {
return i + 1;
})
.attr("text-anchor", "middle")
.attr("font-family", "helvetica")
.attr("font-size", fontSize(i))
.attr("fill", function (d, i) {
if (i + 1 == 1) return "red";
if (isPrime(i + 1)) {
return "yellow";
} else {
return "black";
}
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.