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

@import url('//fonts.googleapis.com/css?family=Roboto:500');

body {
  background-color: #2c2c35;
}

#canvas {
  width: 960px;
  height: 500px;
  margin: auto;
}

.background-arc {
  fill: #46464f;
}

.readout-number {
  fill: #ffffff;
  text-anchor: middle;
  font-size: 160px;
  font-family: 'Roboto';
}

JavaScript

var minAngle = -135;
var maxAngle = 135;
var minSpeed = 0;
var maxSpeed = 160;
var currentSpeed = 80;

var start = d3.rgb('#9393a2');
start.opacity = 0;

var end = d3.rgb('#9393a2');
end.opacity = 1;
var color = d3.scaleLinear().clamp(true);

function randomSpeed() {
  return Math.floor(Math.random() * (maxSpeed - minSpeed + 1)) + minSpeed;
}

function deg2rad(deg) {
  return deg * Math.PI / 180;
}

function speed2rad(speed) {
  return deg2rad(scale(speed));
}

var scale = d3.scaleLinear()
  .range([minAngle, maxAngle])
  .domain([minSpeed, maxSpeed])
  .clamp(true);

var arc = d3.arc()
  .startAngle(speed2rad(minSpeed));

// Get the SVG container, and apply a transform such that the origin is the
// center of the canvas. This way, we don’t need to position arcs individually.
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 + ")");

// Add the background arc, from 0 to 100% (tau).
var background = g.append("path")
  .datum({
    innerRadius: 210,
    outerRadius: 220,
    endAngle: speed2rad(maxSpeed)
  })
  .attr('class', 'background-arc')
  .attr("d", arc);

var readout = svg.append("g")
  .attr("transform", "translate(" + width / 2 + "," + (height + 100) / 2 + ")");

var readoutNumber = readout.append('text')
	.attr("class", "readout-number")
  .text(0);

// Add the gradient
var gradientDefs = svg.append("svg:defs");
// Define the gradient
var gradient = gradientDefs.append("svg:linearGradient")
  .attr("id", "currentSpeed")
  .attr("spreadMethod", "pad");

// Define the gradient color stops
gradient.append("svg:stop")
  .attr("offset", "30%")
  .attr("stop-color", "#9393a2")
  .attr("stop-opacity", 0.0);

gradient.append("svg:stop")
  .attr("offset", "100%")
  .attr("stop-color", "#9393a2")
  .attr("stop-opacity", 0.5);

// Add the foreground arc in white
var...