D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
wonga00
Full window
Github gist
Labeling arcs at the midpoint
<script src="https://d3js.org/d3.v4.min.js"></script> <body> <script> let width = 300; let height = 300; let svg = d3.select('body').append('svg') .attr('width', width) .attr('height', height) .append('g') .attr('transform', `translate(${width * 0.5}, ${height * 0.5})`); let outerRadius = 0.8 * width * 0.5, innerRadius = 0.6 * width * 0.5; let data = [ { startAngle: 0, endAngle: Math.PI * 1, name: "Cow" }, { startAngle: Math.PI * 1, endAngle: Math.PI * 1.2, name: "Banana" }, { startAngle: Math.PI * 1.2, endAngle: Math.PI * 1.8, name: "Apple" }, { startAngle: Math.PI * 1.8, endAngle: Math.PI * 2, name: "This is a long one" } ]; let color = d3.scaleOrdinal(d3.schemeCategory10); let arc = d3.arc() .outerRadius(outerRadius) .innerRadius(innerRadius) .startAngle(d => d.startAngle) .endAngle(d => d.endAngle); let bars = svg.selectAll('.bar').data(data); let barsEnter = bars.enter() .append('path') .attr('class', 'bar') bars.merge(barsEnter) .attr('d', d => arc(d)) .attr('fill', d => color(d.name)) // create arcs that wrap around the entire circle and have the midpoint // at the angle we want to center the text on let textArcData = data.map(d => { let angle = (d.startAngle + d.endAngle) * 0.5; if (angle > Math.PI / 2 && angle < Math.PI * 3 / 2) { return { startAngle: angle + Math.PI, endAngle: angle - Math.PI, lowerHalf: true, name: d.name } } else { return { startAngle: angle - Math.PI, endAngle: angle + Math.PI, lowerHalf: false, name: d.name } } }) let textArc = d3.arc() .outerRadius(outerRadius) .innerRadius(outerRadius); let textArcs = svg.selectAll('.text-arc').data(textArcData); let textArcsEnter = textArcs.enter() .append('path') .attr('class', 'text-arc') .merge(textArcs) .attr('d', d => textArc(d)) .attr('id', (d, i) => 'textarc' + i) .style("fill", "none"); svg.selectAll(".behaviorText") .data(textArcData) .enter().append("text") .attr("class", "behaviorText") .attr('dy', d => d.lowerHalf ? 14 : -4) .append("textPath") .attr("xlink:href", (d, i) => '#textarc' + i) // since the arc wraps around, a quarter of the length will be the midpoint .attr('startOffset', '25%') .style("text-anchor","middle") .text(d => d.name); </script> </body>
https://d3js.org/d3.v4.min.js