"use strict"; /**  * Licensed Materials - Property of IBM  * IBM Cognos Products: Cognos Analytics  * Copyright IBM Corp. 2015, 2016  * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.  */ define(['underscore', 'q', 'jquery', 'rave2', 'bi/admin/nls/StringResource', 'bi/admin/common/visualizations/VizControl'], function (_, Q, $, rave, StringResource, VizControl) { 'use strict'; //NOSONAR: meant to be strict var StackedContext = function StackedContext(xScale, yScale) { return { x: function x(d) { return xScale(d.x); }, y: function y(d) { return yScale(d.y0 + d.y); }, width: xScale.rangeBand(), height: function height(d) { return yScale(d.y0) - yScale(d.y0 + d.y); } }; }; var GroupedContext = function GroupedContext(xScale, yScale, numLayers, svgHeight) { return { x: function x(d, i, j) { return xScale(d.x) + xScale.rangeBand() / numLayers * j; }, y: function y(d) { return yScale(d.y); }, width: xScale.rangeBand() / numLayers, height: function height(d) { return svgHeight - yScale(d.y); } }; }; var VizStackedBar = VizControl.extend({ chartMode: 'stacked', yticks: 5, init: function init(options) { this.margin.left = 45; this.margin.top = 10; this.margin.bottom = 60; VizStackedBar.inherited('init', this, arguments); }, _prepareData: function _prepareData(data) { this._rawData = data; var attr2 = this._attr2Name; var da = this._groupData(data, this._attr2Name); this._attr2Values = da.map(function (item) { return item[0][attr2]; }); return da; }, _draw: function _draw(data) { var n = data.length, m = data[0].layer.length, stack = rave.layout.stack().values(function (d) { return d.layer; }), layers = stack(data, function () {}), yGroupMax = rave.max(layers, function (l) { return rave.max(l.layer, function (d) { return d.y; }); }), yStackMax = rave.max(layers, function (l) { return rave.max(l.layer, function (d) { return d.y0 + d.y; }); }), yMax = this.chartMode === 'stacked' ? yStackMax : yGroupMax, bottom = this.margin.top + this.svgHeight; var x = rave.scale.ordinal().domain(rave.range(m)).rangeRoundBands([0, this.svgWidth], 0.1); var y = rave.scale.linear().domain([0, yMax * 1.2]).range([this.svgHeight, 0]); var xAxis = rave.svg.axis().scale(x).tickSize(5).orient('bottom'); var maxDataValue = 0; data.forEach(function (dataItem) { maxDataValue = Math.max(dataItem.total, maxDataValue); }); var yAxis = rave.svg.axis().scale(y).tickSize(5).tickPadding(6).ticks(Math.min(maxDataValue, this.yticks)).orient('left'); this.svg.append('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); var getColor = function getColor(d) { return this._colorScale(d.name); }; var layer = this.svg.selectAll('.layer').data(layers).enter().append('g').attr('class', 'layer').style('fill', getColor.bind(this)).attr('transform', function () { return 'translate(' + this.margin.left + ', ' + this.margin.top + ')'; }.bind(this)); var context = this.chartMode === 'stacked' ? new StackedContext(x, y, n, this.svgHeight) : new GroupedContext(x, y, n, this.svgHeight); var rects = layer.selectAll('rect').data(function (d) { return d.layer; }).enter().append('rect').attr('x', context.x).attr('y', this.svgHeight).attr('width', context.width).attr('height', 0); rects.on('mouseover', function () { var rect = rave.select(this); var color = rect.style('fill') || '#ddd'; var rgb = rave.rgb(color).darker(); rect.style('fill', rgb.toString()); }).on('mouseout', function () { rave.select(this).style('fill', null); }); rects.transition().delay(function (d, i) { return i * 20; }).attr('y', context.y).attr('height', context.height); this.svg.append('g').attr('class', 'bi-chart-axis x-axis').attr('transform', 'translate(' + this.margin.left + ', ' + bottom + ')').call(xAxis); var ya = this.svg.append('g').attr('class', 'bi-chart-axis y-axis-stackedbar').attr('transform', 'translate(' + this.margin.left + ', ' + this.margin.top + ')').call(yAxis); var rules = this.svg.selectAll('g.bi-chart-rule').data(y.ticks(this.yticks)).enter().append('g').attr('class', 'bi-chart-rule').attr('transform', function (d) { return 'translate(' + this.margin.left + ', ' + (this.margin.top + y(d)) + ')'; }.bind(this)); rules.append('line').attr('x2', this.svgWidth).style('stroke-opacity', function (d) { return d ? .7 : 0; }); var legends = _.map(layers, function (l) { return l.name; }); var lx = rave.scale.ordinal().domain(legends).rangeRoundBands([this.margin.left, this.width], 0.1); var legend = this.svg.selectAll('.bi-chart-legend').data(layers).enter().append('g').attr('class', 'bi-chart-legend').attr('transform', function (d) { return 'translate(' + lx(d.name) + ', ' + (bottom + 30) + ')'; }.bind(this)); legend.append('rect').attr('x', 0).attr('width', 18).attr('height', 18).style('fill', getColor.bind(this)); legend.append('text').attr('x', 24).attr('y', 9).attr('dy', '.35em').text(function (d) { return StringResource.get(d.legendName) + (d.total ? ' ( ' + d.total + ' )' : ' ( 0 )'); }); var transRules = function (yMax) { y.domain([0, yMax * 1.2]); ya.transition().duration(300).ease('circle').call(yAxis); var rules = this.svg.selectAll('g.bi-chart-rule').data(y.ticks(this.yticks)); rules.exit().remove(); rules.enter().append('g').attr('class', 'bi-chart-rule').attr('transform', function (d) { return 'translate(' + this.margin.left + ', ' + (this.margin.top + y(d)) + ')'; }.bind(this)); rules.enter().append('line').attr('x2', this.svgWidth).style('stroke-opacity', function (d) { return d ? .7 : 0; }); rules.transition().duration(300).ease('circle').attr('transform', function (d) { return 'translate(' + this.margin.left + ', ' + (this.margin.top + y(d)) + ')'; }.bind(this)); }.bind(this); var transitionGrouped = function transitionGrouped() { transRules(yGroupMax); var context = new GroupedContext(x, y, n, this.svgHeight); rects.transition().duration(300).delay(function (d, i) { return i * 20; }).attr('x', context.x).attr('width', context.width).transition().attr('y', context.y).attr('height', context.height); }; var transitionStacked = function transitionStacked() { transRules(yStackMax); var context = new StackedContext(x, y, n, this.svgHeight); rects.transition().duration(300).delay(function (d, i) { return i * 20; }).attr('y', context.y).attr('height', context.height).transition().attr('x', context.x).attr('width', context.width); }; this._transitionGrouped = transitionGrouped; this._transitionStacked = transitionStacked; }, changeMode: function changeMode(mode) { if (this.chartMode !== mode) { this.chartMode = mode; if (mode === 'stacked') { this._transitionStacked(); } else { this._transitionGrouped(); } } } }); return VizStackedBar; });