{"version":3,"file":"diversification-risk-C0VvA-qk.js","sources":["../../../app/javascript/components/viz/diversification/diversification-risk-graph.js","../../../app/javascript/components/viz/diversification/diversification-risk.vue"],"sourcesContent":["import * as d3 from '~/app/custom-d3'\nimport numeral from 'numeral'\n\nexport default class RiskGraph {\n constructor(el, funds) {\n this.el = el\n this.margin = {\n top: 20,\n left: 50,\n right: 10,\n bottom: 20\n }\n\n this.funds = funds\n this.options = this.generateBounds()\n this.setup(d3.entries(funds))\n\n this.callbacks = {};\n }\n\n on(event, callback) {\n this.callbacks[event] = callback\n }\n\n generateBounds() {\n var bounds = this.el.getBoundingClientRect(),\n height = 300,\n width = 1100\n if(height > bounds.width) {\n height = bounds.width * 0.8\n }\n if(width > bounds.width) {\n width = bounds.width\n }\n return {\n height: height,\n width: width\n }\n }\n\n setup(funds) {\n this.svg = d3.select(this.el).append(\"svg\")\n .attr('class', 'graph')\n .attr(\"width\", this.options.width)\n .attr(\"height\", this.options.height);\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\", -18)\n .attr(\"x\", this.options.width-100)\n .attr(\"dy\", \".71em\")\n .text(\"Historical Risk\");\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 text-lg rotate--90\")\n .attr(\"y\", 6)\n .attr(\"x\", this.margin.top*-1)\n .attr(\"dy\", \".71em\")\n .text(\"Historical Returns\");\n\n\n // Risk/Reward path\n var g = this.svg.append('g')\n .attr('transform', \"translate(\" + this.margin.left + \",\" + this.margin.top + \")\");\n this.path = g.append('path')\n .attr('class', 'line stroke-grey-700 stroke-width-base stroke-dasharray-dashed-lg');\n\n\n\n // Tooltips\n this.tip = d3.tip().attr('class', 'd3-tip rounded').html(function(fund) {\n return `

${fund.label}

Avg gain: ${numeral(fund.computed.avg).format('0.0%')}
Risk: ${numeral(fund.computed.risk).format('0.0')}

`;\n }).offset([-18, 0]);\n this.svg.call(this.tip)\n\n\n // Points groups\n this.cirlces = this.svg.append(\"g\")\n .attr(\"class\", \"points\")\n .attr(\"transform\", \"translate(\" + this.margin.left + \",\" + this.margin.top + \")\");\n\n this.cirlces.selectAll('circle')\n .data(funds)\n .enter()\n .append('circle')\n .attr('r', 8)\n .attr('sector', (d) => d.key)\n .style('fill', (d) => d.value.style.darkColor)\n .style('stroke', (d) => d.value.style.darkColor)\n .style('stroke-width', 4)\n .on('mouseenter', (fund, index, element) => {\n this.callbacks['activate'](fund.key)\n })\n .on('mouseleave', (d) => {\n this.callbacks['activate']()\n })\n }\n\n update(fundObject) {\n var funds = d3.entries(fundObject)\n this.updateYAxis(funds)\n this.updateXAxis(funds)\n this.updateCircles(funds)\n this.updateRiskRewardLine()\n }\n\n\n // X-axis is for the risk\n updateXAxis(funds) {\n var maxRisk = d3.max(funds, (f) => +f.value.computed.risk)\n if(maxRisk < 10) { maxRisk = 10; }\n this.xScale = d3.scaleLinear()\n .domain([0,maxRisk+2])\n .range([0, this.options.width - this.margin.left - this.margin.right]);\n\n var xTickCount = this.options.width / 100;\n if(xTickCount > 20) { xTickCount = 20; }\n\n var xAxis = d3.axisBottom().scale(this.xScale).ticks(xTickCount)\n this.xAxisEl.call(xAxis);\n }\n\n // Y-axis is the average returns\n updateYAxis(funds) {\n var maxAvg = d3.max(funds, (f) => parseFloat(f.value.computed.avg)*100)\n var minAvg = d3.min(funds, (f) => parseFloat(f.value.computed.avg)*100)\n if(minAvg > 0) { minAvg = 0; }\n this.yScale = d3.scaleLinear()\n .domain([maxAvg, minAvg])\n .range([0, this.options.height - this.margin.bottom - this.margin.top])\n\n var yAxis = d3.axisLeft().scale(this.yScale).ticks(6).tickFormat((d) => `${d}%`)\n this.yAxisEl.call(yAxis);\n }\n\n // Place all circles\n updateCircles(funds) {\n var circles = this.cirlces.selectAll('circle').data(funds)\n\n circles.transition()\n .delay((d,i) => i*75)\n .duration(1000)\n .attr('cy', (d) => this.yScale(parseFloat(d.value.computed.avg)*100))\n .attr('cx', (d) => this.xScale(d.value.computed.risk))\n\n }\n\n // Draw the Risk/Reward line\n updateRiskRewardLine(funds) {\n var linePath = d3.path(),\n startX = this.xScale(1),\n startY = this.yScale(1);\n linePath.moveTo(startX, startY);\n linePath.bezierCurveTo(startX, startY, this.xScale(6), this.yScale(5), this.xScale(20), this.yScale(10));\n linePath.lineTo(this.xScale(30), this.yScale(11))\n this.path.transition()\n .duration(1000)\n .attr('d', linePath.toString())\n }\n\n highlight(sector) {\n if(sector && sector.length > 0) {\n var circle = this.cirlces.select(`[sector=${sector}]`),\n fund = this.funds[sector]\n this.cirlces.select(`[sector=${sector}]`).transition(150).attr('r', 16)\n this.tip.style('color', fund.style.darkColor)\n .style('background-color', fund.style.darkColor)\n this.tip.show(fund, circle.node())\n } else {\n this.cirlces.selectAll('circle').transition(500).attr('r', 8)\n this.tip.hide()\n }\n }\n}\n","\n\n\n"],"names":["RiskGraph","el","funds","d3.entries","event","callback","bounds","height","width","d3.select","g","d3.tip","fund","numeral","d","index","element","fundObject","maxRisk","d3.max","f","d3.scaleLinear","xTickCount","xAxis","d3.axisBottom","maxAvg","minAvg","d3.min","yAxis","d3.axisLeft","circles","i","linePath","d3.path","startX","startY","sector","circle","_sfc_main","newActiveFund","newFunds","symbol","_hoisted_1","_openBlock","_createElementBlock"],"mappings":"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"}