Skip to content

Instantly share code, notes, and snippets.

@tezzutezzu
Last active January 3, 2018 14:21
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 tezzutezzu/8e6c99f6963f49dbd3315e1eb70896b6 to your computer and use it in GitHub Desktop.
Save tezzutezzu/8e6c99f6963f49dbd3315e1eb70896b6 to your computer and use it in GitHub Desktop.
Fixed arcs in a variable circle
license: mit
border: no
scrolling: no

Move your mouse to edit the size of the circle

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { font-family:sans-serif; margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
circle {fill:none; stroke:#000; stroke-width:2}
text {text-anchor:middle}
line {stroke:#000}
</style>
</head>
<body>
<script>
var radius = 117;
const arcLength = 100
var arc = d3.arc();
var margin = { top: 0, right: 0, bottom: 0, left: 0 },
width = document.body.clientWidth - margin.left - margin.right,
height = document.body.clientHeight - margin.top - margin.bottom;
var startRadius;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
svg.append("circle").attr("cx", width/2).attr("cy", height/2)
svg.append("line").attr("class", "radius").attr("x1", width/2).attr("y1", height/2).attr("y2", height/2)
svg.append("text").attr("class", "radiusLabel")
svg.append("text").attr("class", "circLabel")
svg.append("text").attr("class", "arcsLabel").attr("x", width-20).attr("y", 30).style("text-anchor","end")
svg.append("text").attr("class", "gapLabel").attr("x", width-20).attr("y", 60).style("text-anchor","end")
d3.selectAll("body").call(d3.drag().on("start", dragStarted));
function dragStarted() {
d3.event.on("drag", dragged)
startRadius = radius;
function dragged(d) {
radius = Math.abs(startRadius - d3.event.x);
update();
}
}
function update() {
var circ = radius*Math.PI*2;
var arcs = d3.range(0, Math.floor(circ/arcLength));
var arcDegrees = (arcLength / circ) * (Math.PI*2);
var arcsEl = svg.selectAll(".arc").data(arcs)
arcsEl.exit().remove()
arcsEl.enter()
.append("g")
.attr("transform", `translate(${width/2}, ${height/2})`)
.append("path")
.attr("fill", "red").attr("class", "arc")
arcsEl
.attr("d", d=>{
var startAngle = (d / arcs.length) * Math.PI *2;
var endAngle = startAngle + arcDegrees;
return arc({
innerRadius: radius*1.03,
outerRadius: radius*1.03+4,
startAngle: startAngle,
endAngle: endAngle
})
})
svg.select(".radius").attr("x2", width/2 + radius)
svg.select("circle").attr("r", radius)
svg.select(".radiusLabel").text(`r = ${radius}`).attr("x", width/2).attr("y", height/2 -10 )
svg.select(".circLabel").text(`c = ${rd(circ)}`).attr("x", width/2+radius).attr("y", height/2+radius*1.1)
svg.select(".arcsLabel").text(`${arcs.length} arcs of length ${arcLength}`)
svg.select(".gapLabel").text(`${rd((circ - (arcLength*arcs.length))/(arcs.length-1))} gap between arcs`)
}
function rd(n) {
return (Math.round(n*100)/100).toFixed(2);
}
update();
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment