Gauge

by Peter Galiba

HTML

<input type="number" min="0" max="180" id="counter" value="60" />
<div id="raphael-canvas"></div>

JavaScript

/*global document, window, Raphael*/
(function (Raphael) {
  var paper = new Raphael(document.getElementById('raphael-canvas'), 640, 480), color = '#8cc63f';

  /**
   * Replace the variables in text with the components in vars.
   *
   * @param {String} path
   *   The SVG path string.
   * @param {Object} vars
   *   Variable holder.
   */
  function replaceVars(path, vars) {
    return path.replace(/[vs][a-zA-Z]/g, function (match) {
      return vars[match];
    });
  }

  function drawArrow(xloc, yloc, value, r) {
    var arrow = paper.set(),
        R = 5,
        path = replaceVars('Mvx,vy lvR,-vr vR,vr', {
          vx: xloc + r - R + 2,
          vy: yloc,
          vr: r,
          vR: R - 2
        });

    arrow.push(
      paper.path(path).attr({fill: '#4e4e4e', stroke: 'none'}).rotate(value - 90, xloc + r, yloc),
      paper.circle(xloc + r, yloc, R).attr({fill: '#989898', stroke: 'none'})
    );
  }

  /**
   * Draw the scale lines for the gauge.
   *
   * @param {Number} xloc
   *   The start point's x component.
   * @param {Number} yloc
   *   The start point's y component.
   * @param {Number} value
   *   Degree between 0 and 180 to show.
   * @param {Number} r
   *   The circle's radius.
   */
  function drawScale(xloc, yloc, value, r) {
    var i = 1,
        segments = 12,
        R = r - 10,
        sa,
        alpha,
        a,
        x,
        y,
        sx,
        sy,
        vars,
        degree,
        diff = 0.5,
        wide,
        path,
        scale = paper.set();

    for (; i < segments; i += 1) {
      degree = 180 / segments * i;
      // Check if the current scale should be wide.
      wide = (i % 4 === 0 && degree <= value);
      diff = wide ? 1 : 0.5;
      alpha = degree - diff;
      a = Raphael.rad(alpha);
      sa = Raphael.rad(alpha + 2 * diff);
      x = Math.cos(a);
      y = Math.sin(a);
      sx = Math.cos(sa);
      sy = Math.sin(sa);
      vars = {
        vx: xloc + r - r * x,
        vy: yloc - r * y,
  ...