D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mforando
Full window
Github gist
Polar Labeling Logic
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } </style> </head> <body> <script> var width = 500; var height = 500; // Feel free to change or delete any of the code you see in this editor! var svg = d3.select("body").append("svg") .attr("width", 500) .attr("height", 500) .style("overflow","visible") var chart = svg.append("g") .attr("transform","translate(250,250)") var mainCircle = chart.append("circle") .attr("r",width/4) .attr("fill","white") .attr("stroke","black") var randAngles = d3.range(10).map(function(d){ return {"angle":Math.random()*Math.PI - Math.PI/2} }) var scaleBand = d3.scaleBand() .domain(randAngles .sort(function(a,b){return d3.ascending(a.angle,b.angle)}) .map(function(d,i){return i})) .range([-height/2 + 20,height/2 - 20]) var radiusInner = width/4; var radiusOuterMin = width/4 + 15; var radiusOuterMax = width/2; var radiusScale = d3.scaleLinear() .range([radiusOuterMin,radiusOuterMax,radiusOuterMin]) .domain([0,Math.PI,Math.PI*2]) var circles = chart.selectAll(".randcircles") .data(randAngles) circles.enter() .append("circle") .attr("r",3) .attr("cx",function(d){return Math.cos(d.angle)*radiusInner}) .attr("cy",function(d){return Math.sin(d.angle)*radiusInner}) var lbls = chart.selectAll(".randcircles") .data(randAngles) lbls.enter() .append("text") .text(function(d){return d3.format('0.2f')(d.angle)}) .attr("x",300) .attr("y",function(d,i){return scaleBand(i)}) var polyLineData = randAngles.map(function(d,i){ //figure out the current angle. var curAngle = d.angle; //figure out the slope for the current angle. var slope = (Math.sin(d.angle)*radiusInner)/(Math.cos(d.angle)*radiusInner); //y = mx + b; // intercept = 0 so // y = mx; // y/m = x; //solve for the intersection between the desired y-position // the equation for the label's line is just the Y value desired (constant) var desiredY = scaleBand(i); var xVal = desiredY/slope; var yVal = desiredY; //adjust the second point if its in the wrong direction. if(xVal<Math.cos(d.angle)*radiusInner || xVal > 300){ xVal = 250; yVal = Math.sin(d.angle)*radiusInner; } return [[Math.cos(d.angle)*radiusInner,Math.sin(d.angle)*radiusInner], [xVal,yVal], [300,desiredY]] }) var paths = chart.selectAll("polyline") .data(polyLineData) paths.enter() .append("polyline") .attr("points",function(d){return d}) .attr("stroke","black") .attr("fill","none") console.log(polyLineData) </script> </body>
https://d3js.org/d3.v4.min.js