<commit_before>/*!
 * Funnel Chart v1.1.0
 * https://github.com/promotably/funnel-chart
 *
 * Copyright 2015 Promotably LLC
 * Released under the MIT license
 */
(function (root, factory) {
  if(typeof define === 'function' && define.amd) {
    define(factory);
  }
  else if(typeof module === 'object' && module.exports) {
    module.exports = factory();
  }
  else {
    root.FunnelChart = factory();
  }
}(this, function() {

  function extend(out) {
    out = out || {};

    for (var i = 1; i < arguments.length; i++) {
      if (!arguments[i])
        continue;

      for (var key in arguments[i]) {
        if (arguments[i].hasOwnProperty(key))
          out[key] = arguments[i][key];
      }
    }

    return out;
  }

  // canvas arg can be an ID string or HTMLElement
  function FunnelChart(canvas, settings) {
    // Allows FunnelChart to be instantiated without use of "new"
    if (!(this instanceof FunnelChart))
      return new FunnelChart(canvas, settings);

    // Ensure canvas is an HTMLElement
    this.canvas = (typeof canvas === 'string') ?
      document.getElementById(canvas) : canvas;

    // TODO: Check settings.values exists
    if(!settings.values || !settings.values.length)
      throw('A values setting must be provided');

    // Extend default settings
    this.settings = extend(this.settings, settings);

    // Init!
    this.initialize();
  }

  FunnelChart.prototype = extend(FunnelChart.prototype, {

    settings: {

      // Boolean - Whether to display % change between sections
      displayPercentageChange: true,

      // Number - The number of decimal places that should be displayed for %
      // change values
      pPrecision: 1,

      // String - The color of the horizontal label lines (if labels are shown)
      labelLineColor: '#eee',

      // String or Array - The font color(s) of the labels.
      labelFontColor: '#657274',

      // String or Array - The color(s) of the funnel sections.
      sectionColor: '#0498b3',

      // String or Array - The color(s) of the funnel percentage sections.
      pSectionColor: '#bfd1d4',

      // String - The font for labels and values
      font: 'Helvetica Neue',

      // Number - The maximum font size in pixels (px) for labels and values.
      // This will always be used where possible unless the height of the
      // funnel sections is too small to permit it, in which case the font size
      // will be automatically reduced to fit
      maxFontSize: 13,

      // String - The font weight for labels and values
      fontWeight: '300',

      // String or Array - The font color(s) for funnel sections
      sectionFontColor: '#fff',

      // String or Array - The font color(s) for % change sections
      pSectionFontColor: '#657274',

      // Number - The height of the % change sections compared to the main
      // funnel sections. This is a percent value.
      pSectionHeightPercent: 100,

      // Number - The percentage of the full canvas width that should be
      // reserved for display of labels (if provided). The funnel will expand
      // to fit the remainder.
      labelWidthPercent: 30,

      // Number - The percentage width difference between the top and the
      // bottom of the funnel.
      funnelReductionPercent: 40,

      // Number - The space between the right hand edge of the funnel and the
      // label text in pixels.
      labelOffset: 10,

      // Number - The line height between each funnel section
      lineHeight: 1
    },

    initialize: function() {
      this.calculateDimensions();
      this.draw();
    },

    calculateDimensions: function() {
      var settings = this.settings,
          labelWidth, sectionTotalHeight, multiplier;

      // Width and height of canvas
      this.width = this.canvas.offsetWidth;
      this.height = this.canvas.offsetHeight;

      // Width allocated to labels
      labelWidth = this.hasLabels() ? this.width * (settings.labelWidthPercent / 100) : 0;
      this.labelMaxWidth = labelWidth - settings.labelOffset;

      // Start and end width of funnel
      this.startWidth = this.width - labelWidth;
      this.endWidth = this.startWidth * (settings.funnelReductionPercent / 100);

      // Total height of each section
      sectionTotalHeight = (this.height / (settings.values.length));

      // Section heights
      if(settings.displayPercentageChange) {
        sectionTotalHeight = (this.height / (settings.values.length));
        multiplier = this.height / (this.height - (sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent);
        this.sectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * 100));
        this.pSectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent));
      }
      else {
        this.sectionHeight = sectionTotalHeight;
        this.pSectionHeight = 0;
      }
    },

    draw: function() {
      var canvas = this.canvas,
          settings = this.settings;

      if (canvas.getContext) {
        var ctx = canvas.getContext('2d'),
            maxAvailFontSize = ((settings.displayPercentageChange) ? this.pSectionHeight : this.sectionHeight) - 2;

        // Reduce font size if necessary
        if(settings.maxFontSize >= maxAvailFontSize)
          settings.maxFontSize = maxAvailFontSize;

        // Configure font styling
        ctx.font = settings.fontWeight + ' ' + settings.maxFontSize + 'px ' + settings.font;

        // Draw labels if we have any<commit_msg>Make things look great on Retina screens<commit_after>/*!
 * Funnel Chart v1.1.0
 * https://github.com/promotably/funnel-chart
 *
 * Copyright 2015 Promotably LLC
 * Released under the MIT license
 */
(function (root, factory) {
  if(typeof define === 'function' && define.amd) {
    define(factory);
  }
  else if(typeof module === 'object' && module.exports) {
    module.exports = factory();
  }
  else {
    root.FunnelChart = factory();
  }
}(this, function() {

  function extend(out) {
    out = out || {};

    for (var i = 1; i < arguments.length; i++) {
      if (!arguments[i])
        continue;

      for (var key in arguments[i]) {
        if (arguments[i].hasOwnProperty(key))
          out[key] = arguments[i][key];
      }
    }

    return out;
  }

  // canvas arg can be an ID string or HTMLElement
  function FunnelChart(canvas, settings) {
    // Allows FunnelChart to be instantiated without use of "new"
    if (!(this instanceof FunnelChart))
      return new FunnelChart(canvas, settings);

    // Ensure canvas is an HTMLElement
    this.canvas = (typeof canvas === 'string') ?
      document.getElementById(canvas) : canvas;

    // TODO: Check settings.values exists
    if(!settings.values || !settings.values.length)
      throw('A values setting must be provided');

    // Extend default settings
    this.settings = extend(this.settings, settings);

    // Init!
    this.initialize();
  }

  FunnelChart.prototype = extend(FunnelChart.prototype, {

    settings: {

      // Boolean - Whether to display % change between sections
      displayPercentageChange: true,

      // Number - The number of decimal places that should be displayed for %
      // change values
      pPrecision: 1,

      // String - The color of the horizontal label lines (if labels are shown)
      labelLineColor: '#eee',

      // String or Array - The font color(s) of the labels.
      labelFontColor: '#657274',

      // String or Array - The color(s) of the funnel sections.
      sectionColor: '#0498b3',

      // String or Array - The color(s) of the funnel percentage sections.
      pSectionColor: '#bfd1d4',

      // String - The font for labels and values
      font: 'Helvetica Neue',

      // Number - The maximum font size in pixels (px) for labels and values.
      // This will always be used where possible unless the height of the
      // funnel sections is too small to permit it, in which case the font size
      // will be automatically reduced to fit
      maxFontSize: 13,

      // String - The font weight for labels and values
      fontWeight: '300',

      // String or Array - The font color(s) for funnel sections
      sectionFontColor: '#fff',

      // String or Array - The font color(s) for % change sections
      pSectionFontColor: '#657274',

      // Number - The height of the % change sections compared to the main
      // funnel sections. This is a percent value.
      pSectionHeightPercent: 100,

      // Number - The percentage of the full canvas width that should be
      // reserved for display of labels (if provided). The funnel will expand
      // to fit the remainder.
      labelWidthPercent: 30,

      // Number - The percentage width difference between the top and the
      // bottom of the funnel.
      funnelReductionPercent: 40,

      // Number - The space between the right hand edge of the funnel and the
      // label text in pixels.
      labelOffset: 10,

      // Number - The line height between each funnel section
      lineHeight: 1
    },

    initialize: function() {
      this.calculateDimensions();
      this.draw();
    },

    calculateDimensions: function() {
      var settings = this.settings,
          labelWidth, sectionTotalHeight, multiplier;

      // Width and height of canvas
      this.width = this.canvas.offsetWidth;
      this.height = this.canvas.offsetHeight;

      // Ensure canvas dimensions are correct for device pixel ratio
      this.createHiDPICanvas();

      // Width allocated to labels
      labelWidth = this.hasLabels() ? this.width * (settings.labelWidthPercent / 100) : 0;
      this.labelMaxWidth = labelWidth - settings.labelOffset;

      // Start and end width of funnel
      this.startWidth = this.width - labelWidth;
      this.endWidth = this.startWidth * (settings.funnelReductionPercent / 100);

      // Total height of each section
      sectionTotalHeight = (this.height / (settings.values.length));

      // Section heights
      if(settings.displayPercentageChange) {
        sectionTotalHeight = (this.height / (settings.values.length));
        multiplier = this.height / (this.height - (sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent);
        this.sectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * 100));
        this.pSectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent));
      }
      else {
        this.sectionHeight = sectionTotalHeight;
        this.pSectionHeight = 0;
      }
    },

    pixelRatio: function(){
      var ctx = this.canvas.getContext('2d'),
          dpr = window.devicePixelRatio || 1,
          bsr = ctx.webkitBackingStorePixelRatio ||
                ctx.mozBackingStorePixelRatio ||
                ctx.msBackingStorePixelRatio ||
                ctx.oBackingStorePixelRatio ||
                ctx.backingStorePixelRatio || 1;
      return dpr / bsr;
    },

    createHiDPICanvas: function() {
        var canvas = this.canvas,
            ratio = this.pixelRatio(),
            w = this.width,
            h = this.height;

        canvas.width = w * ratio;
        canvas.height = h * ratio;
        canvas.style.width = w + 'px';
        canvas.style.height = h + 'px';
        canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);
    },

    draw: function() {
      var canvas = this.canvas,
          settings = this.settings;

      if (canvas.getContext) {
        var ctx = canvas.getContext('2d'),
            maxAvailFontSize = ((settings.displayPercentageChange) ? this.pSectionHeight : this.sectionHeight) - 2;

        // Reduce font size if necessary
        if(settings.maxFontSize >= maxAvailFontSize)
          settings.maxFontSize = maxAvailFontSize;

        // Configure font styling
        ctx.font = settings.fontWeight + ' ' + settings.maxFontSize + 'px ' + settings.font;

        // Draw labels if we have any
{'fraction_non_alphanumeric': 0.10326851468762929, 'fraction_numerical': 0.011419114604882085, 'mean_word_length': 2.435474701534963, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7515738', 'n_tokens_mistral': 3416, 'n_tokens_neox': 3215, 'n_words': 1062}