Skip to content

Instantly share code, notes, and snippets.

@markvital
Last active November 4, 2016 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save markvital/5ce7efd184698b596906d47c14fac6cc to your computer and use it in GitHub Desktop.
Save markvital/5ce7efd184698b596906d47c14fac6cc to your computer and use it in GitHub Desktop.
Layout Equidistant Points Along an Archimedean Spiral
license: mit
svg {
background: white;
}
.spiral {
fill: none;
stroke: #303030;
stroke-width: 3px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="description" content="Points Along an Archimedean Spiral" />
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script>
<link href="index.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
var nodesCount = 32;
var width = 960,
height = 500;
var centerX = width/2,
centerY = height/2,
radius = 500,
coils = 10;
var placeholderR=22;
var textArea={width: 30, height: 15};
var iconArea={width: 15, height: 15};
var direction = 1; //RTL = -1, LTR =1
var textIconGap = 5;
var rotation = - 2*Math.PI;
var thetaMax = coils * 2 * Math.PI;
var awayStep = radius / thetaMax;
var chord = placeholderR*2;
var initialAdjustment = chord / awayStep;
var a_time = [];
for ( theta = chord / awayStep; theta <= thetaMax; ) {
if (a_time.length == nodesCount) break;
away = awayStep * theta;
around = theta + rotation;
around*= direction;
theta += chord / away;
a_time.push({around: around, away: away});
}
console.log("around=" + around + " theta=" + theta + " away=" + away);
console.log(a_time);
fmod = function (a,b) {
return Number((a - (Math.floor(a / b) * b)).toPrecision(8));
};
var finalAngle = fmod(around, 2*Math.PI);
console.log( "finalAngle= " + finalAngle );
var adjustAngle = finalAngle-initialAdjustment;
//var adjustAngle = 0;
var new_time = [];
for (var i = 0; i < a_time.length; i++) {
x = centerX + Math.cos ( a_time[i].around + adjustAngle) * a_time[i].away;
y = centerY + Math.sin ( a_time[i].around + adjustAngle) * a_time[i].away;
xArc = centerX + Math.cos ( a_time[i].around + adjustAngle) * (a_time[i].away-placeholderR);
yArc = centerY + Math.sin ( a_time[i].around + adjustAngle) * (a_time[i].away-placeholderR);
new_time.push({x: x, y: y, xArc: xArc, yArc: yArc});
}
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g");
var lineFunction = d3.svg.line()
.x(function(d) { return d.xArc; })
.y(function(d) { return d.yArc; })
.interpolate("cardinal");
svg.append("path")
.attr("d", lineFunction(new_time))
.attr("stroke", "gray")
.attr("stroke-width", 0.5)
.attr("fill", "none");
svg.append("circle")
.attr("class", "node-placeholder")
.attr("cx", centerX)
.attr("cy", centerY)
.attr("r", 0.5)
.attr("fill", "red");
var node = svg.selectAll("circle")
.data(new_time)
.enter()
.append("g");
node.append("circle")
.attr("class", "node-placeholder")
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.attr("fill", "lightgrey")
.attr("r", placeholderR)
node.append("circle")
.attr("class", "TL-dot")
.attr("cx", function (d) { return d.xArc; })
.attr("cy", function (d) { return d.yArc; })
.attr("fill", "black")
.attr("r", 2)
node.append("rect")
.attr("class", "text-placeholder")
.attr("x", function (d) { return d.x - textArea.width/2; })
.attr("y", function (d) { return d.y; })
.attr("width", textArea.width)
.attr("height", textArea.height)
.attr("fill", "#919191");
node.append("rect")
.attr("class", "icon-placeholder")
.attr("x", function (d) { return d.x - iconArea.width/2; })
.attr("y", function (d) { return d.y - iconArea.height-textIconGap; })
.attr("width", iconArea.width)
.attr("height", iconArea.height)
.attr("fill", "#919191");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment