{"version":3,"file":"index-CxPLqNWp.js","sources":["../../../app/javascript/components/viz/graph-investment-fees/fee-graph.js","../../../app/javascript/components/viz/graph-investment-fees/index.vue"],"sourcesContent":["import * as d3 from '~/app/custom-d3'\nimport numeral from 'numeral'\n\nexport default class FeeGraph {\n constructor(el) {\n this.el = el\n this.margin = {\n top: 20,\n left: 50,\n right: 10,\n bottom: 30\n }\n\n this.options = this.generateBounds()\n this.bisectYears = d3.bisector(function(d) { return d.year; }).left\n\n this.setup()\n }\n\n generateBounds() {\n var bounds = this.el.getBoundingClientRect(),\n width = 1200,\n height = width * (9/16)\n\n if((height > bounds.width) || (width > bounds.width)) {\n width = bounds.width\n height = width * (9/16)\n }\n\n return {\n height: height,\n width: width\n }\n }\n\n resize() {\n this.options = this.generateBounds()\n\n this.svg.attr('width', this.options.width)\n .attr('height', this.options.height)\n .attr('viewbox', `0 0 ${this.options.width} ${this.options.height}`);\n\n this.mainGroup.attr(\"transform\", \"translate(\" + this.margin.left + \",\" + this.margin.top + \")\");\n\n this.xHoverLine.attr(\"y2\", this.options.height);\n\n this.movingRect.attr(\"width\", this.options.width-this.margin.left-this.margin.right)\n .attr(\"height\", this.options.height-this.margin.top-this.margin.bottom)\n\n this.xAxisEl.attr(\"transform\", \"translate(\"+this.margin.left+\",\" + (this.options.height-this.margin.top-10) + \")\");\n this.xAxisEl.attr(\"x\", this.options.width - this.margin.left - this.margin.right)\n\n // Y-axis\n this.yAxisEl.attr(\"transform\", \"translate(\"+this.margin.left+\",\"+this.margin.top+\")\");\n this.yAxisEl.attr(\"x\", this.margin.top - 40);\n }\n\n setup() {\n this.svg = d3.select(this.el).append('svg')\n .attr('class', 'mx-auto')\n\n this.mainGroup = this.svg.append(\"g\")\n .attr(\"transform\", \"translate(\" + this.margin.left + \",\" + this.margin.top + \")\");\n\n // Line - Fund A\n this.line = d3.line()\n .x((quote) => {\n return this.xScale(quote.year);\n })\n .y((quote) => {\n return this.yScale(quote.amount);\n });\n this.path = this.mainGroup.append(\"path\")\n .attr(\"class\", \"line stroke-width-base stroke-blue-500\");\n\n // Line - Fund B\n this.basePath = this.mainGroup.append(\"path\")\n .attr(\"class\", \"line stroke-width-base stroke-red-500\");\n\n\n\n // Focus contains:\n // - A circle on the main graph line corresponding with x/y\n // - The x/y dotted lines\n // - A rect with a tooltip\n var focus = this.mainGroup.append(\"g\")\n .style(\"display\", \"none\");\n var focusCircle = focus.append(\"circle\")\n .attr('class', 'stroke-width-base fill-blue-100 stroke-blue-500')\n .attr(\"r\", 7.5);\n var bottomFocusCircle = focus.append(\"circle\")\n .attr('class', 'stroke-width-base fill-red-100 stroke-red-500')\n .attr(\"r\", 7.5);\n this.xHoverLine = focus.append(\"line\")\n .attr(\"class\", \"line stroke-purple-500 stroke-width-sm stroke-dasharray-dashed-sm\")\n .attr(\"y1\", 0)\n .attr(\"y2\", this.options.height);\n\n\n // Midpoint\n this.tip = d3.tip().attr('class', 'd3-tip d3-tip--default').html(function(message) {\n return `

${message}

`;\n }).offset([0, -14]).direction('w');\n this.svg.call(this.tip)\n var middleFocusCircle = focus.append(\"circle\")\n .attr('class', 'stroke-width-base fill-red-100 stroke-red-500')\n .attr(\"r\", 0);\n\n // Rect for moving\n this.movingRect = this.mainGroup.append(\"rect\")\n .attr(\"class\", \"overlay\")\n .attr(\"width\", this.options.width-this.margin.left-this.margin.right)\n .attr(\"height\", this.options.height-this.margin.top-this.margin.bottom)\n .on(\"mouseover\", function() {\n focus.style(\"display\", null);\n })\n .on(\"mouseout\", () => {\n focus.style(\"display\", \"none\");\n this.tip.hide();\n })\n .on(\"mousemove\", (a,b,el) => {\n var x0 = this.xScale.invert(d3.mouse(el[0])[0]),\n i = this.bisectYears(this.growthA, x0, 1),\n d0 = this.growthA[i - 1],\n d1 = this.growthA[i];\n if(!d0 || !d1) { return true; }\n var quoteA = x0 - d0.year > d1.year - x0 ? d1 : d0,\n quoteB = this.growthB[quoteA.year]\n\n // if(quoteA.amount < quoteB.amount) {\n // var tempQuote = quoteA\n // quoteA = quoteB\n // quoteB = tempQuote\n // }\n\n var xPoint = this.xScale(quoteA.year),\n topPoint = this.yScale(quoteA.amount),\n bottomPoint = this.yScale(quoteB.amount)\n this.xHoverLine.attr('x1', xPoint)\n .attr('x2', xPoint)\n .attr('y1', topPoint)\n .attr('y2', bottomPoint)\n\n focusCircle.attr('cy', topPoint)\n .attr('cx', xPoint)\n bottomFocusCircle.attr('cy', bottomPoint)\n .attr('cx', xPoint)\n\n middleFocusCircle.attr('cy', this.yScale((quoteA.amount - quoteB.amount)/2+quoteB.amount))\n .attr('cx', xPoint)\n\n this.tip.show(this.messageForYear(quoteA, quoteB), middleFocusCircle.node())\n });\n\n // X-axis\n this.xAxisEl = this.svg.append(\"g\")\n .attr(\"class\", \"x axis\")\n .attr(\"transform\", \"translate(\"+this.margin.left+\",\" + (this.options.height-this.margin.top-10) + \")\");\n this.xAxisEl.append(\"text\")\n .attr(\"class\", \"text-end text-lg\")\n .attr(\"y\", -24)\n .attr(\"x\", this.options.width - this.margin.left - this.margin.right)\n .attr(\"dy\", \".71em\")\n .text(\"Years\");\n\n // Y-axis\n this.yAxisEl = this.svg.append(\"g\")\n .attr(\"class\", \"y axis\")\n .attr(\"transform\", \"translate(\"+this.margin.left+\",\"+this.margin.top+\")\");\n this.yAxisEl.append(\"text\")\n .attr(\"class\", \"text-end rotate--90 text-lg\")\n .attr(\"y\", 12)\n .attr(\"x\", this.margin.top - 40)\n .attr(\"dy\", \".71em\")\n .text(\"Total Amount\");\n }\n\n messageForYear(quoteA, quoteB) {\n var difference = quoteA.amount - quoteB.amount\n return `

${numeral(difference).format('$0,000')} after ${quoteA.year} year${quoteA.year > 1 ? 's' : ''}

${numeral(quoteA.amount).format('$0,000')} from ${this.nameA}

${numeral(quoteB.amount).format('$0,000')} from ${this.nameB}

`\n }\n\n\n update(nameA, nameB, growthA, growthB) {\n this.nameA = nameA;\n this.nameB = nameB;\n this.growthA = growthA;\n this.growthB = growthB;\n\n this.resize()\n\n var maxA = d3.max(this.growthA, function(y) { return y.amount; }),\n maxB = d3.max(this.growthB, function(y) { return y.amount; }),\n maxTotal = d3.max([maxA, maxB]);\n\n this.yScale = d3.scaleLinear()\n .domain([maxTotal, 0])\n .range([0, this.options.height - this.margin.bottom - this.margin.top]);\n this.xScale = d3.scaleLinear()\n .domain([0,this.growthA.length])\n .range([0, this.options.width - this.margin.left - this.margin.right]);\n var xTickCount = this.options.width / 100;\n if(xTickCount > 20) { xTickCount = 20; }\n var xAxis = d3.axisBottom().scale(this.xScale).ticks(xTickCount),\n yAxis = d3.axisLeft().scale(this.yScale).ticks(this.options.width/100).tickFormat((d) => d3.format(\".2s\")(d))\n\n // ${numeral(d).format('$0,000')}`)\n this.xAxisEl.call(xAxis);\n this.yAxisEl.call(yAxis);\n\n\n // Redraw the lines\n this.path.datum(this.growthA).attr('d', this.line);\n this.basePath.datum(this.growthB).attr('d', this.line);\n }\n}\n","\n\n\n"],"names":["FeeGraph","el","d3.bisector","d","bounds","width","height","d3.select","d3.line","quote","focus","focusCircle","bottomFocusCircle","d3.tip","message","middleFocusCircle","b","x0","d3.mouse","i","d0","d1","quoteA","quoteB","xPoint","topPoint","bottomPoint","difference","numeral","nameA","nameB","growthA","growthB","maxA","d3.max","y","maxB","maxTotal","d3.scaleLinear","xTickCount","xAxis","d3.axisBottom","yAxis","d3.axisLeft","d3.format","_sfc_main","growth","throttle","_hoisted_1","_openBlock","_createElementBlock"],"mappings":"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"}