<commit_before>this['arcGauge'] = {};

ArcGauge.COLOR_MODE_RANGE = "colorModeRange";
ArcGauge.COLOR_MODE_VALUE = "colorModeValue";

// http://tauday.com/tau-manifesto -> TAU == 2PI
ArcGauge.τ = 2 * Math.PI;
ArcGauge.TAU = 2 * Math.PI;

ArcGauge.DISPLAY_PERCENTAGE = "displayAsPercentage";
ArcGauge.DISPLAY_VALUE = "displayAsValue";
ArcGauge.VALUES_PERCENTAGE = "valuesPercentage";
ArcGauge.VALUES_ACTUAL = "valuesActual";

function ArcGauge(options) {
  options = options || {};

  this.startAngle = ((options.startAngle !== null && options.startAngle !== undefined) ? options.startAngle : ArcGauge.TAU * 0.6);
  this.arcAngle = ((options.arcAngle !== null && options.arcAngle !== undefined) ? options.arcAngle : ArcGauge.TAU * 0.8);
  this.endAngle = this.startAngle + this.arcAngle;

  this.goodMargin = ((options.goodMargin !== null && options.goodMargin !== undefined) ? options.goodMargin : 2);
  this.dangerMargin = ((options.dangerMargin !== null && options.dangerMargin !== undefined) ? options.dangerMargin : 10);
  this.colorMode = ((options.colorMode !== null && options.colorMode !== undefined) ? options.colorMode : ArcGauge.COLOR_MODE_VALUE);

  this.valueType = ((options.valueType !== null && options.valueType !== undefined) ? options.valueType : ArcGauge.VALUES_ACTUAL);

  this.minValue = ((options.minValue !== null && options.minValue !== undefined) ? options.minValue : 0);
  this.maxValue = ((options.maxValue !== null && options.maxValue !== undefined) ? options.maxValue : 100);

  this.goodColor = ((options.goodColor !== null && options.goodColor !== undefined) ? options.goodColor : "green");
  this.warningColor = ((options.warningColor !== null && options.warningColor !== undefined) ? options.warningColor : "orange");
  this.dangerColor = ((options.dangerColor !== null && options.dangerColor !== undefined) ? options.dangerColor : "red");
  this.markColor = ((options.markColor !== null && options.markColor !== undefined) ? options.markColor : "gray");
  this.textColor = ((options.textColor !== null && options.textColor !== undefined) ? options.textColor : "black");
  this.backgroundColor = ((options.backgroundColor !== null && options.backgroundColor !== undefined) ? options.backgroundColor : "lightgray");

  this.value = ((options.value !== null && options.value !== undefined) ? options.value : 0);
  this.setValue(this.value, false);

  this.target = ((options.target !== null && options.target !== undefined) ? options.target : 0.5);
  this.setTarget(this.target, false);

  this.textDisplayMode = ((options.textDisplayMode !== null && options.textDisplayMode !== undefined) ? options.textDisplayMode : ArcGauge.DISPLAY_PERCENTAGE);
  this.textSize = ((options.textSize !== null && options.textSize !== undefined) ? options.textSize : 40);
  this.textFontName = ((options.textFontName !== null && options.textFontName !== undefined) ? options.textFontName : "sans-serif");
  this.textFontWeight = ((options.textFontWeight !== null && options.textFontWeight !== undefined) ? options.textFontWeight : "bold");

  this.appendTo = ((options.appendTo !== null && options.appendTo !== undefined) ? options.appendTo : "body");

  this.width = ((options.width !== null && options.width !== undefined) ? options.width : 300);
  this.height = ((options.height !== null && options.height !== undefined) ? options.height : 300);

  // An arc function with all values bound except the endAngle. So, to compute an
  // SVG path string for a given angle, we pass an object with an endAngle
  // property to the `arc` function, and it will return the corresponding string.

  this.innerRadius = ((options.innerRadius !== null && options.innerRadius !== undefined) ? options.innerRadius : 80);
  this.outerRadius = ((options.outerRadius !== null && options.outerRadius !== undefined) ? options.outerRadius : 120);
  this.markerInnerRadius = ((options.markerInnerRadius !== null && options.markerInnerRadius !== undefined) ? options.markerInnerRadius : options.outerRadius + 2);
  this.markerOuterRadius = ((options.markerOuterRadius !== null && options.markerOuterRadius !== undefined) ? options.markerOuterRadius : this.markerInnerRadius + 4);

  var arc = d3.svg.arc()
      .innerRadius(this.innerRadius)
      .outerRadius(this.outerRadius)
      .startAngle(this.startAngle);

  this.innerArc = d3.svg.arc()
      .innerRadius(this.innerRadius)
      .outerRadius(this.outerRadius)
      .startAngle(this.startAngle);

  this.markArc = d3.svg.arc()
      .innerRadius(this.markerInnerRadius)
      .outerRadius(this.markerOuterRadius)
      // .startAngle(this.startAngle + (this.arcAngle * (this.targetPercentage - 0.005)));
      .startAngle(this.startAngle);

  // Create 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.
  // setup the viewbox so that the size changes automatically

  var svg = d3.select("#" + this.appendTo).append("svg")
    .attr("width", this.width)
    .attr("height", this.height)
    .attr("class", "arcGauge")
    .attr("viewBox", "0 0 200 200")  // set viewBox to 200/200 so we can use 0 to 100 for sizing
    // .attr("perserveAspectRatio", "xMidYMid meet");
    // .attr("perserveAspectRatio", "none")
    .append("g").attr("transform", "translate(100, 100)");

  // determin the true size of the svg element
  //  var elem1 = document.getElementById(this.appendTo);
  //  var style = window.getComputedStyle(elem1, null);
  //  var svgBBox = svg.node().getBBox();
  // svg = svg.append("g").attr("transform", "translate(" + parseFloat(style.width) / 2 + "," + parseFloat(style.height) / 2 + ")");

  // Add the background arc, from 0 to 100% (τ).
  var background = svg.append("path")
      .datum({endAngle: this.endAngle})
      .style("fill", this.backgroundColor)
      .attr("d", arc);

  var foregroundColor = this._determineForegroundColor();

  this.targetMark = svg.append("path")
      .datum({endAngle: this.startAngle + (this.arcAngle * this.targetPercentage)})
      .style("fill", this.markColor)
      .attr("d", this.markArc);

  this.foreground = svg.append("path")
      .attr("id", "targetValue")
      .datum({endAngle: this.startAngle + (this.arcAngle * this.valuePercentage)})
      .style("fill", foregroundColor)
      .attr("d", this.innerArc);

  this.text = svg.append("text")
      .attr("id", "arcValue")
      .attr("dy", ".35em")
      .text(this._getTextValue())
      .attr("text-anchor", "middle")
      .attr("font-family", this.textFontName)
      .style("font-weight", this.textFontWeight)
      .style("font-size", this.textSize)
      .attr("fill", this.textColor);

  console.log("##font-size: " + this.textSize);

  // newText.setAttributeNS(null,"fill-opacity",Math.random());
  // newText.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")");
}

ArcGauge.prototype._getTextValue = function() {
  var displayText = '';

  switch(this.textDisplayMode) {
    case ArcGauge.DISPLAY_PERCENTAGE:
      displayText = this.valuePercentage * 100;
      break;

    case ArcGauge.DISPLAY_VALUE:
    default:
      displayText = this.value;
  }

  return displayText;
};

ArcGauge.prototype._determineForegroundColor = function() {
  var foregroundColor = this.goodColor;

  if(this.colorMode === ArcGauge.COLOR_MODE_VALUE) {
    if(this.value >= this.target - this.goodMargin) {
      foregroundColor = this.goodColor;
    } else if(this.value <= this.target - this.dangerMargin) {
      foregroundColor = this.dangerColor;
    } else {
      foregroundColor = this.warningColor;
    }
  }

  // TODO: sort out range mode for color
  if(this.colorMode === ArcGauge.COLOR_MODE_RANGE) {
    if(this.value < 0.3) {
      foregroundColor = this.dangerColor;
    } else if(this.value < 0.7) {
      foregroundColor = this.warningColor;
    } else {
      foregroundColor = this.goodColor;
    }
  }

  return foregroundColor;
};

ArcGauge.prototype.setTarget = function(newValue, redrawGauge) {
  redrawGauge = ((redrawGauge !== null && redrawGauge !== undefined) ? redrawGauge : true);

  this.target = newValue;

  if(this.valueType == ArcGauge.VALUES_ACTUAL) {
    this.targetPercentage = (this.target - this.minValue) / (this.maxValue - this.minValue);
  } else {
    this.targetPercentage = newValue;
  }

  if(redrawGauge) {
    var percentageValue = this.valuePercentage;

    (function(percentageValue, arcGaugeInst) {

//  var markArc = d3.svg.arc()
//      .innerRadius(122)
//      .outerRadius(126)
//      .startAngle(this.startAngle);
//
//  this.targetMark = svg.append("path")
//      .datum({endAngle: this.startAngle + (this.arcAngle * this.targetPercentage)})
//      .style("fill", "rgba(150, 150, 150, .8)")
//      .attr("d", markArc);

      arcGaugeInst.targetMark.transition()
        .duration(750)
        .call(arcTween, arcGaugeInst.startAngle + (arcGaugeInst.arcAngle * arcGaugeInst.targetPercentage), arcGaugeInst.markArc);

      arcGaugeInst.foreground.transition()
        .duration(750)
        .style("fill", arcGaugeInst._determineForegroundColor());
    })(this.valuePercentage, this);
  }
};

ArcGauge.prototype.setValue = function(newValue, redrawGauge) {
  redrawGauge = ((redrawGauge !== null && redrawGauge !== undefined) ? redrawGauge : true);
  var formatPercent = d3.format(".0%");

  if(newValue > this.maxValue) {
    newValue = this.maxValue;
  }

  if(newValue < this.minValue) {
    newValue = this.minValue;
  }

  this.value = newValue;
  var oldValue = 0;

  // TODO: sort out actual value, currently not working in tween function for text
  if(this.valueType == ArcGauge.VALUES_ACTUAL) {
    oldValue = this.valuePercentage;
    this.valuePercentage = (this.value - this.minValue) / (this.maxValue - this.minValue);
  } else {
    oldValue = this.valuePercentage;
    this.valuePercentage = newValue;
  }

  if(redrawGauge) {
    var percentageValue = this.valuePercentage;

    (function(percentageValue, arcGaugeInst) {
      arcGaugeInst.foreground.transition()
        .duration(750)
        .style("fill", arcGaugeInst._determineForegroundColor())
        .call(arcTween, arcGaugeInst.startAngle + (arcGaugeInst.arcAngle * arcGaugeInst.valuePercentage), arcGaugeInst.innerArc);

      arcGaugeInst.text.transition()
        .duration(750)
        .ease('linear')
        .tween('text', function() {
          var ip = d3.interpolate(oldValue, percentageValue);
          return function(t) {
            var v = ip(t);
            // this.textContent = Math.round(v * 100);
            this.textContent = formatPercent(v);
          };
      });
    })(this.valuePercentage, this);
  }

  // note: cannot bind this to the tween function, as this points to the selection of the tween
};

ArcGauge.prototype.demo = function() {
  // Every so often, start a transition to a new random angle. Use transition.call
  // (identical to selection.call) so that we can encapsulate the logic for
  // tweening the arc in a separate function below.

  setInterval(function() {
    if(this.valueType == ArcGauge.VALUES_ACTUAL) {
      this.setTarget(Math.random() * 100);
      this.setValue(Math.random() * 100);
    } else {
      this.setTarget(Math.random());
      this.setValue(Math.random());
    }
  }.bind(this), 1500);
};

// Creates a tween on the specified transition's "d" attribute, transitioning
// any selected arcs from their current angle to the specified new angle.
function arcTween(transition, newAngle, arc) {
  // The function passed to attrTween is invoked for each selected element when
  // the transition starts, and for each element returns the interpolator to use
  // over the course of transition. This function is thus responsible for
  // determining the starting angle of the transition (which is pulled from the
  // element's bound datum, d.endAngle), and the ending angle (simply the
  // newAngle argument to the enclosing function).
  transition.attrTween("d", function(d) {

    // To interpolate between the two angles, we use the default d3.interpolate.
    // (Internally, this maps to d3.interpolateNumber, since both of the
    // arguments to d3.interpolate are numbers.) The returned function takes a
    // single argument t and returns a number between the starting angle and the
    // ending angle. When t = 0, it returns d.endAngle; when t = 1, it returns
    // newAngle; and for 0 < t < 1 it returns an angle in-between.
    var interpolate = d3.interpolate(d.endAngle, newAngle);

    // The return value of the attrTween is also a function: the function that
    // we want to run for each tick of the transition. Because we used
    // attrTween("d"), the return value of this last function will be set to the
    // "d" attribute at every tick. (It's also possible to use transition.tween
    // to run arbitrary code for every tick, say if you want to set multiple
    // attributes from a single function.) The argument t ranges from 0, at the
    // start of the transition, to 1, at the end.
    return function(t) {

      // Calculate the current arc angle based on the transition time, t. Since
      // the t for the transition and the t for the interpolate both range from
      // 0 to 1, we can pass t directly to the interpolator.
      //
      // Note that the interpolated angle is written into the element's bound
      // data object! This is important: it means that if the transition were
      // interrupted, the data bound to the element would still be consistent
      // with its appearance. Whenever we start a new arc transition, the
      // correct starting angle can be inferred from the data.
      d.endAngle = interpolate(t);

      // Lastly, compute the arc path given the updated data! In effect, this
      // transition uses data-space interpolation: the data is interpolated
      // (that is, the end angle) rather than the path string itself.
      // Interpolating the angles in polar coordinates, rather than the raw path
      // string, produces valid intermediate arcs during the transition.
      return arc(d);
    };
  });
}
<commit_msg>Added range checking to setTarget()<commit_after>this['arcGauge'] = {};

ArcGauge.COLOR_MODE_RANGE = "colorModeRange";
ArcGauge.COLOR_MODE_VALUE = "colorModeValue";

// http://tauday.com/tau-manifesto -> TAU == 2PI
ArcGauge.τ = 2 * Math.PI;
ArcGauge.TAU = 2 * Math.PI;

ArcGauge.DISPLAY_PERCENTAGE = "displayAsPercentage";
ArcGauge.DISPLAY_VALUE = "displayAsValue";
ArcGauge.VALUES_PERCENTAGE = "valuesPercentage";
ArcGauge.VALUES_ACTUAL = "valuesActual";

function ArcGauge(options) {
  options = options || {};

  this.startAngle = ((options.startAngle !== null && options.startAngle !== undefined) ? options.startAngle : ArcGauge.TAU * 0.6);
  this.arcAngle = ((options.arcAngle !== null && options.arcAngle !== undefined) ? options.arcAngle : ArcGauge.TAU * 0.8);
  this.endAngle = this.startAngle + this.arcAngle;

  this.goodMargin = ((options.goodMargin !== null && options.goodMargin !== undefined) ? options.goodMargin : 2);
  this.dangerMargin = ((options.dangerMargin !== null && options.dangerMargin !== undefined) ? options.dangerMargin : 10);
  this.colorMode = ((options.colorMode !== null && options.colorMode !== undefined) ? options.colorMode : ArcGauge.COLOR_MODE_VALUE);

  this.valueType = ((options.valueType !== null && options.valueType !== undefined) ? options.valueType : ArcGauge.VALUES_ACTUAL);

  this.minValue = ((options.minValue !== null && options.minValue !== undefined) ? options.minValue : 0);
  this.maxValue = ((options.maxValue !== null && options.maxValue !== undefined) ? options.maxValue : 100);

  this.goodColor = ((options.goodColor !== null && options.goodColor !== undefined) ? options.goodColor : "green");
  this.warningColor = ((options.warningColor !== null && options.warningColor !== undefined) ? options.warningColor : "orange");
  this.dangerColor = ((options.dangerColor !== null && options.dangerColor !== undefined) ? options.dangerColor : "red");
  this.markColor = ((options.markColor !== null && options.markColor !== undefined) ? options.markColor : "gray");
  this.textColor = ((options.textColor !== null && options.textColor !== undefined) ? options.textColor : "black");
  this.backgroundColor = ((options.backgroundColor !== null && options.backgroundColor !== undefined) ? options.backgroundColor : "lightgray");

  this.value = ((options.value !== null && options.value !== undefined) ? options.value : 0);
  this.setValue(this.value, false);

  this.target = ((options.target !== null && options.target !== undefined) ? options.target : 0.5);
  this.setTarget(this.target, false);

  this.textDisplayMode = ((options.textDisplayMode !== null && options.textDisplayMode !== undefined) ? options.textDisplayMode : ArcGauge.DISPLAY_PERCENTAGE);
  this.textSize = ((options.textSize !== null && options.textSize !== undefined) ? options.textSize : 40);
  this.textFontName = ((options.textFontName !== null && options.textFontName !== undefined) ? options.textFontName : "sans-serif");
  this.textFontWeight = ((options.textFontWeight !== null && options.textFontWeight !== undefined) ? options.textFontWeight : "bold");

  this.appendTo = ((options.appendTo !== null && options.appendTo !== undefined) ? options.appendTo : "body");

  this.width = ((options.width !== null && options.width !== undefined) ? options.width : 300);
  this.height = ((options.height !== null && options.height !== undefined) ? options.height : 300);

  // An arc function with all values bound except the endAngle. So, to compute an
  // SVG path string for a given angle, we pass an object with an endAngle
  // property to the `arc` function, and it will return the corresponding string.

  this.innerRadius = ((options.innerRadius !== null && options.innerRadius !== undefined) ? options.innerRadius : 80);
  this.outerRadius = ((options.outerRadius !== null && options.outerRadius !== undefined) ? options.outerRadius : 120);
  this.markerInnerRadius = ((options.markerInnerRadius !== null && options.markerInnerRadius !== undefined) ? options.markerInnerRadius : options.outerRadius + 2);
  this.markerOuterRadius = ((options.markerOuterRadius !== null && options.markerOuterRadius !== undefined) ? options.markerOuterRadius : this.markerInnerRadius + 4);

  var arc = d3.svg.arc()
      .innerRadius(this.innerRadius)
      .outerRadius(this.outerRadius)
      .startAngle(this.startAngle);

  this.innerArc = d3.svg.arc()
      .innerRadius(this.innerRadius)
      .outerRadius(this.outerRadius)
      .startAngle(this.startAngle);

  this.markArc = d3.svg.arc()
      .innerRadius(this.markerInnerRadius)
      .outerRadius(this.markerOuterRadius)
      // .startAngle(this.startAngle + (this.arcAngle * (this.targetPercentage - 0.005)));
      .startAngle(this.startAngle);

  // Create 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.
  // setup the viewbox so that the size changes automatically

  var svg = d3.select("#" + this.appendTo).append("svg")
    .attr("width", this.width)
    .attr("height", this.height)
    .attr("class", "arcGauge")
    .attr("viewBox", "0 0 200 200")  // set viewBox to 200/200 so we can use 0 to 100 for sizing
    // .attr("perserveAspectRatio", "xMidYMid meet");
    // .attr("perserveAspectRatio", "none")
    .append("g").attr("transform", "translate(100, 100)");

  // determin the true size of the svg element
  //  var elem1 = document.getElementById(this.appendTo);
  //  var style = window.getComputedStyle(elem1, null);
  //  var svgBBox = svg.node().getBBox();
  // svg = svg.append("g").attr("transform", "translate(" + parseFloat(style.width) / 2 + "," + parseFloat(style.height) / 2 + ")");

  // Add the background arc, from 0 to 100% (τ).
  var background = svg.append("path")
      .datum({endAngle: this.endAngle})
      .style("fill", this.backgroundColor)
      .attr("d", arc);

  var foregroundColor = this._determineForegroundColor();

  this.targetMark = svg.append("path")
      .datum({endAngle: this.startAngle + (this.arcAngle * this.targetPercentage)})
      .style("fill", this.markColor)
      .attr("d", this.markArc);

  this.foreground = svg.append("path")
      .attr("id", "targetValue")
      .datum({endAngle: this.startAngle + (this.arcAngle * this.valuePercentage)})
      .style("fill", foregroundColor)
      .attr("d", this.innerArc);

  this.text = svg.append("text")
      .attr("id", "arcValue")
      .attr("dy", ".35em")
      .text(this._getTextValue())
      .attr("text-anchor", "middle")
      .attr("font-family", this.textFontName)
      .style("font-weight", this.textFontWeight)
      .style("font-size", this.textSize)
      .attr("fill", this.textColor);

  console.log("##font-size: " + this.textSize);

  // newText.setAttributeNS(null,"fill-opacity",Math.random());
  // newText.setAttributeNS(null,"fill","rgb("+ red +","+ green+","+blue+")");
}

ArcGauge.prototype._getTextValue = function() {
  var displayText = '';

  switch(this.textDisplayMode) {
    case ArcGauge.DISPLAY_PERCENTAGE:
      displayText = this.valuePercentage * 100;
      break;

    case ArcGauge.DISPLAY_VALUE:
    default:
      displayText = this.value;
  }

  return displayText;
};

ArcGauge.prototype._determineForegroundColor = function() {
  var foregroundColor = this.goodColor;

  if(this.colorMode === ArcGauge.COLOR_MODE_VALUE) {
    if(this.value >= this.target - this.goodMargin) {
      foregroundColor = this.goodColor;
    } else if(this.value <= this.target - this.dangerMargin) {
      foregroundColor = this.dangerColor;
    } else {
      foregroundColor = this.warningColor;
    }
  }

  // TODO: sort out range mode for color
  if(this.colorMode === ArcGauge.COLOR_MODE_RANGE) {
    if(this.value < 0.3) {
      foregroundColor = this.dangerColor;
    } else if(this.value < 0.7) {
      foregroundColor = this.warningColor;
    } else {
      foregroundColor = this.goodColor;
    }
  }

  return foregroundColor;
};

ArcGauge.prototype.setTarget = function(newValue, redrawGauge) {
  redrawGauge = ((redrawGauge !== null && redrawGauge !== undefined) ? redrawGauge : true);

  if(newValue > this.maxValue) {
    newValue = this.maxValue;
  }

  if(newValue < this.minValue) {
    newValue = this.minValue;
  }

  this.target = newValue;

  if(this.valueType == ArcGauge.VALUES_ACTUAL) {
    this.targetPercentage = (this.target - this.minValue) / (this.maxValue - this.minValue);
  } else {
    this.targetPercentage = newValue;
  }

  if(redrawGauge) {
    var percentageValue = this.valuePercentage;

    (function(percentageValue, arcGaugeInst) {

//  var markArc = d3.svg.arc()
//      .innerRadius(122)
//      .outerRadius(126)
//      .startAngle(this.startAngle);
//
//  this.targetMark = svg.append("path")
//      .datum({endAngle: this.startAngle + (this.arcAngle * this.targetPercentage)})
//      .style("fill", "rgba(150, 150, 150, .8)")
//      .attr("d", markArc);

      arcGaugeInst.targetMark.transition()
        .duration(750)
        .call(arcTween, arcGaugeInst.startAngle + (arcGaugeInst.arcAngle * arcGaugeInst.targetPercentage), arcGaugeInst.markArc);

      arcGaugeInst.foreground.transition()
        .duration(750)
        .style("fill", arcGaugeInst._determineForegroundColor());
    })(this.valuePercentage, this);
  }
};

ArcGauge.prototype.setValue = function(newValue, redrawGauge) {
  redrawGauge = ((redrawGauge !== null && redrawGauge !== undefined) ? redrawGauge : true);
  var formatPercent = d3.format(".0%");

  if(newValue > this.maxValue) {
    newValue = this.maxValue;
  }

  if(newValue < this.minValue) {
    newValue = this.minValue;
  }

  this.value = newValue;
  var oldValue = 0;

  // TODO: sort out actual value, currently not working in tween function for text
  if(this.valueType == ArcGauge.VALUES_ACTUAL) {
    oldValue = this.valuePercentage;
    this.valuePercentage = (this.value - this.minValue) / (this.maxValue - this.minValue);
  } else {
    oldValue = this.valuePercentage;
    this.valuePercentage = newValue;
  }

  if(redrawGauge) {
    var percentageValue = this.valuePercentage;

    (function(percentageValue, arcGaugeInst) {
      arcGaugeInst.foreground.transition()
        .duration(750)
        .style("fill", arcGaugeInst._determineForegroundColor())
        .call(arcTween, arcGaugeInst.startAngle + (arcGaugeInst.arcAngle * arcGaugeInst.valuePercentage), arcGaugeInst.innerArc);

      arcGaugeInst.text.transition()
        .duration(750)
        .ease('linear')
        .tween('text', function() {
          var ip = d3.interpolate(oldValue, percentageValue);
          return function(t) {
            var v = ip(t);
            // this.textContent = Math.round(v * 100);
            this.textContent = formatPercent(v);
          };
      });
    })(this.valuePercentage, this);
  }

  // note: cannot bind this to the tween function, as this points to the selection of the tween
};

ArcGauge.prototype.demo = function() {
  // Every so often, start a transition to a new random angle. Use transition.call
  // (identical to selection.call) so that we can encapsulate the logic for
  // tweening the arc in a separate function below.

  setInterval(function() {
    if(this.valueType == ArcGauge.VALUES_ACTUAL) {
      this.setTarget(Math.random() * 100);
      this.setValue(Math.random() * 100);
    } else {
      this.setTarget(Math.random());
      this.setValue(Math.random());
    }
  }.bind(this), 1500);
};

// Creates a tween on the specified transition's "d" attribute, transitioning
// any selected arcs from their current angle to the specified new angle.
function arcTween(transition, newAngle, arc) {
  // The function passed to attrTween is invoked for each selected element when
  // the transition starts, and for each element returns the interpolator to use
  // over the course of transition. This function is thus responsible for
  // determining the starting angle of the transition (which is pulled from the
  // element's bound datum, d.endAngle), and the ending angle (simply the
  // newAngle argument to the enclosing function).
  transition.attrTween("d", function(d) {

    // To interpolate between the two angles, we use the default d3.interpolate.
    // (Internally, this maps to d3.interpolateNumber, since both of the
    // arguments to d3.interpolate are numbers.) The returned function takes a
    // single argument t and returns a number between the starting angle and the
    // ending angle. When t = 0, it returns d.endAngle; when t = 1, it returns
    // newAngle; and for 0 < t < 1 it returns an angle in-between.
    var interpolate = d3.interpolate(d.endAngle, newAngle);

    // The return value of the attrTween is also a function: the function that
    // we want to run for each tick of the transition. Because we used
    // attrTween("d"), the return value of this last function will be set to the
    // "d" attribute at every tick. (It's also possible to use transition.tween
    // to run arbitrary code for every tick, say if you want to set multiple
    // attributes from a single function.) The argument t ranges from 0, at the
    // start of the transition, to 1, at the end.
    return function(t) {

      // Calculate the current arc angle based on the transition time, t. Since
      // the t for the transition and the t for the interpolate both range from
      // 0 to 1, we can pass t directly to the interpolator.
      //
      // Note that the interpolated angle is written into the element's bound
      // data object! This is important: it means that if the transition were
      // interrupted, the data bound to the element would still be consistent
      // with its appearance. Whenever we start a new arc transition, the
      // correct starting angle can be inferred from the data.
      d.endAngle = interpolate(t);

      // Lastly, compute the arc path given the updated data! In effect, this
      // transition uses data-space interpolation: the data is interpolated
      // (that is, the end angle) rather than the path string itself.
      // Interpolating the angles in polar coordinates, rather than the raw path
      // string, produces valid intermediate arcs during the transition.
      return arc(d);
    };
  });
}
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const binance = require ('./binance.js');

//  ---------------------------------------------------------------------------

module.exports = class binanceus extends binance {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'binanceus',
            'name': 'Binance US',
            'countries': [ 'US' ], // US
            'certified': false,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/65177307-217b7c80-da5f-11e9-876e-0b748ba0a358.jpg',
                'api': {
                    'web': 'https://www.binance.us',
                    'wapi': 'https://api.binance.us/wapi/v3',
                    'public': 'https://api.binance.us/api/v1',
                    'private': 'https://api.binance.us/api/v3',
                    'v3': 'https://api.binance.us/api/v3',
                    'v1': 'https://api.binance.us/api/v1',
                },
                'www': 'https://www.binance.us',
                'referral': 'https://www.binance.us/?ref=35005074',
                'doc': 'https://github.com/binance-us/binance-official-api-docs',
                'fees': 'https://www.binance.us/en/fee/schedule',
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'taker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
                    'maker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
                },
            },
        });
    }
};

<commit_msg>binanceus explicit pro: true<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const binance = require ('./binance.js');

//  ---------------------------------------------------------------------------

module.exports = class binanceus extends binance {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'binanceus',
            'name': 'Binance US',
            'countries': [ 'US' ], // US
            'certified': false,
            'pro': true,
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/1294454/65177307-217b7c80-da5f-11e9-876e-0b748ba0a358.jpg',
                'api': {
                    'web': 'https://www.binance.us',
                    'wapi': 'https://api.binance.us/wapi/v3',
                    'public': 'https://api.binance.us/api/v1',
                    'private': 'https://api.binance.us/api/v3',
                    'v3': 'https://api.binance.us/api/v3',
                    'v1': 'https://api.binance.us/api/v1',
                },
                'www': 'https://www.binance.us',
                'referral': 'https://www.binance.us/?ref=35005074',
                'doc': 'https://github.com/binance-us/binance-official-api-docs',
                'fees': 'https://www.binance.us/en/fee/schedule',
            },
            'fees': {
                'trading': {
                    'tierBased': false,
                    'percentage': true,
                    'taker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
                    'maker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
                },
            },
        });
    }
};

<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const ProcessExitCode = require('../../plugin/process-exit-code');
const { OutputKeepAlivePlugin } = require('../../plugin/output-keep-alive');
const skyPagesConfigUtil = require('../sky-pages/sky-pages.config');
const aliasBuilder = require('./alias-builder');

function spaPath() {
  return skyPagesConfigUtil.spaPath.apply(skyPagesConfigUtil, arguments);
}

function outPath() {
  return skyPagesConfigUtil.outPath.apply(skyPagesConfigUtil, arguments);
}

/**
 * Called when loaded via require.
 * @name getWebpackConfig
 * @param {SkyPagesConfig} skyPagesConfig
 * @returns {WebpackConfig} webpackConfig
 */
function getWebpackConfig(skyPagesConfig, argv = {}) {
  const resolves = [
    process.cwd(),
    spaPath('node_modules'),
    outPath('node_modules')
  ];

  let alias = aliasBuilder.buildAliasList(skyPagesConfig);

  const outConfigMode = skyPagesConfig && skyPagesConfig.skyux && skyPagesConfig.skyux.mode;
  let appPath;

  switch (outConfigMode) {
    case 'advanced':
      appPath = spaPath('src', 'main.ts');
      break;

    default:
      appPath = outPath('src', 'main-internal.ts');
      break;
  }

  return {
    entry: {
      polyfills: [outPath('src', 'polyfills.ts')],
      vendor: [outPath('src', 'vendor.ts')],
      skyux: [outPath('src', 'skyux.ts')],
      app: [appPath]
    },
    output: {
      filename: '[name].js',
      chunkFilename: '[id].chunk.js',
      path: spaPath('dist'),
    },
    resolveLoader: {
      modules: resolves
    },
    resolve: {
      alias: alias,
      modules: resolves,
      extensions: [
        '.js',
        '.ts'
      ]
    },
    module: {
      rules: [
        {
          enforce: 'pre',
          test: /config\.ts$/,
          loader: outPath('loader', 'sky-app-config'),
          include: outPath('runtime')
        },
        {
          enforce: 'pre',
          test: [
            /\.(html|s?css)$/,
            /sky-pages\.module\.ts/
          ],
          loader: outPath('loader', 'sky-assets')
        },
        {
          enforce: 'pre',
          test: /sky-pages\.module\.ts$/,
          loader: outPath('loader', 'sky-pages-module'),
          include: outPath('src', 'app'),
        },
        {
          enforce: 'pre',
          loader: outPath('loader', 'sky-processor', 'preload'),
          include: spaPath('src'),
          exclude: /node_modules/
        },
        {
          test: /\.s?css$/,
          use: [
            'raw-loader',
            'sass-loader'
          ]
        },
        {
          test: /\.html$/,
          loader: 'raw-loader'
        }
      ]
    },
    plugins: [
      // Some properties are required on the root object passed to HtmlWebpackPlugin
      new HtmlWebpackPlugin({
        template: skyPagesConfig.runtime.app.template,
        inject: skyPagesConfig.runtime.app.inject,
        runtime: skyPagesConfig.runtime,
        skyux: skyPagesConfig.skyux
      }),

      new CommonsChunkPlugin({
        name: ['skyux', 'vendor', 'polyfills']
      }),

      new webpack.DefinePlugin({
        'skyPagesConfig': JSON.stringify(skyPagesConfig)
      }),

      new ProgressBarPlugin(),

      new LoaderOptionsPlugin({
        options: {
          context: __dirname,
          skyPagesConfig: skyPagesConfig
        }
      }),

      new ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)@angular/,
        spaPath('src'),
        {}
      ),

      // Webpack 2 behavior does not correctly return non-zero exit code.
      new ProcessExitCode(),

      new OutputKeepAlivePlugin({
        enabled: argv['output-keep-alive']
      })
    ]
  };
}

module.exports = {
  getWebpackConfig: getWebpackConfig
};
<commit_msg>Reverting changes to master<commit_after>/*jslint node: true */
'use strict';

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const ProcessExitCode = require('../../plugin/process-exit-code');
const { OutputKeepAlivePlugin } = require('../../plugin/output-keep-alive');
const skyPagesConfigUtil = require('../sky-pages/sky-pages.config');
const aliasBuilder = require('./alias-builder');

function spaPath() {
  return skyPagesConfigUtil.spaPath.apply(skyPagesConfigUtil, arguments);
}

function outPath() {
  return skyPagesConfigUtil.outPath.apply(skyPagesConfigUtil, arguments);
}

/**
 * Called when loaded via require.
 * @name getWebpackConfig
 * @param {SkyPagesConfig} skyPagesConfig
 * @returns {WebpackConfig} webpackConfig
 */
function getWebpackConfig(skyPagesConfig, argv = {}) {
  const resolves = [
    process.cwd(),
    spaPath('node_modules'),
    outPath('node_modules')
  ];

  let alias = aliasBuilder.buildAliasList(skyPagesConfig);

  const outConfigMode = skyPagesConfig && skyPagesConfig.skyux && skyPagesConfig.skyux.mode;
  let appPath;

  switch (outConfigMode) {
    case 'advanced':
      appPath = spaPath('src', 'main.ts');
      break;

    default:
      appPath = outPath('src', 'main-internal.ts');
      break;
  }

  return {
    entry: {
      polyfills: [outPath('src', 'polyfills.ts')],
      vendor: [outPath('src', 'vendor.ts')],
      skyux: [outPath('src', 'skyux.ts')],
      app: [appPath]
    },
    output: {
      filename: '[name].js',
      chunkFilename: '[id].chunk.js',
      path: spaPath('dist'),
    },
    resolveLoader: {
      modules: resolves
    },
    resolve: {
      alias: alias,
      modules: resolves,
      extensions: [
        '.js',
        '.ts'
      ]
    },
    module: {
      rules: [
        {
          enforce: 'pre',
          test: /runtime\/config\.ts$/,
          loader: outPath('loader', 'sky-app-config')
        },
        {
          enforce: 'pre',
          test: [
            /\.(html|s?css)$/,
            /sky-pages\.module\.ts/
          ],
          loader: outPath('loader', 'sky-assets')
        },
        {
          enforce: 'pre',
          test: /sky-pages\.module\.ts$/,
          loader: outPath('loader', 'sky-pages-module')
        },
        {
          enforce: 'pre',
          loader: outPath('loader', 'sky-processor', 'preload'),
          exclude: /node_modules/
        },
        {
          test: /\.s?css$/,
          use: [
            'raw-loader',
            'sass-loader'
          ]
        },
        {
          test: /\.html$/,
          loader: 'raw-loader'
        }
      ]
    },
    plugins: [
      // Some properties are required on the root object passed to HtmlWebpackPlugin
      new HtmlWebpackPlugin({
        template: skyPagesConfig.runtime.app.template,
        inject: skyPagesConfig.runtime.app.inject,
        runtime: skyPagesConfig.runtime,
        skyux: skyPagesConfig.skyux
      }),

      new CommonsChunkPlugin({
        name: ['skyux', 'vendor', 'polyfills']
      }),

      new webpack.DefinePlugin({
        'skyPagesConfig': JSON.stringify(skyPagesConfig)
      }),

      new ProgressBarPlugin(),

      new LoaderOptionsPlugin({
        options: {
          context: __dirname,
          skyPagesConfig: skyPagesConfig
        }
      }),

      new ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)@angular/,
        spaPath('src'),
        {}
      ),

      // Webpack 2 behavior does not correctly return non-zero exit code.
      new ProcessExitCode(),

      new OutputKeepAlivePlugin({
        enabled: argv['output-keep-alive']
      })
    ]
  };
}

module.exports = {
  getWebpackConfig: getWebpackConfig
};
<|endoftext|>


<commit_before>function Curve(args) {
    if (arguments.length) {
        this.getready(args);
    }
}

extend(Curve, Element);

Curve.prototype.getready = function (args) {

    // Call the constructor from the superclass.
    Curve.superclass.getready.call(this, args);

    this.values = {	"points" : []};
    this.defaultSlot = "points";

    this.setWidth(args.width);
    this.setHeight(args.height);
    this.curveType = args.curveType || "bezier";
    this.handleSize = args.handleSize || 10;
    this.thickness = args.thickness || 2;
    this.curveColor = args.curveColor || "black";
    this.helperColor = args.helperColor || '#CCCCCC';
    this.handleColor = args.handleColor || "red";
    this.curveLabels = (typeof args.curveLabels === 'boolean') ? args.curveLabels : false;

    //internals
    this.handleClicked = null;
    this.supportPoints = [];

    // check for correct number of arguments
    // TODO this will evolve with various types of curves

    if(args.points.length % 2 != 0 || args.points.length < 4) {
        throw "Incorrect number of points " + arguments.length;
    }

    //simple console dump
    if(console){
        console.info(args.points);
    }

    //transform initial arguments into an {Array} of [x,y] coordinates
    var initialPoints = [];
    for(var i=0; i < args.points.length; i=i+2){
        initialPoints.push([args.points[i], args.points[i+1]]);
    }

    this.values.points = initialPoints;

};

// This methods returns true if the point given belongs to this element.
Curve.prototype.isInROI = function (x, y) {
    if ((x > this.ROILeft) && (y > this.ROITop)) {
        if ((x < (this.ROILeft + this.ROIWidth)) && (y < (this.ROITop + this.ROIHeight))) {
            return true;
        }
    }
    return false;
};

Curve.prototype.dragstart = Curve.prototype.mousedown = function (x, y) {

    var points = this.values.points;

    if (this.isInROI(x, y)) {
	    for (var i = 0; i < points.length; i+=1) {
	    	if ((x > (points[i][0] - this.handleSize)) && (x < (points[i][0] + this.handleSize))) {
	    		if ((y > (points[i][1] - this.handleSize)) && (y < (points[i][1] + this.handleSize))) {
	    			// We clicked on an handle!
	    			console.log ("Clicked on handle " + i);
	    			this.handleClicked = i;
	    		}
	    	}
	    }
    }
    return undefined;
};

Curve.prototype.drag = Curve.prototype.mousemove = function (curr_x, curr_y) {

    var to_set = 0,
        ret = {};

    if (this.handleClicked !== null) {
        // Button is activated when cursor is still in the element ROI, otherwise action is void.
        if (this.isInROI(curr_x, curr_y)) {
            // Click on button is completed, the button is no more triggered.
            this.triggered = false;
            // Copy the array before modifying it
            // TODO this is a shallow copy
            var points = this.values.points.slice();
            points[this.handleClicked][0] = curr_x;
            points[this.handleClicked][1] = curr_y;
            ret = {"slot" : "knobvalue", "value" : points};
            return ret;
        }
        else {
        	// Out of ROI, end this here
        	// Copy the array before modifying it
        	// TODO this is a shallow copy
            var points = this.values.points.slice();
            // Calculate where to stop
            points[this.handleClicked][0] = (curr_x < this.ROILeft + this.ROIWidth) ? curr_x : (this.ROILeft + this.ROIWidth);
            points[this.handleClicked][0] = (curr_x > this.ROILeft) ? curr_x : this.ROILeft;
            points[this.handleClicked][1] = (curr_y < this.ROITop + this.ROIHeight) ? curr_y : (this.ROITop + this.ROIHeight);
            points[this.handleClicked][1] = (curr_y < this.ROITop) ? curr_y : this.ROITop;
            // Stop the drag action
        	this.handleClicked = null;

        }
    }

    // Action is void, button was upclicked outside its ROI or never downclicked
    // No need to trigger anything, ignore this event.
    return undefined;

};

Curve.prototype.dragend = Curve.prototype.mouseup = function (x, y) {
	this.handleClicked = null;
}

Curve.prototype.setValue = function (slot, value) {

	console.log ("Setting " + slot + " to " + value);

};

Curve.prototype.refresh = function () {
    if (this.drawClass !== undefined) {

        // Call the superclass.
        Curve.superclass.refresh.call(this, this.drawClass.drawDummy);

        var context = this.drawClass.drawDummy.canvasC;

        if (this.isVisible === true) {
        	var initialPoints = this.values.points;
        	var parameters = {
        		thickness: this.thickness,
     			curveColor: this.curveColor,
     			helperColor: this.helperColor,
     			handleColor: this.handleColor,
     			handleSize: this.handleSize,
     			curveLabels: this.curveLabels
        	}
			this.bezier (context, initialPoints, parameters);
        }
    }
};

Curve.prototype.getPoint = function (index) {
	return this.supportPoints[index];
};

Curve.prototype.getnumPoints = function () {
	return this.supportPoints.length;
};

//Non-interface functions
//N grade bezier curve, adapted from http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api/
Curve.prototype.bezier = function (context, initialPoints, parameters) {

    // if set to true it will also paint debug information along with curve
    var debug = true;

    function distance(a, b){
        return Math.sqrt(Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1], 2));
    }

    /**Computes the drawing/support points for the Bezier curve*/
    function computeSupportPoints(points){

        /**Computes factorial*/
        function fact(k){
            if(k==0 || k==1){
                return 1;
            }
            else{
                return k * fact(k-1);
            }
        }

        /**Computes Bernstain
        *@param {Integer} i - the i-th index
        *@param {Integer} n - the total number of points
        *@param {Number} t - the value of parameter t , between 0 and 1
        **/
        function B(i,n,t){
            //if(n < i) throw "Wrong";
            return fact(n) / (fact(i) * fact(n-i))* Math.pow(t, i) * Math.pow(1-t, n-i);
        }

        /**Computes a point's coordinates for a value of t
        *@param {Number} t - a value between o and 1
        *@param {Array} points - an {Array} of [x,y] coodinates. The initial points
        **/
        function P(t, points){
            var r = [0,0];
            var n = points.length-1;
            for(var i=0; i <= n; i++){
                r[0] += points[i][0] * B(i, n, t);
                r[1] += points[i][1] * B(i, n, t);
            }
            return r;
        }

        /**Compute the incremental step*/
        var tLength = 0;
        for(var i=0; i< points.length-1; i++){
            tLength += distance(points[i], points[i+1]);
        }
        var step = 1 / tLength;

        //compute the support points
        var temp = [];
        for(var t=0;t<=1; t=t+step){
            var p = P(t, points);
            temp.push(p);
        }
        return temp;
    }

    // Stroked rectangle dot
    function paintPoint(ctx, color, size, point){

        ctx.save();
        ctx.strokeStyle = color;
        ctx.lineWidth = Math.round(size / 5);
        ctx.strokeRect(point[0] - Math.round(size / 2) , point[1] - Math.round (size / 2), size, size);
        ctx.restore();
    }

    /**Paint the support points*/
    function paintPoints(ctx, points, parameters){
        ctx.save();

        //paint lines
        ctx.strokeStyle = parameters.helperColor;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();

        //control points
        for(var i=0;i<points.length; i++){
            paintPoint(ctx, parameters.handleColor, parameters.handleSize, points[i]);
            if (parameters.curveLabels) {
            	ctx.fillText("P" + i + " [" + points[i][0] + ',' + points[i][1] + ']', points[i][0], points[i][1] - 10);
            }
        }

        ctx.restore();
    }

    /**Generic paint curve method*/
    function paintCurve(ctx, points, thickness, color){
        ctx.save();
		ctx.lineWidth = thickness;
		context.strokeStyle = color;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();
        ctx.restore();
    }

	// They are memorized, but they are stepped.
    this.supportPoints = computeSupportPoints(initialPoints);
    paintCurve(context, this.supportPoints, parameters.thickness, parameters.curveColor);
    if(debug){
        paintPoints(context, initialPoints, parameters /*.helperColor, parameters.handleColor, parameters.handleSize, parameters.curveLabels*/);
    }
}

Curve.prototype.setGraphicWrapper = function (wrapper) {

    // Call the superclass.
    Curve.superclass.setGraphicWrapper.call(this, wrapper);

    // Get the wrapper primitive functions TODO dummy here
    this.drawClass = wrapper.initObject ([{objName: "drawDummy"}]);

};<commit_msg>Added half-cosine interpolation<commit_after>function Curve(args) {
    if (arguments.length) {
        this.getready(args);
    }
}

extend(Curve, Element);

Curve.prototype.getready = function (args) {

    // Call the constructor from the superclass.
    Curve.superclass.getready.call(this, args);

    this.values = {	"points" : []};
    this.defaultSlot = "points";

    this.setWidth(args.width);
    this.setHeight(args.height);
    this.curveType = args.curveType || "bezier";
    this.handleSize = args.handleSize || 10;
    this.thickness = args.thickness || 2;
    this.curveColor = args.curveColor || "black";
    this.helperColor = args.helperColor || '#CCCCCC';
    this.handleColor = args.handleColor || "red";
    this.curveLabels = (typeof args.curveLabels === 'boolean') ? args.curveLabels : false;

    //internals
    this.handleClicked = null;
    this.supportPoints = [];

    // check for correct number of arguments
    // TODO this will evolve with various types of curves

    switch (args.curveType)  {
    	case "bezier":
		    if(args.points.length % 2 != 0 || args.points.length < 4) {
		        throw "Incorrect number of points " + args.points.length;
		       }
		    break;
	    case "halfcosine":
	    	if(args.points.length !== 4) {
		        throw "Incorrect number of points " + args.points.length;
		       }
		    break;
		default:
			throw "Unknown curve type " + args.curveType;
    }

    //transform initial arguments into an {Array} of [x,y] coordinates
    var initialPoints = [];
    for(var i=0; i < args.points.length; i=i+2){
        initialPoints.push([args.points[i], args.points[i+1]]);
    }

    this.values.points = initialPoints;

};

// This methods returns true if the point given belongs to this element.
Curve.prototype.isInROI = function (x, y) {
    if ((x > this.ROILeft) && (y > this.ROITop)) {
        if ((x < (this.ROILeft + this.ROIWidth)) && (y < (this.ROITop + this.ROIHeight))) {
            return true;
        }
    }
    return false;
};

Curve.prototype.dragstart = Curve.prototype.mousedown = function (x, y) {

    var points = this.values.points;

    if (this.isInROI(x, y)) {
	    for (var i = 0; i < points.length; i+=1) {
	    	if ((x > (points[i][0] - this.handleSize)) && (x < (points[i][0] + this.handleSize))) {
	    		if ((y > (points[i][1] - this.handleSize)) && (y < (points[i][1] + this.handleSize))) {
	    			// We clicked on an handle!
	    			console.log ("Clicked on handle " + i);
	    			this.handleClicked = i;
	    		}
	    	}
	    }
    }
    return undefined;
};

Curve.prototype.drag = Curve.prototype.mousemove = function (curr_x, curr_y) {

    var to_set = 0,
        ret = {};

    if (this.handleClicked !== null) {
        // Button is activated when cursor is still in the element ROI, otherwise action is void.
        if (this.isInROI(curr_x, curr_y)) {
            // Click on button is completed, the button is no more triggered.
            this.triggered = false;
            // Copy the array before modifying it
            // TODO this is a shallow copy
            var points = this.values.points.slice();
            points[this.handleClicked][0] = curr_x;
            points[this.handleClicked][1] = curr_y;
            ret = {"slot" : "knobvalue", "value" : points};
            return ret;
        }
        else {
        	// Out of ROI, end this here
        	// Copy the array before modifying it
        	// TODO this is a shallow copy
            var points = this.values.points.slice();
            // Calculate where to stop
            points[this.handleClicked][0] = (curr_x < this.ROILeft + this.ROIWidth) ? curr_x : (this.ROILeft + this.ROIWidth);
            points[this.handleClicked][0] = (curr_x > this.ROILeft) ? curr_x : this.ROILeft;
            points[this.handleClicked][1] = (curr_y < this.ROITop + this.ROIHeight) ? curr_y : (this.ROITop + this.ROIHeight);
            points[this.handleClicked][1] = (curr_y < this.ROITop) ? curr_y : this.ROITop;
            // Stop the drag action
        	this.handleClicked = null;

        }
    }

    // Action is void, button was upclicked outside its ROI or never downclicked
    // No need to trigger anything, ignore this event.
    return undefined;

};

Curve.prototype.dragend = Curve.prototype.mouseup = function (x, y) {
	this.handleClicked = null;
}

Curve.prototype.setValue = function (slot, value) {

	console.log ("Setting " + slot + " to " + value);

};

Curve.prototype.refresh = function () {
    if (this.drawClass !== undefined) {

        // Call the superclass.
        Curve.superclass.refresh.call(this, this.drawClass.drawDummy);

        var context = this.drawClass.drawDummy.canvasC;

        if (this.isVisible === true) {
        	var initialPoints = this.values.points;
        	var parameters = {
        		thickness: this.thickness,
     			curveColor: this.curveColor,
     			helperColor: this.helperColor,
     			handleColor: this.handleColor,
     			handleSize: this.handleSize,
     			curveLabels: this.curveLabels
        	}

        	switch (this.curveType) {
        	case "bezier":
				this.bezier (context, initialPoints, parameters);
				break;
			case "halfcosine":
				this.halfCosine (context, initialPoints, parameters);
				break;
			}
        }
    }
};

Curve.prototype.getPoint = function (index) {
	return this.supportPoints[index];
};

Curve.prototype.getnumPoints = function () {
	return this.supportPoints.length;
};

//Non-interface functions

Curve.prototype.halfCosine = function (context, initialPoints, parameters) {
	// TODO duplicate
	function distance(a, b){
        return Math.sqrt(Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1], 2));
    }

	/*
     *Computes a point's coordinates for a value of t
     *@param {Number} t - a value between 0 and 1
     *@param {Array} points - an {Array} of [x,y] coodinates. The initial points
    */

    function hCosine (t, points) {
    	// http://paulbourke.net/miscellaneous/interpolation/
    	var mu2 = (1 - Math.cos (t * Math.PI)) / 2;

    	var r = [0,0];
        r[0] = points[0][0] + (points[1][0] - points[0][0]) * t;
        r[1] = (points[0][1] * (1 - mu2) + points[1][1] * mu2);
        return r;
    }

    //Computes the drawing/support points for the Bezier curve
    // TODO all duplicates
    function computeSupportPoints(points){
    	/**Compute the incremental step*/
	    var tLength = 0;
	    for(var i=0; i< points.length-1; i++){
	        tLength += distance(points[i], points[i+1]);
	    }
	    var step = 1 / tLength;

	    //compute the support points
	    var temp = [];
	    for(var t=0; t<=1; t = t+step ){
	        var p = hCosine(t, points);
	        temp.push(p);
	    }
	    return temp;
	}

    /**Generic paint curve method*/
    function paintCurve(ctx, points, thickness, color){
        ctx.save();
		ctx.lineWidth = thickness;
		context.strokeStyle = color;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();
        ctx.restore();
    }

    // Stroked rectangle dot
    function paintPoint(ctx, color, size, point){

        ctx.save();
        ctx.strokeStyle = color;
        ctx.lineWidth = Math.round(size / 5);
        ctx.strokeRect(point[0] - Math.round(size / 2) , point[1] - Math.round (size / 2), size, size);
        ctx.restore();
    }

    /**Paint the support points*/
    function paintPoints(ctx, points, parameters){
        ctx.save();

        //paint lines
        ctx.strokeStyle = parameters.helperColor;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();

        //control points
        for(var i=0;i<points.length; i++){
            paintPoint(ctx, parameters.handleColor, parameters.handleSize, points[i]);
            if (parameters.curveLabels) {
            	ctx.fillText("P" + i + " [" + points[i][0] + ',' + points[i][1] + ']', points[i][0], points[i][1] - 10);
            }
        }

        ctx.restore();
    }

	// They are memorized, but they are stepped.
    this.supportPoints = computeSupportPoints(initialPoints);
    paintCurve(context, this.supportPoints, parameters.thickness, parameters.curveColor);
    paintPoints(context, initialPoints, parameters);

}

Curve.prototype.smoothStep = function (context, initialPoints, parameters) {
    function smooth (y0, y1, t) {
    	// http://codeplea.com/simple-interpolation
    	var tSmooth = t * t * (3 - 2 * t);
    	var res = y0 + tSmooth * (y1 - y0);
    }
}

Curve.prototype.linear = function (context, initialPoints, parameters) {
    function smooth (y0, y1, t) {
    	// http://codeplea.com/simple-interpolation
    	var res = y0 + t * (y1 - y0);
    }
}

//N grade bezier curve, adapted from http://html5tutorial.com/how-to-draw-n-grade-bezier-curve-with-canvas-api/
Curve.prototype.bezier = function (context, initialPoints, parameters) {

    // if set to true it will also paint debug information along with curve
    var debug = true;

    function distance(a, b){
        return Math.sqrt(Math.pow(a[0]-b[0], 2) + Math.pow(a[1]-b[1], 2));
    }

    /**Computes the drawing/support points for the Bezier curve*/
    function computeSupportPoints(points){

        /**Computes factorial*/
        function fact(k){
            if(k==0 || k==1){
                return 1;
            }
            else{
                return k * fact(k-1);
            }
        }

        /**Computes Bernstain
        *@param {Integer} i - the i-th index
        *@param {Integer} n - the total number of points
        *@param {Number} t - the value of parameter t , between 0 and 1
        **/
        function B(i,n,t){
            //if(n < i) throw "Wrong";
            return fact(n) / (fact(i) * fact(n-i))* Math.pow(t, i) * Math.pow(1-t, n-i);
        }

        /**Computes a point's coordinates for a value of t
        *@param {Number} t - a value between o and 1
        *@param {Array} points - an {Array} of [x,y] coodinates. The initial points
        **/
        function P(t, points){
            var r = [0,0];
            var n = points.length-1;
            for(var i=0; i <= n; i++){
                r[0] += points[i][0] * B(i, n, t);
                r[1] += points[i][1] * B(i, n, t);
            }
            return r;
        }

        /**Compute the incremental step*/
        var tLength = 0;
        for(var i=0; i< points.length-1; i++){
            tLength += distance(points[i], points[i+1]);
        }
        var step = 1 / tLength;

        //compute the support points
        var temp = [];
        for(var t=0;t<=1; t=t+step){
            var p = P(t, points);
            temp.push(p);
        }
        return temp;
    }

    // Stroked rectangle dot
    function paintPoint(ctx, color, size, point){

        ctx.save();
        ctx.strokeStyle = color;
        ctx.lineWidth = Math.round(size / 5);
        ctx.strokeRect(point[0] - Math.round(size / 2) , point[1] - Math.round (size / 2), size, size);
        ctx.restore();
    }

    /**Paint the support points*/
    function paintPoints(ctx, points, parameters){
        ctx.save();

        //paint lines
        ctx.strokeStyle = parameters.helperColor;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();

        //control points
        for(var i=0;i<points.length; i++){
            paintPoint(ctx, parameters.handleColor, parameters.handleSize, points[i]);
            if (parameters.curveLabels) {
            	ctx.fillText("P" + i + " [" + points[i][0] + ',' + points[i][1] + ']', points[i][0], points[i][1] - 10);
            }
        }

        ctx.restore();
    }

    /**Generic paint curve method*/
    function paintCurve(ctx, points, thickness, color){
        ctx.save();
		ctx.lineWidth = thickness;
		context.strokeStyle = color;
        ctx.beginPath();
        ctx.moveTo(points[0][0], points[0][1]);
        for(var i=1;i<points.length; i++){
            ctx.lineTo(points[i][0], points[i][1]);
        }
        ctx.stroke();
        ctx.restore();
    }

	// They are memorized, but they are stepped.
    this.supportPoints = computeSupportPoints(initialPoints);
    paintCurve(context, this.supportPoints, parameters.thickness, parameters.curveColor);
    if(debug){
        paintPoints(context, initialPoints, parameters);
    }
}

Curve.prototype.setGraphicWrapper = function (wrapper) {

    // Call the superclass.
    Curve.superclass.setGraphicWrapper.call(this, wrapper);

    // Get the wrapper primitive functions TODO dummy here
    this.drawClass = wrapper.initObject ([{objName: "drawDummy"}]);

};<|endoftext|>


<commit_before>/* ===========================================================
 * bootstrap-tooltip.js v2.3.2
 * http://twitter.github.com/bootstrap/javascript.html#tooltips
 * Inspired by the original jQuery.tipsy by Jason Frame
 * ===========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* TOOLTIP PUBLIC CLASS DEFINITION
  * =============================== */

  var Tooltip = function (element, options) {
    this.init('tooltip', element, options)
  }

  Tooltip.prototype = {

    constructor: Tooltip

  , init: function (type, element, options) {
      var eventIn
        , eventOut
        , triggers
        , trigger
        , i

      this.type = type
      this.$element = $(element)
      this.options = this.getOptions(options)
      this.enabled = true

      triggers = this.options.trigger.split(' ')

      for (i = triggers.length; i--;) {
        trigger = triggers[i]
        if (trigger == 'click') {
          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
        } else if (trigger != 'manual') {
          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
        }
      }

      this.options.selector ?
        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
        this.fixTitle()
    }

  , getOptions: function (options) {
      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)

      if (options.delay && typeof options.delay == 'number') {
        options.delay = {
          show: options.delay
        , hide: options.delay
        }
      }

      return options
    }

  , enter: function (e) {
      var defaults = $.fn[this.type].defaults
        , options = {}
        , self

      this._options && $.each(this._options, function (key, value) {
        if (defaults[key] != value) options[key] = value
      }, this)

      self = $(e.currentTarget)[this.type](options).data(this.type)

      if (!self.options.delay || !self.options.delay.show) return self.show()

      clearTimeout(this.timeout)
      self.hoverState = 'in'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'in') self.show()
      }, self.options.delay.show)
    }

  , leave: function (e) {
      var self = $(e.currentTarget)[this.type](this._options).data(this.type)

      if (this.timeout) clearTimeout(this.timeout)
      if (!self.options.delay || !self.options.delay.hide) return self.hide()

      self.hoverState = 'out'
      this.timeout = setTimeout(function() {
        if (self.hoverState == 'out') self.hide()
      }, self.options.delay.hide)
    }

  , show: function () {
      var $tip
        , pos
        , actualWidth
        , actualHeight
        , placement
        , tp
        , e = $.Event('show')

      if (this.hasContent() && this.enabled) {
        this.$element.trigger(e)
        if (e.isDefaultPrevented()) return
        $tip = this.tip()
        this.setContent()

        if (this.options.animation) {
          $tip.addClass('fade')
        }

        placement = typeof this.options.placement == 'function' ?
          this.options.placement.call(this, $tip[0], this.$element[0]) :
          this.options.placement

        $tip
          .detach()
          .css({ top: 0, left: 0, display: 'block' })

        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)

        pos = this.getPosition()

        actualWidth = $tip[0].offsetWidth
        actualHeight = $tip[0].offsetHeight

        switch (placement) {
          case 'bottom':
            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'top':
            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
            break
          case 'left':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
            break
          case 'right':
            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
            break
        }

        this.applyPlacement(tp, placement)
        this.$element.trigger('shown')
      }
    }

  , applyPlacement: function(offset, placement){
      var $tip = this.tip()
        , width = $tip[0].offsetWidth
        , height = $tip[0].offsetHeight
        , actualWidth
        , actualHeight
        , delta
        , replace

      $tip
        .offset(offset)
        .addClass(placement)
        .addClass('in')

      actualWidth = $tip[0].offsetWidth
      actualHeight = $tip[0].offsetHeight

      if (placement == 'top' && actualHeight != height) {
        offset.top = offset.top + height - actualHeight
        replace = true
      }

      if (placement == 'bottom' || placement == 'top') {
        delta = 0

        if (offset.left < 0){
          delta = offset.left * -2
          offset.left = 0
          $tip.offset(offset)
          actualWidth = $tip[0].offsetWidth
          actualHeight = $tip[0].offsetHeight
        }

        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
      } else {
        this.replaceArrow(actualHeight - height, actualHeight, 'top')
      }

      if (replace) $tip.offset(offset)
    }

  , replaceArrow: function(delta, dimension, position){
      this
        .arrow()
        .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
    }

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()

      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
      $tip.removeClass('fade in top bottom left right')
    }

  , hide: function () {
      var that = this
        , $tip = this.tip()
        , e = $.Event('hide')

      this.$element.trigger(e)
      if (e.isDefaultPrevented()) return

      $tip.removeClass('in')

      function removeWithAnimation() {
        var timeout = setTimeout(function () {
          $tip.off($.support.transition.end).detach()
        }, 500)

        $tip.one($.support.transition.end, function () {
          clearTimeout(timeout)
          $tip.detach()
        })
      }

      $.support.transition && this.$tip.hasClass('fade') ?
        removeWithAnimation() :
        $tip.detach()

      this.$element.trigger('hidden')

      return this
    }

  , fixTitle: function () {
      var $e = this.$element
      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
      }
    }

  , hasContent: function () {
      return this.getTitle()
    }

  , getPosition: function () {
      var el = this.$element[0]
      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
        width: el.offsetWidth
      , height: el.offsetHeight
      }, this.$element.offset())
    }

  , getTitle: function () {
      var title
        , $e = this.$element
        , o = this.options

      title = $e.attr('data-original-title')
        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)

      return title
    }

  , tip: function () {
      return this.$tip = this.$tip || $(this.options.template)
    }

  , arrow: function(){
      return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
    }

  , validate: function () {
      if (!this.$element[0].parentNode) {
        this.hide()
        this.$element = null
        this.options = null
      }
    }

  , enable: function () {
      this.enabled = true
    }

  , disable: function () {
      this.enabled = false
    }

  , toggleEnabled: function () {
      this.enabled = !this.enabled
    }

  , toggle: function (e) {
      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
      self.tip().hasClass('in') ? self.hide() : self.show()
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  }

 /* TOOLTIP PLUGIN DEFINITION
  * ========================= */

  var old = $.fn.tooltip

  $.fn.tooltip = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tooltip')
        , options = typeof option == 'object' && option
      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tooltip.Constructor = Tooltip

  $.fn.tooltip.defaults = {
    animation: true
  , placement: 'top'
  , selector: false
  , template: '

'
  , trigger: 'hover focus'
  , title: ''
  , delay: 0
  , html: false
  , container: false
  }

 /* TOOLTIP NO CONFLICT
  * =================== */

  $.fn.tooltip.noConflict = function () {
    $.fn.tooltip = old
    return this
  }

}(window.jQuery);

/* ===========================================================
 * bootstrap-popover.js v2.3.2
 * http://twitter.github.com/bootstrap/javascript.html#popovers
 * ===========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * =========================================================== */

!function ($) {

  "use strict"; // jshint ;_;

 /* POPOVER PUBLIC CLASS DEFINITION
  * =============================== */

  var Popover = function (element, options) {
    this.init('popover', element, options)
  }

  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
     ========================================== */

  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {

    constructor: Popover

  , setContent: function () {
      var $tip = this.tip()
        , title = this.getTitle()
        , content = this.getContent()

      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
      $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)

      $tip.removeClass('fade top bottom left right in')
    }

  , hasContent: function () {
      return this.getTitle() || this.getContent()
    }

  , getContent: function () {
      var content
        , $e = this.$element
        , o = this.options

      content = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)
        || $e.attr('data-content')

      return content
    }

  , tip: function () {
      if (!this.$tip) {
        this.$tip = $(this.options.template)
      }
      return this.$tip
    }

  , destroy: function () {
      this.hide().$element.off('.' + this.type).removeData(this.type)
    }

  })

 /* POPOVER PLUGIN DEFINITION
  * ======================= */

  var old = $.fn.popover

  $.fn.popover = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('popover')
        , options = typeof option == 'object' && option
      if (!data) $this.data('popover', (data = new Popover(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.popover.Constructor = Popover

  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
    placement: 'right'
  , trigger: 'click'
  , content: ''
  , template: '

'
  })

 /* POPOVER NO CONFLICT
  * =================== */

  $.fn.popover.noConflict = function () {
    $.fn.popover = old
    return this
  }

}(window.jQuery);
<commit_msg>remove useless file<commit_after><|endoftext|>


<commit_before>//AREAS
var carmona=new google.maps.LatLng(14.2992809,121.0284822);
var bancal=new google.maps.LatLng(14.283559,121.007561);
var slex=new google.maps.LatLng(14.322350,121.062300);

var zoomSize = 13;

var bancalAQIStatus = "";
var bancalAirQuality = "";
var bancalAQI = bancal_prevalent_value;
var bancalprevalentPollutant = pollutant_labels[bancal_prevalentIndex];

if(bancalAllDayValues_array.length == 0)
{
  bancalAirQuality = otherAir;
  bancalAQIStatus = "Not Enough Data";
}

else {
  if(bancal_prevalent_value >= 0 && bancal_prevalent_value <= 50){
    bancalAirQuality = goodAir;
    bancalAQIStatus = "Good";
  }else if(bancal_prevalent_value >= 51 && bancal_prevalent_value <= 100)
  {
    bancalAirQuality = fairAir;
    bancalAQIStatus = "Fair";
  }else if(bancal_prevalent_value >= 101 && bancal_prevalent_value <= 150)
  {
    bancalAirQuality = unhealthyAir;
    bancalAQIStatus = "Unhealthy for Sensitive Groups";
  }else if(bancal_prevalent_value >= 151 && bancal_prevalent_value <= 200)
  {
    bancalAirQuality = veryUnhealthyAir;
    bancalAQIStatus = "Very Unhealthy";
  }else if(bancal_prevalent_value >= 201 && bancal_prevalent_value <= 300)
  {
    bancalAirQuality = acutelyUnhealthyAir;
    bancalAQIStatus = "Acutely Unhealthy";
  }else if(bancal_prevalent_value >= 301 && bancal_prevalent_value <= 400)
  {
    bancalAirQuality = emergencyAir;
    bancalAQIStatus = "Emergency";
  }else {
    bancalAirQuality = otherAir;
    bancalAQIStatus = "Not Enough Data";
  }
}

var slexAQIStatus = goodAir;
var slexAirQuality = "Good";
var slexAQI = 21;
var slexprevalentPollutant = "CO";

//var bancalAQIStatus = prevalentValues_bancal_array[0].p_aqi_status;
//var bancalAirQuality = prevalentValues_bancal_array[0].p_airqualiy;
//var bancalAQI = parseInt(prevalentValues_bancal_array[0].concentration_value);
//var bancalprevalentPollutant = prevalentValues_bancal_array[0].e_name;

//var slexAQIStatus = prevalentValues_slex_array[0].p_aqi_status;
//var slexAirQuality = prevalentValues_slex_array[0].p_airqualiy;
//var slexAQI = parseInt(prevalentValues_slex_array[0].concentration_value);
//var slexprevalentPollutant = prevalentValues_slex_array[0].e_name;

var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
};

function initialize()
{
    var mapProp = {
        disableDefaultUI:true,
        center:carmona,
        zoom:zoomSize,
        mapTypeId:google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("googleMap"),mapProp);

    var bancalMarker = new MarkerWithLabel({
        position: bancal,
        map: map,
        labelContent: bancalAQI,
        labelAnchor: new google.maps.Point(20, 65),
        labelClass: "labels", // the CSS class for the label
        labelInBackground: false,
    });

    var slexMarker = new MarkerWithLabel({
        position: slex,
        map: map,
        labelContent: slexAQI,
        labelAnchor: new google.maps.Point(20, 65),
        labelClass: "labels", // the CSS class for the label
        labelInBackground: false,
    });

    var zoneBancal = new google.maps.Circle({
        center:bancal,
        radius:500,
        strokeColor: bancalAirQuality,
        strokeOpacity:0.8,
        strokeWeight:2,
        fillColor: bancalAirQuality,
        fillOpacity:0.5
    });

    var zoneSLEX = new google.maps.Circle({
        center:slex,
        radius:500,
        strokeColor:slexAirQuality,
        strokeOpacity:0.8,
        strokeWeight:2,
        fillColor:slexAirQuality,
        fillOpacity:0.5
    });
    var d = new Date();
    var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

    google.maps.event.addListener(bancalMarker,'click',function() {
        window.location.href = "index.php?area=Bancal";
        //GetBancalStatus();
    });

    google.maps.event.addListener(slexMarker,'click',function() {
        window.location.href = "index.php?area=SLEX";
        //GetSLEXStatus();
    });

    google.maps.event.addListener(map, 'dragend', function() { $("#zoneStatus").hide(); } );

    zoneBancal.setMap(map);
    zoneSLEX.setMap(map);
    bancalMarker.setMap(map);
    slexMarker.setMap(map);

    var bancalZoom=new google.maps.LatLng(14.283969,121.015671);
    function GetBancalStatus() {
        map.setZoom(16);
        map.setCenter(bancalZoom);

        $("#zoneStatus").show();
        document.getElementById("AQIStat").style.backgroundColor = bancalAirQuality;
        document.getElementById("zoneName").innerHTML = 'Bancal Carmona, Cavite';
        document.getElementById("prevalentPollutant").innerHTML = bancalprevalentPollutant;
        document.getElementById("aqiNum").innerHTML = bancalAQI;
        document.getElementById("aqiText").innerHTML = bancalAQIStatus;
        document.getElementById("timeUpdated").innerHTML = date_gathered;

        //document.getElementById("e_symbol_1").innerHTML =  "HII";
        //document.getElementById("concentration_value_1").innerHTML =  "5";

        for(var i = 0; i < bancal_aqi_values.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);
            var elementMin = "aqi_min_" + (i+1);
            var elementMax = "aqi_max_" + (i+1);

            document.getElementById(elementName).innerHTML =  pollutant_symbols[i];
            document.getElementById(conentrationName).innerHTML =  bancal_aqi_values[i];

            document.getElementById(elementMin).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][0]).replace(/"/g, ''));
            document.getElementById(elementMax).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][1]).replace(/"/g, ''));
        }
        /*
         document.getElementById("e_symbol_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("e_symbol_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("e_symbol_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("e_symbol_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("e_symbol_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("e_symbol_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("e_symbol_7").innerHTML =  bancalValues_array[6].e_symbol;

         document.getElementById("concentration_value_1").innerHTML =  slexValues_array[0].e_symbol;
         document.getElementById("concentration_value_2").innerHTML =  slexValues_array[1].e_symbol;
         document.getElementById("concentration_value_3").innerHTML =  slexValues_array[2].e_symbol;
         document.getElementById("concentration_value_4").innerHTML =  slexValues_array[3].e_symbol;
         document.getElementById("concentration_value_5").innerHTML =  slexValues_array[4].e_symbol;
         document.getElementById("concentration_value_6").innerHTML =  slexValues_array[5].e_symbol;
         document.getElementById("concentration_value_7").innerHTML =  slexValues_array[6].e_symbol;
         */
    }
    var slexZoom=new google.maps.LatLng(14.32274,121.071688);
    //noinspection JSAnnotator
    function GetSLEXStatus() {
        map.setZoom(16);
        map.setCenter(slexZoom);

        $("#zoneStatus").show();
        document.getElementById("AQIStat").style.backgroundColor = slexAirQuality;
        document.getElementById("zoneName").innerHTML = 'SLEX Carmona Exit, Cavite';
        document.getElementById("prevalentPollutant").innerHTML = slexprevalentPollutant;
        document.getElementById("aqiNum").innerHTML = slexAQI;
        document.getElementById("aqiText").innerHTML = slexAQIStatus;
        document.getElementById("timeUpdated").innerHTML =  date_gathered;

        //document.getElementById("e_symbol_1").innerHTML =  "HI";
        //document.getElementById("concentration_value_1").innerHTML =  "7";

        //alert(bancal_aqi_values[0]);

        for(var i = 0; i < bancal_aqi_values.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);

            var elementMin = "aqi_min_" + (i+1);
            var elementMax = "aqi_max_" + (i+1);

            document.getElementById(elementName).innerHTML =  pollutant_symbols[i];
            document.getElementById(conentrationName).innerHTML =  bancal_aqi_values[i];

            document.getElementById(elementMin).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][0]).replace(/"/g, ''));
            document.getElementById(elementMax).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][1]).replace(/"/g, ''));
        }

        /*
        for(var i = 0; i < slexValues_array.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);

            document.getElementById(elementName).innerHTML =  slexValues_array[i].e_symbol;
            document.getElementById(conentrationName).innerHTML =  slexValues_array[i].concentration_value;
        }
        */

        /*
         document.getElementById("e_symbol_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("e_symbol_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("e_symbol_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("e_symbol_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("e_symbol_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("e_symbol_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("e_symbol_7").innerHTML =  bancalValues_array[6].e_symbol;

         document.getElementById("concentration_value_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("concentration_value_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("concentration_value_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("concentration_value_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("concentration_value_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("concentration_value_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("concentration_value_7").innerHTML =  bancalValues_array[6].e_symbol;
         */
    }

    var area = getUrlParameter('area');

    if(area!=null){
        if(area=="SLEX"){
            GetSLEXStatus();
        }
        else if(area="Bancal"){
            GetBancalStatus();
        }
    }

}

google.maps.event.addDomListener(window, 'load', initialize);
<commit_msg>Fix color indicator for aqiText<commit_after>//AREAS
var carmona=new google.maps.LatLng(14.2992809,121.0284822);
var bancal=new google.maps.LatLng(14.283559,121.007561);
var slex=new google.maps.LatLng(14.322350,121.062300);

var zoomSize = 13;

var bancalAQIStatus = "";
var bancalAirQuality = "";
var bancalAQI = bancal_prevalent_value;
var bancalprevalentPollutant = pollutant_labels[bancal_prevalentIndex];

if(bancalAllDayValues_array.length == 0)
{
  bancalAirQuality = otherAir;
  bancalAQIStatus = "Not Enough Data";
}

else {
  if(bancal_prevalent_value >= 0 && bancal_prevalent_value <= 50){
    bancalAirQuality = goodAir;
    bancalAQIStatus = "Good";
  }else if(bancal_prevalent_value >= 51 && bancal_prevalent_value <= 100)
  {
    bancalAirQuality = fairAir;
    bancalAQIStatus = "Fair";
  }else if(bancal_prevalent_value >= 101 && bancal_prevalent_value <= 150)
  {
    bancalAirQuality = unhealthyAir;
    bancalAQIStatus = "Unhealthy for Sensitive Groups";
  }else if(bancal_prevalent_value >= 151 && bancal_prevalent_value <= 200)
  {
    bancalAirQuality = veryUnhealthyAir;
    bancalAQIStatus = "Very Unhealthy";
  }else if(bancal_prevalent_value >= 201 && bancal_prevalent_value <= 300)
  {
    bancalAirQuality = acutelyUnhealthyAir;
    bancalAQIStatus = "Acutely Unhealthy";
  }else if(bancal_prevalent_value >= 301 && bancal_prevalent_value <= 400)
  {
    bancalAirQuality = emergencyAir;
    bancalAQIStatus = "Emergency";
  }else {
    bancalAirQuality = otherAir;
    bancalAQIStatus = "Not Enough Data";
  }
}

var slexAQIStatus = goodAir;
var slexAirQuality = "Good";
var slexAQI = 21;
var slexprevalentPollutant = "CO";

//var bancalAQIStatus = prevalentValues_bancal_array[0].p_aqi_status;
//var bancalAirQuality = prevalentValues_bancal_array[0].p_airqualiy;
//var bancalAQI = parseInt(prevalentValues_bancal_array[0].concentration_value);
//var bancalprevalentPollutant = prevalentValues_bancal_array[0].e_name;

//var slexAQIStatus = prevalentValues_slex_array[0].p_aqi_status;
//var slexAirQuality = prevalentValues_slex_array[0].p_airqualiy;
//var slexAQI = parseInt(prevalentValues_slex_array[0].concentration_value);
//var slexprevalentPollutant = prevalentValues_slex_array[0].e_name;

var getUrlParameter = function getUrlParameter(sParam) {
    var sPageURL = decodeURIComponent(window.location.search.substring(1)),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');

        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : sParameterName[1];
        }
    }
};

function initialize()
{
    var mapProp = {
        disableDefaultUI:true,
        center:carmona,
        zoom:zoomSize,
        mapTypeId:google.maps.MapTypeId.ROADMAP
    };

    var map = new google.maps.Map(document.getElementById("googleMap"),mapProp);

    var bancalMarker = new MarkerWithLabel({
        position: bancal,
        map: map,
        labelContent: bancalAQI,
        labelAnchor: new google.maps.Point(20, 65),
        labelClass: "labels", // the CSS class for the label
        labelInBackground: false,
    });

    var slexMarker = new MarkerWithLabel({
        position: slex,
        map: map,
        labelContent: slexAQI,
        labelAnchor: new google.maps.Point(20, 65),
        labelClass: "labels", // the CSS class for the label
        labelInBackground: false,
    });

    var zoneBancal = new google.maps.Circle({
        center:bancal,
        radius:500,
        strokeColor: bancalAirQuality,
        strokeOpacity:0.8,
        strokeWeight:2,
        fillColor: bancalAirQuality,
        fillOpacity:0.5
    });

    var zoneSLEX = new google.maps.Circle({
        center:slex,
        radius:500,
        strokeColor:slexAirQuality,
        strokeOpacity:0.8,
        strokeWeight:2,
        fillColor:slexAirQuality,
        fillOpacity:0.5
    });
    var d = new Date();
    var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];

    google.maps.event.addListener(bancalMarker,'click',function() {
        window.location.href = "index.php?area=Bancal";
        //GetBancalStatus();
    });

    google.maps.event.addListener(slexMarker,'click',function() {
        window.location.href = "index.php?area=SLEX";
        //GetSLEXStatus();
    });

    google.maps.event.addListener(map, 'dragend', function() { $("#zoneStatus").hide(); } );

    zoneBancal.setMap(map);
    zoneSLEX.setMap(map);
    bancalMarker.setMap(map);
    slexMarker.setMap(map);

    var bancalZoom=new google.maps.LatLng(14.283969,121.015671);
    function GetBancalStatus() {
        map.setZoom(16);
        map.setCenter(bancalZoom);

        $("#zoneStatus").show();
        document.getElementById("aqiText").style.color = bancalAirQuality;
        document.getElementById("AQIStat").style.backgroundColor = bancalAirQuality;
        document.getElementById("zoneName").innerHTML = 'Bancal Carmona, Cavite';
        document.getElementById("prevalentPollutant").innerHTML = bancalprevalentPollutant;
        document.getElementById("aqiNum").innerHTML = bancalAQI;
        document.getElementById("aqiText").innerHTML = bancalAQIStatus;
        document.getElementById("timeUpdated").innerHTML = date_gathered;

        //document.getElementById("e_symbol_1").innerHTML =  "HII";
        //document.getElementById("concentration_value_1").innerHTML =  "5";

        for(var i = 0; i < bancal_aqi_values.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);
            var elementMin = "aqi_min_" + (i+1);
            var elementMax = "aqi_max_" + (i+1);

            document.getElementById(elementName).innerHTML =  pollutant_symbols[i];
            document.getElementById(conentrationName).innerHTML =  bancal_aqi_values[i];

            document.getElementById(elementMin).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][0]).replace(/"/g, ''));
            document.getElementById(elementMax).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][1]).replace(/"/g, ''));
        }
        /*
         document.getElementById("e_symbol_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("e_symbol_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("e_symbol_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("e_symbol_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("e_symbol_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("e_symbol_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("e_symbol_7").innerHTML =  bancalValues_array[6].e_symbol;

         document.getElementById("concentration_value_1").innerHTML =  slexValues_array[0].e_symbol;
         document.getElementById("concentration_value_2").innerHTML =  slexValues_array[1].e_symbol;
         document.getElementById("concentration_value_3").innerHTML =  slexValues_array[2].e_symbol;
         document.getElementById("concentration_value_4").innerHTML =  slexValues_array[3].e_symbol;
         document.getElementById("concentration_value_5").innerHTML =  slexValues_array[4].e_symbol;
         document.getElementById("concentration_value_6").innerHTML =  slexValues_array[5].e_symbol;
         document.getElementById("concentration_value_7").innerHTML =  slexValues_array[6].e_symbol;
         */
    }
    var slexZoom=new google.maps.LatLng(14.32274,121.071688);
    //noinspection JSAnnotator
    function GetSLEXStatus() {
        map.setZoom(16);
        map.setCenter(slexZoom);

        $("#zoneStatus").show();
        document.getElementById("aqiText").style.color = slexAirQuality;
        document.getElementById("AQIStat").style.backgroundColor = slexAirQuality;
        document.getElementById("zoneName").innerHTML = 'SLEX Carmona Exit, Cavite';
        document.getElementById("prevalentPollutant").innerHTML = slexprevalentPollutant;
        document.getElementById("aqiNum").innerHTML = slexAQI;
        document.getElementById("aqiText").innerHTML = slexAQIStatus;
        document.getElementById("timeUpdated").innerHTML =  date_gathered;

        //document.getElementById("e_symbol_1").innerHTML =  "HI";
        //document.getElementById("concentration_value_1").innerHTML =  "7";

        //alert(bancal_aqi_values[0]);

        for(var i = 0; i < bancal_aqi_values.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);

            var elementMin = "aqi_min_" + (i+1);
            var elementMax = "aqi_max_" + (i+1);

            document.getElementById(elementName).innerHTML =  pollutant_symbols[i];
            document.getElementById(conentrationName).innerHTML =  bancal_aqi_values[i];

            document.getElementById(elementMin).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][0]).replace(/"/g, ''));
            document.getElementById(elementMax).innerHTML =  parseInt(JSON.stringify(bancal_min_max_values[i][1]).replace(/"/g, ''));
        }

        /*
        for(var i = 0; i < slexValues_array.length; i++)
        {
            var elementName = "e_symbol_" + (i+1);
            var conentrationName = "concentration_value_" + (i+1);

            document.getElementById(elementName).innerHTML =  slexValues_array[i].e_symbol;
            document.getElementById(conentrationName).innerHTML =  slexValues_array[i].concentration_value;
        }
        */

        /*
         document.getElementById("e_symbol_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("e_symbol_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("e_symbol_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("e_symbol_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("e_symbol_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("e_symbol_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("e_symbol_7").innerHTML =  bancalValues_array[6].e_symbol;

         document.getElementById("concentration_value_1").innerHTML =  bancalValues_array[0].e_symbol;
         document.getElementById("concentration_value_2").innerHTML =  bancalValues_array[1].e_symbol;
         document.getElementById("concentration_value_3").innerHTML =  bancalValues_array[2].e_symbol;
         document.getElementById("concentration_value_4").innerHTML =  bancalValues_array[3].e_symbol;
         document.getElementById("concentration_value_5").innerHTML =  bancalValues_array[4].e_symbol;
         document.getElementById("concentration_value_6").innerHTML =  bancalValues_array[5].e_symbol;
         document.getElementById("concentration_value_7").innerHTML =  bancalValues_array[6].e_symbol;
         */
    }

    var area = getUrlParameter('area');

    if(area!=null){
        if(area=="SLEX"){
            GetSLEXStatus();
        }
        else if(area="Bancal"){
            GetBancalStatus();
        }
    }

}

google.maps.event.addDomListener(window, 'load', initialize);
<|endoftext|>