<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@*" data-semver="3.2.2" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.min.js"></script>
    <script data-require="d3@*" data-semver="3.2.2" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.min.js"></script>
    
    <link rel="stylesheet" type="text/css" href="./style.css">
  </head>

  <body>
    <script src="./app.js"></script>
  </body>

</html>
let Gauge = function(configuration) {
  let that = {}

  let config = {
    size: 300,
    arcInset: 150,
    arcWidth: 60,

    pointerWidth: 8,
    pointerOffset: 0,
    pointerHeadLengthPercent: 0.9,

    minValue: 0,
    maxValue: 100000,

    minAngle: -90,
    maxAngle: 90,

    transitionMs: 750,

    currentLabelFontSize: 20,
    currentLabelInset: 20,
    labelFont: "Helvetica",
    labelFontSize: 15,
    labelFormat: (numberToFormat) => {
      let prefix = d3.formatPrefix(numberToFormat)
      console.log(prefix)
      return prefix.scale(numberToFormat) + '' + prefix.symbol.toUpperCase()
    },

    arcColorFn: function(value) {
      let ticks = [{
        tick: 0,
        color: 'green'
      }, {
        tick: 25000,
        color: 'yellow'
      }, {
        tick: 50000,
        color: 'orange'
      }, {
        tick: 75000,
        color: 'red'
      }]
      let ret;
      ticks.forEach(function(tick) {

        if (value > tick.tick) {
          ret = tick.color
          return
        }
      });
      return ret;
    }
  }

  function configure(configuration) {
    for (let prop in configuration) {
      config[prop] = configuration[prop]
    }
  }
  configure(configuration);

  let foreground, arc, svg, current;
  let cur_color;
  let new_color, hold;

  var oR = config.size - config.arcInset;
  var iR = config.size - oR - config.arcWidth;

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

  function render(value) {

    //oR = 30;
    //iR = 10;



    // Arc Defaults
    arc = d3.svg.arc()
      .innerRadius(iR)
      .outerRadius(oR)
      .startAngle(deg2rad(-90))

    // Place svg element
    svg = d3.select("body").append("svg")
      .attr("width", config.size)
      .attr("height", config.size)
      .append("g")
      .attr("transform", "translate(" + config.size / 2 + "," + config.size / 2 + ")")


    // Append background arc to svg
    var background = svg.append("path")
      .datum({
        endAngle: deg2rad(90)
      })
      .attr("class", "gaugeBackground")
      .attr("d", arc)

    // Append foreground arc to svg
    foreground = svg.append("path")
      .datum({
        endAngle: deg2rad(-90)
      })
      //.style("fill", cur_color)
      .attr("d", arc);

    // Display Max value
    var max = svg.append("text")
      .attr("transform", "translate(" + (iR + ((oR - iR) / 2)) + ",15)") // Set between inner and outer Radius
      .attr("text-anchor", "middle")
      .style("font-family", config.labelFont)
      .text(config.labelFormat(config.maxValue))

    // Display Min value
    var min = svg.append("text")
      .attr("transform", "translate(" + -(iR + ((oR - iR) / 2)) + ",15)") // Set between inner and outer Radius
      .attr("text-anchor", "middle")
      .style("font-size", config.labelFontSize)
      .style("font-family", config.labelFont)
      .text(config.minValue)

    // Display Current value  
    current = svg.append("text")
      .attr("transform", "translate(0," + -(-config.currentLabelInset + iR / 4) + ")") // Push up from center 1/4 of innerRadius
      .attr("text-anchor", "middle")
      .style("font-size", config.currentLabelFontSize)
      .style("font-family", config.labelFont)
      .text(config.labelFormat(current))
  }


  function update(value) {
    // Get new color
    new_color = config.arcColorFn(value)
    console.log(new_color)

    var numPi = deg2rad(Math.floor(value * 180 / config.maxValue - 90));

    // Display Current value
    current.transition()
      .text(value)
      // .text(config.labelFormat(value))

    // Arc Transition
    foreground.transition()
      .duration(config.transitionMs)
      .styleTween("fill", function() {
        return d3.interpolate(new_color, cur_color);
      })
      .call(arcTween, numPi);

    // Set colors for next transition
    hold = cur_color;
    cur_color = new_color;
    new_color = hold;
  }

  // Update animation
  function arcTween(transition, newAngle) {
    transition.attrTween("d", function(d) {
      var interpolate = d3.interpolate(d.endAngle, newAngle);
      return function(t) {
        d.endAngle = interpolate(t);
        return arc(d);
      };
    });
  }

  render();
  that.update = update;
  that.configuration = config;
  return that;
}

let g = new Gauge({
  size: 200
});
console.log(g)
g.update(30000);
g.update(70000);
.gaugeBackground {
  fill: #ddd;
}