Helper of LCMP_StrikeChart component
({ | |
//Function which draws the bar chart | |
barChart: function (component, helper) { | |
component.set('v.displayAxis', true); | |
var dataset = component.get("v.data"); //The data retrieved from the controller or parent component | |
var color = helper.getColors(); //Setting the colors to the bars | |
//Setting the orientation of the chart as vertical, can also be turned to horizontal | |
var isVertical = component.get('v.orientation') === 'vertical'; | |
var numericalAxis = isVertical ? 'y' : 'x'; | |
var stringAxis = isVertical ? 'x' : 'y'; | |
//Setting the labels for the X & Y axis | |
var xAxisLabel = component.get('v.xAxisLabel'); | |
var yAxisLabel = component.get('v.yAxisLabel'); | |
//Setting the height and width of the chart | |
var chartWidth = component.get('v.containerWidth'); | |
var chartHeight = helper.getHeight(chartWidth); | |
helper.setyAxisLabelMaxHeight(component, chartHeight); | |
var paddingBox = helper.getPaddingBox(chartWidth); | |
var leftAxis = component.find('leftAxis').getElement(); | |
$A.util.removeClass(leftAxis, 'slds-hide'); | |
var leftAxisLabelWidth = leftAxis.clientHeight; //get height since we rotated | |
chartWidth -= leftAxisLabelWidth; | |
var x0 = d3.scaleBand().rangeRound([0, chartWidth]).paddingInner(0.1); | |
var x1 = d3.scaleBand().padding(0.05); | |
var y = d3.scaleLinear().rangeRound([chartHeight, 0]); | |
//Setting the formats of the numbers and the strings | |
var numericalFormat = function (d) { | |
return helper.abbreviateNumber(d) | |
}; | |
var stringFormat = function (d) { | |
return d; | |
}; | |
var xTickFormatter = stringFormat; | |
var yTickFormatter = numericalFormat; | |
//Creating the values on both the axis | |
var xAxis = helper.addBottomAxis(x0, 0, xTickFormatter); | |
var yAxis = helper.addLeftAxis(y, 0, yTickFormatter); | |
var svg = d3.select(component.find('chart').getElement()).append("svg") | |
.attr("width", chartWidth) | |
.attr("height", chartHeight) | |
.attr('style', 'transform: translateX(' + (leftAxisLabelWidth) + 'px);'); | |
//Here we pass the chart related data from the LCMP_CaseTrackerCharts component as a wrapper object | |
//The options variable below stores all the fields from the wrapper except the label/Account field | |
var options = d3.keys(dataset[0]).filter(function(key) { return key !== "label"; }); | |
//Looping through each element of the data from parent and getting its name and corresponding value | |
dataset.forEach(function(d) { | |
d.valores = options.map(function(name) { return {name: name, value: +d[name]}; }); | |
}); | |
//X0 is the chart element, X1 is each bar in the chart | |
x0.domain(dataset.map(function(d) { return d.label; })); | |
x1.domain(options).rangeRound([0, x0.bandwidth()]); | |
y.domain([0, d3.max(dataset, function(d) { return d3.max(d.valores, function(d) { return d.value; }); })]); | |
//The functions which create the html to form the bar chart | |
svg.append("g") | |
.attr("class", "x sc-axis") | |
.attr("transform", "translate(0," + chartHeight + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y sc-axis") | |
.call(yAxis); | |
//Drawing each bar and drawing it as per its label and positioning it appropriately | |
var bar = svg.selectAll(".sc-bc-bar") | |
.data(dataset) | |
.enter().append("g") | |
.attr("transform", function(d) { return "translate(" + x0(d.label) + ",0)"; }); | |
//Settig the x position and v position of each bar relative to the previous bar | |
bar.selectAll(".sc-bc-bar") | |
.data(function(d) { return d.valores; }) | |
.enter().append("rect").attr('class', 'sc-bc-bar')// drawing a rectangle and appending required styling | |
.attr("width", x1.bandwidth()) // setting the width of each bar | |
.attr("x", function(d) { return x1(d.name); }) | |
.attr("y", function(d) { return y(d.value); }) | |
.attr("value", function(d){return d.name;}) | |
.attr("height", function(d) { return chartHeight - y(d.value); }) // setting the height of the chart | |
.style("fill", function(d) { return color(d.name); }); // filling the color for the bar | |
//While hovering over each bar, the corresponding data values are displayed in the tooltip | |
bar.on('mouseover', $A.getCallback(function (dataPoint) { | |
var x = dataPoint.label; | |
var elements = document.querySelectorAll(':hover'); | |
var l = elements.length; | |
l = l-1; | |
var elementData = elements[l].__data__; | |
var elementLabel = elementData.name; | |
if(elementLabel==="OpenCases"){ | |
elementLabel = "Open Cases"; | |
} | |
else if(elementLabel==="ClosedCases"){ | |
elementLabel = "Closed Cases"; | |
} | |
else if(elementLabel==="TotalCases"){ | |
elementLabel = "Total Cases"; | |
} | |
var y = elementLabel +" - "+elementData.value; | |
// Setting the format of the tooltip | |
var tooltipHtml = '<span class="sc-axis-label">' + xAxisLabel + ': </span><span class="sc-axis-value">' + x + '</span><br/>' + | |
'<span class="sc-axis-label">' + yAxisLabel + ': </span><span class="sc-axis-value">' + y + '</span>'; | |
component.set('v.tooltipHtml', tooltipHtml) | |
})); | |
//Hide tooltip after the mouse moves out | |
bar.on('mouseout', $A.getCallback(function () { | |
helper.hideTooltip(component); | |
})); | |
//Get the position of the mouse relative to the chart | |
bar.on('mousemove', $A.getCallback(function (dataPoint) { | |
var mousePos = d3.mouse(component.find('chartContainer').getElement()); | |
var tooltipOptions = { | |
x: mousePos[0], | |
y: mousePos[1], | |
chartWidth: chartWidth | |
} | |
helper.showToolTip(component, tooltipOptions); | |
})); | |
//Setting the legend for the chart (legend is the indicator which helps to determine which color represents what number) | |
var legend = svg.selectAll(".legend") | |
.data(options.slice()) | |
.enter().append("g") | |
.attr("class", "legend") | |
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); | |
//Creating the rectangle for the legend | |
legend.append("rect") | |
.attr("x", chartWidth + 76) | |
.attr("width", 18) | |
.attr("height", 18) | |
.style("fill", color); | |
//Creating the text for the legend | |
legend.append("text") | |
.attr("x", chartWidth + 70) | |
.attr("y", 9) | |
.attr("dy", ".35em") | |
.attr("style", "font-size: .625rem;color: #8b8b8b;text-anchor: end") | |
.text(function(d) { | |
if(d === "OpenCases") { | |
d = "Open Cases"; | |
} else if(d === "ClosedCases") { | |
d = "Closed Cases"; | |
} | |
else if(d === "TotalCases") { | |
d = "Total Cases"; | |
} | |
return d; | |
}); | |
}, | |
//Sets the maximum value for the Y axis | |
setyAxisLabelMaxHeight: function (component, chartHeight) { | |
component.set('v.yAxisLabelMaxHeight', chartHeight * .7); | |
}, | |
// Funtion to hide the tooltip box | |
hideTooltip: function(component) { | |
component.set('v.tooltipOpacity', 0); | |
component.set('v.tooltipDisplay', 'none') | |
}, | |
//Function to set the tooltip position and data | |
showToolTip: function(component, tooltipOptions) { | |
var tooltipElement = component.find('tooltipContainer').getElement() | |
var tooltipElementCopy = component.find('tooltipContainerCopy').getElement(); | |
var tooltipOffSet = 10; | |
var tooltipXPos = tooltipOptions.x + tooltipOffSet; | |
var tooltipYPos = tooltipOptions.y + tooltipOffSet; | |
if ((tooltipElementCopy.clientWidth + tooltipXPos) > tooltipOptions.chartWidth) { | |
tooltipXPos -= (tooltipElementCopy.clientWidth + (tooltipOffSet * 2)); | |
if (tooltipXPos < 0) { | |
tooltipXPos = tooltipOptions.x + tooltipOffSet; | |
} | |
} | |
component.set('v.tooltipDisplay', 'block'); | |
component.set('v.tooltipXPos', tooltipXPos); | |
component.set('v.tooltipYPos', tooltipYPos); | |
component.set('v.tooltipOpacity', 1); | |
}, | |
//Function which sets the padding for the chart | |
getPaddingBox: function(chartWidth) { | |
return { | |
top: chartWidth * .02, | |
left: chartWidth * .1, | |
bottom: chartWidth * .1, | |
right: chartWidth * .02 | |
} | |
}, | |
//Function which sets the colors for the bars | |
getColors: function() { | |
return d3.scaleOrdinal().range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", | |
"#ff8c00", "#8cc5aa", "#9fa0a4", "#16325c", "#76ded9", "#08a69e", | |
"#e2cd81", "#e49e24", "#c03a38"]); | |
}, | |
//Function which rounds off the bar value | |
abbreviateNumber: function(amount) { | |
var absAmount = Math.abs(Number(amount)); | |
var amountNumber = Number(amount); | |
var shortenedNumber = amountNumber; | |
var abbreviation = ''; | |
var trillion = Math.pow(10, 12); | |
var billion = Math.pow(10, 9); | |
var million = Math.pow(10, 6); | |
var thousand = Math.pow(10, 3); | |
if (absAmount / trillion >= 1) { | |
shortenedNumber = amountNumber / trillion; | |
abbreviation = 'T'; | |
} else if (absAmount / billion >= 1) { | |
shortenedNumber = amountNumber / billion; | |
abbreviation = 'B'; | |
} else if (absAmount / million >= 1) { | |
shortenedNumber = amountNumber / million; | |
abbreviation = 'M'; | |
} else if (absAmount / thousand >= 1) { | |
shortenedNumber = amountNumber / thousand; | |
abbreviation = 'K'; | |
} | |
return (parseFloat(shortenedNumber.toFixed(1)) + abbreviation); | |
}, | |
addLeftAxis: function(scale, tickSizeOuter, tickFormat) { | |
return d3.axisLeft().scale(scale).tickSizeOuter(tickSizeOuter).tickFormat(tickFormat); | |
}, | |
addBottomAxis: function(scale, tickSizeOuter, tickFormat) { | |
return d3.axisBottom().scale(scale).tickSizeOuter(tickSizeOuter).tickFormat(tickFormat); | |
}, | |
getWidth: function(basedOnWidth) { | |
return basedOnWidth * .75; | |
}, | |
getHeight: function(basedOnWidth) { | |
return basedOnWidth * .66; | |
}, | |
//Function to determine the font size of the chart based on chart width | |
determineFontSize: function(chartWidth) { | |
var fontSize = '.8125rem'; | |
if (chartWidth < 767) { | |
fontSize = '.625rem'; | |
} else if (chartWidth < 1023) { | |
fontSize = '.75rem'; | |
} | |
return fontSize; | |
}, | |
//Function which performs the drawing of the chart | |
drawChart: function(component, helper) { | |
var chartType = component.get('v.type'); | |
var chartToDraw = chartType + 'Chart'; | |
if (chartType === 'pie' || chartType === 'donut') chartToDraw = 'pieDonutChart'; | |
helper[chartToDraw](component, helper); | |
component.set('v.chartRendered', true); | |
} | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment