text: /*
   * --------------------------------------------------------------------
   * jQuery inputToButton plugin
   * Author: Scott Jehl, scott@filamentgroup.com
   * Copyright (c) 2009 Filament Group 
   * licensed under MIT (filamentgroup.com/examples/mit-license.txt)
   * --------------------------------------------------------------------
  */
  (function ($) {
      $.fn.visualize = function (options, container) {
          return $(this).each(function () {
              //configuration
              var o = $.extend({
                  type: 'bar', //also available: area, pie, line
                  width: $(this).width(), //height of canvas - defaults to table height
                  height: '400px', //height of canvas - defaults to table height // $(this).height() - By Developer
                  appendTitle: true, //table caption text is added to chart
                  title: null, //grabs from table caption if null
                  appendKey: true, //color key is added to chart
                  rowFilter: ' ',
                  colFilter: ' ',
                  colors: ['#ee8310', '#8d10ee', '#5a3b16', '#26a4ed', '#f45a90', '#e9e744', '#be1e2d', '#666699', '#92d5ea'],
                  textColors: [], //corresponds with colors array. null/undefined items will fall back to CSS
                  parseDirection: 'x', //which direction to parse the table data
                  pieMargin: 20, //pie charts only - spacing around pie
                  pieLabelsAsPercent: true,
                  pieLabelPos: 'inside',
                  lineWeight: 4, //for line and area - stroke weight
                  barGroupMargin: 10,
                  barMargin: 1, //space around bars in bar chart (added to both sides of bar)
                  yLabelInterval: 15 //distance between y labels
              }, options);
  
              //reset width, height to numbers
              o.width = parseFloat(o.width);
              o.height = parseFloat(o.height);
  
  
              var self = $(this);
  
              //function to scrape data from html table
              function scrapeTable() {
                  var colors = o.colors;
                  var textColors = o.textColors;
                  var tableData = {
                      dataGroups: function () {
                          var dataGroups = [];
                          if (o.parseDirection == 'x') {
                              self.find('tr:gt(0)').filter(o.rowFilter).each(function (i) {
                                  dataGroups[i] = {};
                                  dataGroups[i].points = [];
                                  dataGroups[i].color = colors[i];
                                  if (textColors[i]) { dataGroups[i].textColor = textColors[i]; }
                                  $(this).find('td').filter(o.colFilter).each(function () {
                                      dataGroups[i].points.push(parseFloat($(this).text()));
                                  });
                              });
                          }
                          else {
                              var cols = self.find('tr:eq(1) td').filter(o.colFilter).size();
                              for (var i = 0; i < cols; i++) {
                                  dataGroups[i] = {};
                                  dataGroups[i].points = [];
                                  dataGroups[i].color = colors[i];
                                  if (textColors[i]) { dataGroups[i].textColor = textColors[i]; }
                                  self.find('tr:gt(0)').filter(o.rowFilter).each(function () {
                                      dataGroups[i].points.push($(this).find('td').filter(o.colFilter).eq(i).text() * 1);
                                  });
                              };
                          }
                          return dataGroups;
                      },
                      allData: function () {
                          var allData = [];
                          $(this.dataGroups()).each(function () {
                              allData.push(this.points);
                          });
                          return allData;
                      },
                      dataSum: function () {
                          var dataSum = 0;
                          var allData = this.allData().join(',').split(',');
                          $(allData).each(function () {
                              dataSum += parseFloat(this);
                          });
                          return dataSum
                      },
                      topValue: function () {
                          var topValue = 0;
                          var allData = this.allData().join(',').split(',');
                          $(allData).each(function () {
                              if (parseFloat(this, 10) > topValue) topValue = parseFloat(this);
                          });
                          return topValue;
                      },
                      bottomValue: function () {
                          var bottomValue = 0;
                          var allData = this.allData().join(',').split(',');
                          $(allData).each(function () {
                              if (this < bottomValue) bottomValue = parseFloat(this);
                          });
                          return bottomValue;
                      },
                      memberTotals: function () {
                          var memberTotals = [];
                          var dataGroups = this.dataGroups();
                          $(dataGroups).each(function (l) {
                              var count = 0;
                              $(dataGroups[l].points).each(function (m) {
                                  count += dataGroups[l].points[m];
                              });
                              memberTotals.push(count);
                          });
                          return memberTotals;
                      },
                      yTotals: function () {
                          var yTotals = [];
                          var dataGroups = this.dataGroups();
                          var loopLength = this.xLabels().length;
                          for (var i = 0; i < loopLength; i++) {
                              yTotals[i] = [];
                              var thisTotal = 0;
                              $(dataGroups).each(function (l) {
                                  yTotals[i].push(this.points[i]);
                              });
                              yTotals[i].join(',').split(',');
                              $(yTotals[i]).each(function () {
                                  thisTotal += parseFloat(this);
                              });
                              yTotals[i] = thisTotal;
  
                          }
                          return yTotals;
                      },
                      topYtotal: function () {
                          var topYtotal = 0;
                          var yTotals = this.yTotals().join(',').split(',');
                          $(yTotals).each(function () {
                              if (parseFloat(this, 10) > topYtotal) topYtotal = parseFloat(this);
                          });
                          return topYtotal;
                      },
                      totalYRange: function () {
                          return this.topValue() - this.bottomValue();
                      },
                      xLabels: function () {
                          var xLabels = [];
                          if (o.parseDirection == 'x') {
                              self.find('tr:eq(0) th').filter(o.colFilter).each(function () {
                                  xLabels.push($(this).html());
                              });
                          }
                          else {
                              self.find('tr:gt(0) th').filter(o.rowFilter).each(function () {
                                  xLabels.push($(this).html());
                              });
                          }
                          return xLabels;
                      },
                      yLabels: function () {
                          var yLabels = [];
                          yLabels.push(bottomValue);
                          var numLabels = Math.round(o.height / o.yLabelInterval);
                          var loopInterval = Math.ceil(totalYRange / numLabels) || 1;
                          while (yLabels[yLabels.length - 1] < topValue - loopInterval) {
                              yLabels.push(yLabels[yLabels.length - 1] + loopInterval);
                          }
                          yLabels.push(topValue);
                          return yLabels;
                      }
                  };
  
                  return tableData;
              };
  
  
              //function to create a chart
              var createChart = {
                  pie: function () {
  
                      canvasContain.addClass('visualize-pie');
  
                      if (o.pieLabelPos == 'outside') { canvasContain.addClass('visualize-pie-outside'); }
  
                      var centerx = Math.round(canvas.width() / 2);
                      var centery = Math.round(canvas.height() / 2);
                      var radius = centery - o.pieMargin;
                      var counter = 0.0;
                      var toRad = function (integer) { return (Math.PI / 180) * integer; };
                      var labels = $('<ul class="visualize-labels"></ul>')
  					.insertAfter(canvas);
  
                      //draw the pie pieces
                      $.each(memberTotals, function (i) {
                          var fraction = (this <= 0 || isNaN(this)) ? 0 : this / dataSum;
                          ctx.beginPath();
                          ctx.moveTo(centerx, centery);
                          ctx.arc(centerx, centery, radius,
  						counter * Math.PI * 2 - Math.PI * 0.5,
  						(counter + fraction) * Math.PI * 2 - Math.PI * 0.5,
  		                false);
                          ctx.lineTo(centerx, centery);
                          ctx.closePath();
                          ctx.fillStyle = dataGroups[i].color;
                          ctx.fill();
                          // draw labels
                          var sliceMiddle = (counter + fraction / 2);
                          var distance = o.pieLabelPos == 'inside' ? radius / 1.5 : radius + radius / 5;
                          var labelx = Math.round(centerx + Math.sin(sliceMiddle * Math.PI * 2) * (distance));
                          var labely = Math.round(centery - Math.cos(sliceMiddle * Math.PI * 2) * (distance));
                          var leftRight = (labelx > centerx) ? 'right' : 'left';
                          var topBottom = (labely > centery) ? 'bottom' : 'top';
                          var percentage = parseFloat((fraction * 100).toFixed(2));
  
                          if (percentage) {
                              var labelval = (o.pieLabelsAsPercent) ? percentage + '%' : this;
                              var labeltext = $('<span class="visualize-label">' + labelval + '</span>')
  				        	.css(leftRight, 0)
  				        	.css(topBottom, 0);
                              if (labeltext)
                                  var label = $('<li class="visualize-label-pos"></li>')
  				       			.appendTo(labels)
  				        		.css({ left: labelx, top: labely })
  				        		.append(labeltext);
                              labeltext
  				        	.css('font-size', radius / 8)
  				        	.css('margin-' + leftRight, -labeltext.width() / 2)
  				        	.css('margin-' + topBottom, -labeltext.outerHeight() / 2);
  
                              if (dataGroups[i].textColor) { labeltext.css('color', dataGroups[i].textColor); }
                          }
                          counter += fraction;
                      });
                  },
  
                  line: function (area) {
  
                      if (area) { canvasContain.addClass('visualize-area'); }
                      else { canvasContain.addClass('visualize-line'); }
  
                      //write X labels
                      var xInterval = canvas.width() / (xLabels.length - 1);
                      var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
  					.width(canvas.width())
  					.height(canvas.height())
  					.insertBefore(canvas);
                      $.each(xLabels, function (i) {
                          var thisLi = $('<li><span>' + this + '</span></li>')
  						.prepend('<span class="line" />')
  						.css('left', xInterval * i)
  						.appendTo(xlabelsUL);
                          var label = thisLi.find('span:not(.line)');
                          var leftOffset = label.width() / -2;
                          if (i == 0) { leftOffset = 0; }
                          else if (i == xLabels.length - 1) { leftOffset = -label.width(); }
                          label
  						.css('margin-left', leftOffset)
  						.addClass('label');
                      });
  
                      //write Y labels
                      var yScale = canvas.height() / totalYRange;
                      var liBottom = canvas.height() / (yLabels.length - 1);
                      var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
  					.width(canvas.width())
  					.height(canvas.height())
  					.insertBefore(canvas);
  
                      $.each(yLabels, function (i) {
                          var thisLi = $('<li><span>' + this + '</span></li>')
  						.prepend('<span class="line"  />')
  						.css('bottom', liBottom * i)
  						.prependTo(ylabelsUL);
                          var label = thisLi.find('span:not(.line)');
                          var topOffset = label.height() / -2;
                          if (i == 0) { topOffset = -label.height(); }
                          else if (i == yLabels.length - 1) { topOffset = 0; }
                          label
  						.css('margin-top', topOffset)
  						.addClass('label');
                      });
  
                      //start from the bottom left
                      ctx.translate(0, zeroLoc);
                      //iterate and draw
                      $.each(dataGroups, function (h) {
                          ctx.beginPath();
                          ctx.lineWidth = o.lineWeight;
                          ctx.lineJoin = 'round';
                          var points = this.points;
                          var integer = 0;
                          ctx.moveTo(0, -(points[0] * yScale));
                          $.each(points, function () {
                              ctx.lineTo(integer, -(this * yScale));
                              integer += xInterval;
                          });
                          ctx.strokeStyle = this.color;
                          ctx.stroke();
                          if (area) {
                              ctx.lineTo(integer, 0);
                              ctx.lineTo(0, 0);
                              ctx.closePath();
                              ctx.fillStyle = this.color;
                              ctx.globalAlpha = .3;
                              ctx.fill();
                              ctx.globalAlpha = 1.0;
                          }
                          else { ctx.closePath(); }
                      });
                  },
  
                  area: function () {
                      createChart.line(true);
                  },
  
                  bar: function () {
  
                      canvasContain.addClass('visualize-bar');
  
                      //write X labels
                      var xInterval = canvas.width() / (xLabels.length);
                      var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
  					.width(canvas.width())
  					.height(canvas.height())
  					.insertBefore(canvas);
                      $.each(xLabels, function (i) {
                          var thisLi = $('<li><span class="label">' + this + '</span></li>')
  						.prepend('<span class="line" />')
  						.css('left', xInterval * i)
  						.width(xInterval)
  						.appendTo(xlabelsUL);
                          var label = thisLi.find('span.label');
                          label.addClass('label');
                      });
  
                      //write Y labels
                      var yScale = canvas.height() / totalYRange;
                      var liBottom = canvas.height() / (yLabels.length - 1);
                      var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
  					.width(canvas.width())
  					.height(canvas.height())
  					.insertBefore(canvas);
                      $.each(yLabels, function (i) {
                          var thisLi = $('<li><span>' + this + '</span></li>')
  						.prepend('<span class="line"  />')
  						.css('bottom', liBottom * i)
  						.prependTo(ylabelsUL);
                          var label = thisLi.find('span:not(.line)');
                          var topOffset = label.height() / -2;
                          if (i == 0) { topOffset = -label.height(); }
                          else if (i == yLabels.length - 1) { topOffset = 0; }
                          label
  							.css('margin-top', topOffset)
                              .css('color', '#ee8310')
  							.addClass('label');
  
                          /* By Developer - Start */
                          if (label.html() == "0") {
                              label
                                  .html("Waiting to die")
                                  .css('margin-top', topOffset + 6);
                          }
                          else if (label.html() == "1")
                              label.html("Big Pharma Cash Cow to Longterm medical Dificiences");
                          else if (label.html() == "2")
                              label.html("Nutritionally exhausted Premature Aging");
                          else if (label.html() == "3")
                              label.html("Nutritionally depleted");
                          else if (label.html() == "4")
                              label.html("Less than Optimal");
                          else if (label.html() == "5") {
                              label
                                  .html("Optimal Health")
                                  .css('margin-top', topOffset - 6);
                          }
                          /* By Developer - End */
                      });
  
                      //start from the bottom left
                      ctx.translate(0, zeroLoc);
                      //iterate and draw
                      for (var h = 0; h < dataGroups.length; h++) {
                          ctx.beginPath();
                          var linewidth = (xInterval - o.barGroupMargin * 2) / dataGroups.length; //removed +1 
                          var strokeWidth = linewidth - (o.barMargin * 2);
                          ctx.lineWidth = strokeWidth;
                          var points = dataGroups[h].points;
                          var integer = 0;
                          for (var i = 0; i < points.length; i++) {
                              var xVal = (integer - o.barGroupMargin) + (h * linewidth) + linewidth / 2;
                              xVal += o.barGroupMargin * 2;
  
                              ctx.moveTo(xVal, 0);
                              ctx.lineTo(xVal, Math.round(-points[i] * yScale));
                              integer += xInterval;
                          }
                          ctx.strokeStyle = dataGroups[h].color;
                          ctx.stroke();
                          ctx.closePath();
                      }
                  }
              };
  
              //create new canvas, set w&h attrs (not inline styles)
              var canvasNode = document.createElement("canvas");
              canvasNode.setAttribute('height', o.height);
              canvasNode.setAttribute('width', o.width);
              var canvas = $(canvasNode);
  
              //get title for chart
              var title = o.title || self.find('caption').text();
  
              //create canvas wrapper div, set inline w&h, append
              var canvasContain = (container || $('<div class="visualize" role="img" aria-label="Chart representing data from the table: ' + title + '" />'))
  			.height(o.height)
  			.width(o.width)
  			.append(canvas);
  
              //scrape table (this should be cleaned up into an obj)
              var tableData = scrapeTable();
              var dataGroups = tableData.dataGroups();
              var allData = tableData.allData();
              var dataSum = tableData.dataSum();
              var topValue = tableData.topValue();
              var bottomValue = tableData.bottomValue();
              var memberTotals = tableData.memberTotals();
              var totalYRange = tableData.totalYRange();
              var zeroLoc = o.height * (topValue / totalYRange);
              var xLabels = tableData.xLabels();
              var yLabels = tableData.yLabels();
  
              //title/key container
              if (o.appendTitle || o.appendKey) {
                  var infoContain = $('<div class="visualize-info"></div>')
  				.appendTo(canvasContain);
              }
  
              //append title
              if (o.appendTitle) {
                  $('<div class="visualize-title">' + title + '</div>').appendTo(infoContain);
              }
  
  
              //append key
              if (o.appendKey) {
                  var newKey = $('<ul class="visualize-key"></ul>');
                  var selector;
                  if (o.parseDirection == 'x') {
                      selector = self.find('tr:gt(0) th').filter(o.rowFilter);
                  }
                  else {
                      selector = self.find('tr:eq(0) th').filter(o.colFilter);
                  }
  
                  selector.each(function (i) {
                      $('<li><span class="visualize-key-color" style="background: ' + dataGroups[i].color + '"></span><span class="visualize-key-label">' + $(this).text() + '</span></li>')
  					.appendTo(newKey);
                  });
                  newKey.appendTo(infoContain);
              };
  
              //append new canvas to page
  
              if (!container) { canvasContain.insertAfter(this); }
              if (typeof (G_vmlCanvasManager) != 'undefined') { G_vmlCanvasManager.init(); G_vmlCanvasManager.initElement(canvas[0]); }
  
              //set up the drawing board	
              var ctx = canvas[0].getContext('2d');
  
              //create chart
              createChart[o.type]();
  
              //clean up some doubled lines that sit on top of canvas borders (done via JS due to IE)
              $('.visualize-line li:first-child span.line, .visualize-line li:last-child span.line, .visualize-area li:first-child span.line, .visualize-area li:last-child span.line, .visualize-bar li:first-child span.line,.visualize-bar .visualize-labels-y li:last-child span.line').css('border', 'none');
              if (!container) {
                  //add event for updating
                  canvasContain.bind('visualizeRefresh', function () {
                      self.visualize(o, $(this).empty());
                  });
              }
          }).next(); //returns canvas(es)
      };
  })(jQuery);
  
  
  