Public
Edited
Apr 20, 2024
1 fork
Insert cell
Insert cell
Insert cell
<svg width="400" height="400" viewBox="0 0 400 400">
<style>
.arcArea {stroke: black; stroke-width: 1px; fill: steelblue; opacity: 0.8;}
</style>
<g id="layer1" transform="translate(200,200)"></g>
</svg>
Insert cell
Insert cell
data = ([
{inR:100, outR:120, startAng:0, endAng:60},
{inR:50, outR:60, startAng:60, endAng:145},
{inR:150, outR:180, startAng:60, endAng:145},
{inR:120, outR:165, startAng:145, endAng:220},
{inR:30, outR:150, startAng:265, endAng:275},
{inR:30, outR:120, startAng:275, endAng:285},
{inR:30, outR:200, startAng:285, endAng:295},
{inR:30, outR:90, startAng:295, endAng:305}
])
Insert cell
arcAreasLayer = d3.select(svgContainer).select("#layer1");
Insert cell
arcAreas = {
let arcAreas = arcAreasLayer.selectAll(".arcArea")
.data(data)
.join("path")
.classed("arcArea",true)
.attr("d", d => arcPolygonPath(d.inR, d.outR, d.startAng, d.endAng)); // direct from data or calculate and pass in
return arcAreas;
}
Insert cell
Insert cell
arcPoint = (radius,angle) => {return polarXY(radius+adjust,90-angle)} // example shows starting at 90deg going clockwise (90-angle)
Insert cell
Insert cell
arcPolygonPath = (inR,outR,startAng,endAng) => {
let largeArcFlag = (startAngle,endAngle) => {if (endAngle - startAngle > 180) {return 1} else {return 0}} // largearc calc
let pathString =
"M " + arcPoint(inR,startAng).x + " " + arcPoint(inR,startAng).y + // move to start point
" A " + inR + " " + inR + // draw Arc with x and y radii
" 0" + // rotation of the whole thing, assuming 0
" " + largeArcFlag(startAng,endAng) + // calculate Large Arc Flag (> 180 deg)
" 1 " + // clockwise drawing for the arc (0 or 1)
arcPoint(inR,endAng).x + " " + arcPoint(inR,endAng).y // finish at the end point x,y
+
" L " + arcPoint(outR,endAng).x + " " + arcPoint(outR,endAng).y // line to outer radius at endAngle
+
" A " + outR + " " + outR + // new arc heading back on outside
" 0" +
" " + largeArcFlag(startAng,endAng) +
" 0 " + // counterclockwise this time, going back.
arcPoint(outR,startAng).x + " " + arcPoint(outR,startAng).y
+ " Z"; // close the polygon back to start (line to start)
return pathString;
}
Insert cell
Insert cell
Insert cell
polarXY = (magnitude,angle) => {
magnitude = Number(magnitude);
angle = Number(angle);
let x = magnitude * Math.cos(radiansFromDeg(angle));
let y = -magnitude * Math.sin(radiansFromDeg(angle)); // negative because 0 is at the top
return {"x":x, "y":y};
}
Insert cell
radiansFromDeg = (deg) => {
deg = Number(deg);
return deg * Math.PI / 180;
}
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