Drawing an Arc with D3
by JP Obley
HTML
<script src="//d3js.org/d3.v4.min.js"></script>
<div id="canvas">
<svg width="100%" height="100%"></svg>
</div>
CSS
body {
background-color:#bbbbbb;
}
#canvas {
width: 960px;
height: 500px;
margin: auto;
}
JavaScript
var minDeg = -90;
var maxDeg = 90;
var minValue = 0;
var maxValue = 100;
var currentValue = 40;
var n = 500;
var tailLength = 30;
var div = d3.select("#canvas");
var divBox = div.node().getBoundingClientRect();
var svg = d3.select("svg");
var width = divBox.width;
var height = divBox.height;
var g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
function randomValue() {
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function val2rad(val) {
return deg2rad(val2deg(val));
}
function rad2deg(rad) {
return rad * 180 / Math.PI;
}
var val2deg = d3.scaleLinear()
.range([minDeg, maxDeg])
.domain([minValue, maxValue])
.clamp(true);
var color = d3.scaleLinear()
.domain([0, n])
.range(['#bbbbbb', 'tomato'])
.clamp(true);
var fullArc = d3.arc()
.innerRadius(210)
.outerRadius(220)
.startAngle(val2rad(minValue))
.endAngle(val2rad(maxValue));
g.append("path")
.style("fill", "dodgerblue")
.attr("d", fullArc);
var tailArcs = d3.range(n).map(i => ({
i,
color: color(i),
startAngle: deg2rad(minDeg),
endAngle: deg2rad(minDeg)
}));
var tailArc = d3.arc()
.innerRadius(169)
.outerRadius(210)
.startAngle(d => d.startAngle)
.endAngle(d => d.endAngle);
var tails = g.selectAll("path.tail")
.data(tailArcs)
.enter()
.append('path')
.attr("class", "tail")
.attr("d", tailArc)
.style("fill", d => d.color)
.style("stroke", d => d.i === n - 1 ? 'none' : d.color);
function update(value) {
var maxDeg = val2deg(value);
var minDeg = val2deg(value - tailLength);
var step = (maxDeg - minDeg) / n;
tails.data(tailArcs)
.transition().duration(500)
.attrTween('d', tweenArc(d => {
var startAngle = minDeg + (d.i * step);
return {
startAngle: deg2rad(startAngle),
endAngle: deg2rad(startAngle + step)
}
}));
}
function tweenArc(getNextAngles) {
...