123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- "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;
- });
|