{"version":3,"sources":["jsdelivr-header.js","/npm/funnel-chart@1.1.1/src/funnel-chart.js"],"names":[],"mappings":"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","file":"/npm/funnel-chart@1.1.1/src/funnel-chart.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/funnel-chart@1.1.1/src/funnel-chart.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","/*!\n * Funnel Chart v1.1.1\n * https://github.com/promotably/funnel-chart\n *\n * Copyright 2015 Promotably LLC\n * Released under the MIT license\n */\n(function (root, factory) {\n  if(typeof define === 'function' && define.amd) {\n    define(factory);\n  }\n  else if(typeof module === 'object' && module.exports) {\n    module.exports = factory();\n  }\n  else {\n    root.FunnelChart = factory();\n  }\n}(this, function() {\n\n  function extend(out) {\n    out = out || {};\n\n    for (var i = 1; i < arguments.length; i++) {\n      if (!arguments[i])\n        continue;\n\n      for (var key in arguments[i]) {\n        if (arguments[i].hasOwnProperty(key))\n          out[key] = arguments[i][key];\n      }\n    }\n\n    return out;\n  }\n\n  // canvas arg can be an ID string or HTMLElement\n  function FunnelChart(canvas, settings) {\n    // Allows FunnelChart to be instantiated without use of \"new\"\n    if (!(this instanceof FunnelChart))\n      return new FunnelChart(canvas, settings);\n\n    // Ensure canvas is an HTMLElement\n    this.canvas = (typeof canvas === 'string') ?\n      document.getElementById(canvas) : canvas;\n\n    // TODO: Check settings.values exists\n    if(!settings.values || !settings.values.length)\n      throw('A values setting must be provided');\n\n    // Extend default settings\n    this.settings = extend(this.settings, settings);\n\n    // Init!\n    this.initialize();\n  }\n\n  FunnelChart.prototype = extend(FunnelChart.prototype, {\n\n    settings: {\n\n      // Boolean - Whether to display % change between sections\n      displayPercentageChange: true,\n\n      // Number - The number of decimal places that should be displayed for %\n      // change values\n      pPrecision: 1,\n\n      // String - The color of the horizontal label lines (if labels are shown)\n      labelLineColor: '#eee',\n\n      // String or Array - The font color(s) of the labels.\n      labelFontColor: '#657274',\n\n      // String or Array - The color(s) of the funnel sections.\n      sectionColor: '#0498b3',\n\n      // String or Array - The color(s) of the funnel percentage sections.\n      pSectionColor: '#bfd1d4',\n\n      // String - The font for labels and values\n      font: 'Helvetica Neue',\n\n      // Number - The maximum font size in pixels (px) for labels and values.\n      // This will always be used where possible unless the height of the\n      // funnel sections is too small to permit it, in which case the font size\n      // will be automatically reduced to fit\n      maxFontSize: 13,\n\n      // String - The font weight for labels and values\n      fontWeight: '300',\n\n      // String or Array - The font color(s) for funnel sections\n      sectionFontColor: '#fff',\n\n      // String or Array - The font color(s) for % change sections\n      pSectionFontColor: '#657274',\n\n      // Number - The height of the % change sections compared to the main\n      // funnel sections. This is a percent value.\n      pSectionHeightPercent: 100,\n\n      // Number - The percentage of the full canvas width that should be\n      // reserved for display of labels (if provided). The funnel will expand\n      // to fit the remainder.\n      labelWidthPercent: 30,\n\n      // Number - The percentage width difference between the top and the\n      // bottom of the funnel.\n      funnelReductionPercent: 40,\n\n      // Number - The space between the right hand edge of the funnel and the\n      // label text in pixels.\n      labelOffset: 10,\n\n      // Number - The line height between each funnel section\n      lineHeight: 1\n    },\n\n    initialize: function() {\n      this.calculateDimensions();\n      this.draw();\n    },\n\n    calculateDimensions: function() {\n      var settings = this.settings,\n          labelWidth, sectionTotalHeight, multiplier;\n\n      // Width and height of canvas\n      this.width = this.canvas.offsetWidth;\n      this.height = this.canvas.offsetHeight;\n\n      // Ensure canvas dimensions are correct for device pixel ratio\n      this.createHiDPICanvas();\n\n      // Width allocated to labels\n      labelWidth = this.hasLabels() ? this.width * (settings.labelWidthPercent / 100) : 0;\n      this.labelMaxWidth = labelWidth - settings.labelOffset;\n\n      // Start and end width of funnel\n      this.startWidth = this.width - labelWidth;\n      this.endWidth = this.startWidth * (settings.funnelReductionPercent / 100);\n\n      // Total height of each section\n      sectionTotalHeight = (this.height / (settings.values.length));\n\n      // Section heights\n      if(settings.displayPercentageChange) {\n        sectionTotalHeight = (this.height / (settings.values.length));\n        multiplier = this.height / (this.height - (sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent);\n        this.sectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * 100));\n        this.pSectionHeight = (multiplier * ((sectionTotalHeight / (100 + settings.pSectionHeightPercent)) * settings.pSectionHeightPercent));\n      }\n      else {\n        this.sectionHeight = sectionTotalHeight;\n        this.pSectionHeight = 0;\n      }\n    },\n\n    pixelRatio: function(){\n      var ctx = this.canvas.getContext('2d'),\n          dpr = window.devicePixelRatio || 1,\n          bsr = ctx.webkitBackingStorePixelRatio ||\n                ctx.mozBackingStorePixelRatio ||\n                ctx.msBackingStorePixelRatio ||\n                ctx.oBackingStorePixelRatio ||\n                ctx.backingStorePixelRatio || 1;\n      return dpr / bsr;\n    },\n\n    createHiDPICanvas: function() {\n        var canvas = this.canvas,\n            ratio = this.pixelRatio(),\n            w = this.width,\n            h = this.height;\n\n        canvas.width = w * ratio;\n        canvas.height = h * ratio;\n        canvas.style.width = w + 'px';\n        canvas.style.height = h + 'px';\n        canvas.getContext('2d').setTransform(ratio, 0, 0, ratio, 0, 0);\n    },\n\n    draw: function() {\n      var canvas = this.canvas,\n          settings = this.settings;\n\n      if (canvas.getContext) {\n        var ctx = canvas.getContext('2d'),\n            maxAvailFontSize = ((settings.displayPercentageChange) ? this.pSectionHeight : this.sectionHeight) - 2;\n\n        // Reduce font size if necessary\n        if(settings.maxFontSize >= maxAvailFontSize)\n          settings.maxFontSize = maxAvailFontSize;\n\n        // Configure font styling\n        ctx.font = settings.fontWeight + ' ' + settings.maxFontSize + 'px ' + settings.font;\n\n        // Draw labels if we have any\n        if(this.hasLabels()) this.drawLabels(ctx);\n\n        // Draw funnel clipping area with white background\n        this.drawClippingArea(ctx, settings);\n        ctx.fillStyle = '#fff';\n        ctx.fill();\n        ctx.clip();\n\n        // Draw funnel sections\n        this.drawSections(ctx);\n\n        // Tidy up funnel outline\n        this.drawClippingArea(ctx, settings, true);\n        ctx.lineWidth = 2;\n        ctx.strokeStyle = '#fff';\n        ctx.stroke();\n      }\n    },\n\n    drawLabels: function(ctx) {\n      var settings = this.settings,\n          i, yPos;\n\n      ctx.strokeStyle = settings.labelLineColor;\n      ctx.lineWidth = settings.lineHeight;\n\n      for(i = 0; i < settings.values.length; i++) {\n        yPos = this.calculateYPos(i) - 1;\n\n        ctx.fillStyle = this.sequentialValue(settings.labelFontColor, i);\n        ctx.fillText(\n          settings.labels[i] || '',\n          this.startWidth + settings.labelOffset,\n          yPos + (this.sectionHeight / 2) + (settings.maxFontSize / 2) - 2,\n          this.labelMaxWidth\n        );\n\n        if(i > 0) {\n          ctx.beginPath();\n          ctx.moveTo(i, yPos);\n          ctx.lineTo(this.width, yPos);\n          ctx.stroke();\n        }\n\n        if(i < (settings.values.length - 1) && settings.displayPercentageChange){\n          ctx.beginPath();\n          ctx.moveTo(i, yPos + this.sectionHeight);\n          ctx.lineTo(this.width, yPos + this.sectionHeight);\n          ctx.stroke();\n        }\n\n      }\n    },\n\n    drawClippingArea: function(ctx, settings, curvesOnly) {\n      var inset = (this.startWidth - this.endWidth) / 2;\n      var height = (settings.values.length * this.sectionHeight) +\n                     ((settings.values.length - 1) * this.pSectionHeight) +\n                     (settings.values.length + 1),\n          lineOrMove = curvesOnly ? 'moveTo' : 'lineTo';\n\n      ctx.beginPath();\n      ctx.moveTo(0,0);\n      ctx[lineOrMove](this.startWidth,0);\n      ctx.quadraticCurveTo(\n        (this.startWidth - inset),\n        (height / 3),\n        (this.startWidth - inset),\n        height\n      );\n      ctx[lineOrMove](inset,height);\n      ctx.quadraticCurveTo(inset, (height / 3), 0, 0);\n    },\n\n    drawSections: function(ctx) {\n      var settings = this.settings,\n          i, yPos;\n\n      ctx.textAlign = 'center';\n\n      for(i = 0; i < settings.values.length; i++) {\n        yPos = this.calculateYPos(i);\n\n        ctx.fillStyle = this.sequentialValue(settings.sectionColor, i);\n        ctx.fillRect(0, yPos, this.startWidth, this.sectionHeight - settings.lineHeight);\n        ctx.fillStyle = this.sequentialValue(settings.sectionFontColor, i);\n        ctx.fillText(\n          settings.values[i],\n          this.startWidth / 2,\n          yPos + ((this.sectionHeight - settings.lineHeight) / 2) + (settings.maxFontSize / 2) - 2\n        );\n\n        if(i < (settings.values.length - 1) && settings.displayPercentageChange) {\n          ctx.fillStyle = this.sequentialValue(settings.pSectionColor, i);\n          ctx.fillRect(\n            0,\n            (yPos + this.sectionHeight),\n            this.startWidth,\n            this.pSectionHeight - settings.lineHeight\n          );\n\n          ctx.fillStyle = this.sequentialValue(settings.pSectionFontColor, i);\n          ctx.fillText(\n            (settings.values[i] === 0) ? '' : ((settings.values[i + 1] / settings.values[i]) * 100).toFixed(settings.pPrecision) + '%',\n            this.startWidth / 2,\n            yPos + this.sectionHeight + ((this.pSectionHeight - settings.lineHeight) / 2) + (settings.maxFontSize / 2) - 1\n          );\n        }\n      }\n    },\n\n    hasLabels: function() {\n      var labels = this.settings.labels;\n      return labels && !!labels.length;\n    },\n\n    calculateYPos: function(i) {\n      var sectionHeight = this.sectionHeight;\n      if(this.settings.displayPercentageChange) sectionHeight += this.pSectionHeight;\n      return sectionHeight * i;\n    },\n\n    sequentialValue: function(arr, i) {\n      if(typeof arr === 'string') return arr;\n      return arr[i % arr.length];\n    }\n\n  });\n\n  return FunnelChart;\n\n}));\n"]}