D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mbostock
Full window
Github gist
Circle in Sector
<!DOCTYPE html> <meta charset="utf-8"> <style> .sector, .circle { fill: none; stroke: #666; } .wedge { fill: #ddd; stroke: #333; stroke-width: 1.5px; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var width = 960, height = 500, sectorRadius = 400; var arc = d3.svg.arc() .innerRadius(0); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + (sectorRadius + (height - sectorRadius) / 2) + ")"); var sector = svg.append("path").attr("class", "sector"), wedge = svg.append("path").attr("class", "wedge"), circle = svg.append("circle").attr("class", "circle"); var ease = d3.ease("cubic-in-out"), duration = 7500; d3.timer(function(elapsed) { var t = ease(1 - Math.abs((elapsed % duration) / duration - .5) * 2), startAngle = -Math.PI / 3 * t - .1, endAngle = -startAngle, circleRadius = sectorRadius / (1 / Math.sin((endAngle - startAngle) / 2) + 1), p0 = [0, 0], p1 = [sectorRadius * Math.cos(startAngle - Math.PI / 2), sectorRadius * Math.sin(startAngle - Math.PI / 2)], p2 = [sectorRadius * Math.cos(endAngle - Math.PI / 2), sectorRadius * Math.sin(endAngle - Math.PI / 2)], t1 = cornerTangents(p0, p1, sectorRadius, circleRadius, 1), t2 = cornerTangents(p0, p2, sectorRadius, circleRadius, 1); sector.attr("d", arc .outerRadius(sectorRadius) .startAngle(startAngle) .endAngle(endAngle)); wedge.attr("d", "M" + p0 + "L" + t1[0] + "A" + circleRadius + "," + circleRadius + " 0 1,1 " + t2[0] + "Z"); circle .attr("cy", circleRadius - sectorRadius) .attr("r", circleRadius); }); function cornerTangents(p0, p1, r1, rc, cw) { var x01 = p0[0] - p1[0], y01 = p0[1] - p1[1], lo = (cw ? rc : -rc) / Math.sqrt(x01 * x01 + y01 * y01), ox = lo * y01, oy = -lo * x01, x1 = p0[0] + ox, y1 = p0[1] + oy, x2 = p1[0] + ox, y2 = p1[1] + oy, x3 = (x1 + x2) / 2, y3 = (y1 + y2) / 2, dx = x2 - x1, dy = y2 - y1, d2 = dx * dx + dy * dy, r = r1 - rc, D = x1 * y2 - x2 * y1, d = (dy < 0 ? -1 : 1) * Math.sqrt(r * r * d2 - D * D), cx0 = (D * dy - dx * d) / d2, cy0 = (-D * dx - dy * d) / d2, cx1 = (D * dy + dx * d) / d2, cy1 = (-D * dx + dy * d) / d2, dx0 = cx0 - x3, dy0 = cy0 - y3, dx1 = cx1 - x3, dy1 = cy1 - y3; // Pick the closer of the two intersection points. // TODO Is there a faster way to determine which intersection to use? if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; return [ [cx0 - ox, cy0 - oy], [cx0 * r1 / r, cy0 * r1 / r] ]; } </script>
https://d3js.org/d3.v3.min.js