initialize: function(chart, datasetIndex) {
Chart.DatasetController.prototype.initialize.call(this, chart, datasetIndex);
+ var me = this;
+ var meta = me.getMeta();
+ var dataset = me.getDataset();
+
+ meta.stack = dataset.stack;
// Use this to indicate that this is a bar dataset.
- this.getMeta().bar = true;
+ meta.bar = true;
},
- // Get the number of datasets that display bars. We use this to correctly calculate the bar width
- getBarCount: function() {
+ // Correctly calculate the bar width accounting for stacks and the fact that not all bars are visible
+ getStackCount: function() {
var me = this;
- var barCount = 0;
+ var meta = me.getMeta();
+ var yScale = me.getScaleForId(meta.yAxisID);
+
+ var stacks = [];
helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
- var meta = me.chart.getDatasetMeta(datasetIndex);
- if (meta.bar && me.chart.isDatasetVisible(datasetIndex)) {
- ++barCount;
+ var dsMeta = me.chart.getDatasetMeta(datasetIndex);
+ if (dsMeta.bar && me.chart.isDatasetVisible(datasetIndex) &&
+ (yScale.options.stacked === false ||
+ (yScale.options.stacked === true && stacks.indexOf(dsMeta.stack) === -1) ||
+ (yScale.options.stacked === undefined && (dsMeta.stack === undefined || stacks.indexOf(dsMeta.stack) === -1)))) {
+ stacks.push(dsMeta.stack);
}
}, me);
- return barCount;
+
+ return stacks.length;
},
update: function(reset) {
var base = yScale.getBaseValue();
var original = base;
- if (yScale.options.stacked) {
+ if ((yScale.options.stacked === true) ||
+ (yScale.options.stacked === undefined && meta.stack !== undefined)) {
var chart = me.chart;
var datasets = chart.data.datasets;
var value = Number(datasets[datasetIndex].data[index]);
for (var i = 0; i < datasetIndex; i++) {
var currentDs = datasets[i];
var currentDsMeta = chart.getDatasetMeta(i);
- if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
+ if (currentDsMeta.bar && currentDsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i) &&
+ meta.stack === currentDsMeta.stack) {
var currentVal = Number(currentDs.data[index]);
base += value < 0 ? Math.min(currentVal, original) : Math.max(currentVal, original);
}
var me = this;
var meta = me.getMeta();
var xScale = me.getScaleForId(meta.xAxisID);
- var datasetCount = me.getBarCount();
+ var stackCount = me.getStackCount();
- var tickWidth = xScale.width / xScale.ticks.length;
+ var tickWidth = xScale.width / xScale.ticks.length;\r
var categoryWidth = tickWidth * xScale.options.categoryPercentage;
var categorySpacing = (tickWidth - (tickWidth * xScale.options.categoryPercentage)) / 2;
- var fullBarWidth = categoryWidth / datasetCount;
+ var fullBarWidth = categoryWidth / stackCount;
var barWidth = fullBarWidth * xScale.options.barPercentage;
var barSpacing = fullBarWidth - (fullBarWidth * xScale.options.barPercentage);
return {
- datasetCount: datasetCount,
+ stackCount: stackCount,
tickWidth: tickWidth,
categoryWidth: categoryWidth,
categorySpacing: categorySpacing,
},
calculateBarWidth: function(ruler) {
- var xScale = this.getScaleForId(this.getMeta().xAxisID);
+ var me = this;
+ var meta = me.getMeta();
+ var xScale = me.getScaleForId(meta.xAxisID);
if (xScale.options.barThickness) {
return xScale.options.barThickness;
}
- return xScale.options.stacked ? ruler.categoryWidth * xScale.options.barPercentage : ruler.barWidth;
+ return ruler.barWidth;\r
},
- // Get bar index from the given dataset index accounting for the fact that not all bars are visible
- getBarIndex: function(datasetIndex) {
- var barIndex = 0;
- var meta, j;
+ // Get stack index from the given dataset index accounting for stacks and the fact that not all bars are visible
+ getStackIndex: function(datasetIndex) {
+ var me = this;
+ var meta = me.chart.getDatasetMeta(datasetIndex);
+ var yScale = me.getScaleForId(meta.yAxisID);
+ var dsMeta, j;
+ var stacks = [meta.stack];
for (j = 0; j < datasetIndex; ++j) {
- meta = this.chart.getDatasetMeta(j);
- if (meta.bar && this.chart.isDatasetVisible(j)) {
- ++barIndex;
+ dsMeta = this.chart.getDatasetMeta(j);
+ if (dsMeta.bar && this.chart.isDatasetVisible(j) &&
+ (yScale.options.stacked === false ||
+ (yScale.options.stacked === true && stacks.indexOf(dsMeta.stack) === -1) ||
+ (yScale.options.stacked === undefined && (dsMeta.stack === undefined || stacks.indexOf(dsMeta.stack) === -1)))) {
+ stacks.push(dsMeta.stack);
}
}
- return barIndex;
+ return stacks.length - 1;
},
calculateBarX: function(index, datasetIndex, ruler) {
var me = this;
var meta = me.getMeta();
var xScale = me.getScaleForId(meta.xAxisID);
- var barIndex = me.getBarIndex(datasetIndex);
+ var stackIndex = me.getStackIndex(datasetIndex);
var leftTick = xScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
leftTick -= me.chart.isCombo ? (ruler.tickWidth / 2) : 0;
- if (xScale.options.stacked) {
- return leftTick + (ruler.categoryWidth / 2) + ruler.categorySpacing;
- }
-
return leftTick +
(ruler.barWidth / 2) +
ruler.categorySpacing +
- (ruler.barWidth * barIndex) +
+ (ruler.barWidth * stackIndex) +
(ruler.barSpacing / 2) +
- (ruler.barSpacing * barIndex);
+ (ruler.barSpacing * stackIndex);
},
calculateBarY: function(index, datasetIndex) {
var yScale = me.getScaleForId(meta.yAxisID);
var value = Number(me.getDataset().data[index]);
- if (yScale.options.stacked) {
-
+ if (yScale.options.stacked ||
+ (yScale.options.stacked === undefined && meta.stack !== undefined)) {
var base = yScale.getBaseValue();
var sumPos = base,
- sumNeg = base;
+ sumNeg = base;\r
for (var i = 0; i < datasetIndex; i++) {
var ds = me.chart.data.datasets[i];
var dsMeta = me.chart.getDatasetMeta(i);
- if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i)) {
+ if (dsMeta.bar && dsMeta.yAxisID === yScale.id && me.chart.isDatasetVisible(i) &&
+ meta.stack === dsMeta.stack) {
var stackedVal = Number(ds.data[index]);
if (stackedVal < 0) {
sumNeg += stackedVal || 0;
};
Chart.controllers.horizontalBar = Chart.controllers.bar.extend({
+
+ // Correctly calculate the bar width accounting for stacks and the fact that not all bars are visible
+ getStackCount: function() {
+ var me = this;
+ var meta = me.getMeta();
+ var xScale = me.getScaleForId(meta.xAxisID);
+
+ var stacks = [];
+ helpers.each(me.chart.data.datasets, function(dataset, datasetIndex) {
+ var dsMeta = me.chart.getDatasetMeta(datasetIndex);
+ if (dsMeta.bar && me.chart.isDatasetVisible(datasetIndex) &&
+ (xScale.options.stacked === false ||
+ (xScale.options.stacked === true && stacks.indexOf(dsMeta.stack) === -1) ||
+ (xScale.options.stacked === undefined && (dsMeta.stack === undefined || stacks.indexOf(dsMeta.stack) === -1)))) {
+ stacks.push(dsMeta.stack);
+ }
+ }, me);
+
+ return stacks.length;
+ },
+
updateElement: function(rectangle, index, reset) {
var me = this;
var meta = me.getMeta();
var base = xScale.getBaseValue();
var originalBase = base;
- if (xScale.options.stacked) {
+ if (xScale.options.stacked ||
+ (xScale.options.stacked === undefined && meta.stack !== undefined)) {
var chart = me.chart;
var datasets = chart.data.datasets;
var value = Number(datasets[datasetIndex].data[index]);
for (var i = 0; i < datasetIndex; i++) {
var currentDs = datasets[i];
var currentDsMeta = chart.getDatasetMeta(i);
- if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i)) {
+ if (currentDsMeta.bar && currentDsMeta.xAxisID === xScale.id && chart.isDatasetVisible(i) &&
+ meta.stack === currentDsMeta.stack) {
var currentVal = Number(currentDs.data[index]);
base += value < 0 ? Math.min(currentVal, originalBase) : Math.max(currentVal, originalBase);
}
var me = this;
var meta = me.getMeta();
var yScale = me.getScaleForId(meta.yAxisID);
- var datasetCount = me.getBarCount();
+ var stackCount = me.getStackCount();
var tickHeight = yScale.height / yScale.ticks.length;
var categoryHeight = tickHeight * yScale.options.categoryPercentage;
var categorySpacing = (tickHeight - (tickHeight * yScale.options.categoryPercentage)) / 2;
- var fullBarHeight = categoryHeight / datasetCount;
+ var fullBarHeight = categoryHeight / stackCount;
var barHeight = fullBarHeight * yScale.options.barPercentage;
var barSpacing = fullBarHeight - (fullBarHeight * yScale.options.barPercentage);
return {
- datasetCount: datasetCount,
+ stackCount: stackCount,
tickHeight: tickHeight,
categoryHeight: categoryHeight,
categorySpacing: categorySpacing,
calculateBarHeight: function(ruler) {
var me = this;
- var yScale = me.getScaleForId(me.getMeta().yAxisID);
+ var meta = me.getMeta();
+ var yScale = me.getScaleForId(meta.yAxisID);
if (yScale.options.barThickness) {
return yScale.options.barThickness;
}
- return yScale.options.stacked ? ruler.categoryHeight * yScale.options.barPercentage : ruler.barHeight;
+ return ruler.barHeight;
+ },
+
+ // Get stack index from the given dataset index accounting for stacks and the fact that not all bars are visible
+ getStackIndex: function(datasetIndex) {
+ var me = this;
+ var meta = me.chart.getDatasetMeta(datasetIndex);
+ var xScale = me.getScaleForId(meta.xAxisID);
+ var dsMeta, j;
+ var stacks = [meta.stack];
+
+ for (j = 0; j < datasetIndex; ++j) {
+ dsMeta = this.chart.getDatasetMeta(j);
+ if (dsMeta.bar && this.chart.isDatasetVisible(j) &&
+ (xScale.options.stacked === false ||
+ (xScale.options.stacked === true && stacks.indexOf(dsMeta.stack) === -1) ||
+ (xScale.options.stacked === undefined && (dsMeta.stack === undefined || stacks.indexOf(dsMeta.stack) === -1)))) {
+ stacks.push(dsMeta.stack);
+ }
+ }
+
+ return stacks.length - 1;\r
},
calculateBarX: function(index, datasetIndex) {
var xScale = me.getScaleForId(meta.xAxisID);
var value = Number(me.getDataset().data[index]);
- if (xScale.options.stacked) {
-
+ if (xScale.options.stacked ||
+ (xScale.options.stacked === undefined && meta.stack !== undefined)) {
var base = xScale.getBaseValue();
var sumPos = base,
- sumNeg = base;
+ sumNeg = base;\r
for (var i = 0; i < datasetIndex; i++) {
var ds = me.chart.data.datasets[i];
var dsMeta = me.chart.getDatasetMeta(i);
- if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i)) {
+ if (dsMeta.bar && dsMeta.xAxisID === xScale.id && me.chart.isDatasetVisible(i) &&
+ meta.stack === dsMeta.stack) {
var stackedVal = Number(ds.data[index]);
if (stackedVal < 0) {
sumNeg += stackedVal || 0;
var me = this;
var meta = me.getMeta();
var yScale = me.getScaleForId(meta.yAxisID);
- var barIndex = me.getBarIndex(datasetIndex);
+ var stackIndex = me.getStackIndex(datasetIndex);
var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;
- if (yScale.options.stacked) {
- return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;
- }
-
return topTick +
(ruler.barHeight / 2) +
ruler.categorySpacing +
- (ruler.barHeight * barIndex) +
+ (ruler.barHeight * stackIndex) +
(ruler.barSpacing / 2) +
- (ruler.barSpacing * barIndex);
+ (ruler.barSpacing * stackIndex);
}
});
};
expect(meta.yAxisID).toBe('firstYScaleID');
});
- it('should correctly count the number of bar datasets', function() {
- var chart = window.acquireChart({
- type: 'bar',
- data: {
- datasets: [
- {data: [], type: 'line'},
- {data: [], hidden: true},
- {data: []},
- {data: []}
- ],
- labels: []
- }
+ it('should correctly count the number of stacks ignoring datasets of other types and hidden datasets', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], type: 'line'},
+ {data: [], hidden: true},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackCount()).toBe(2);
});
+ });
- var meta = chart.getDatasetMeta(1);
- expect(meta.controller.getBarCount()).toBe(2);
+ it('should correctly count the number of stacks when a group is not specified', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackCount()).toBe(4);
+ });
});
- it('should correctly get the bar index accounting for hidden datasets', function() {
- var chart = window.acquireChart({
- type: 'bar',
- data: {
- datasets: [
- {data: []},
- {data: [], hidden: true},
- {data: [], type: 'line'},
- {data: []}
- ],
- labels: []
- }
+ it('should correctly count the number of stacks when a group is not specified and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackCount()).toBe(1);
});
+ });
- var meta = chart.getDatasetMeta(1);
- expect(meta.controller.getBarIndex(0)).toBe(0);
- expect(meta.controller.getBarIndex(3)).toBe(1);
+ it('should correctly count the number of stacks when a group is not specified and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackCount()).toBe(4);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for some', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(3);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for some and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(2);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for some and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(4);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for all', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(2);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for all and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(2);
+ });
+ });
+
+ it('should correctly count the number of stacks when a group is specified for all and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(3);
+ expect(meta.controller.getStackCount()).toBe(4);
+ });
+ });
+
+ it('should correctly get the stack index accounting for datasets of other types and hidden datasets', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: [], hidden: true},
+ {data: [], type: 'line'},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(3)).toBe(1);
+ });
+ });
+
+ it('should correctly get the stack index when a group is not specified', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(1);
+ expect(meta.controller.getStackIndex(2)).toBe(2);
+ expect(meta.controller.getStackIndex(3)).toBe(3);
+ });
+ });
+
+ it('should correctly get the stack index when a group is not specified and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(0);
+ expect(meta.controller.getStackIndex(2)).toBe(0);
+ expect(meta.controller.getStackIndex(3)).toBe(0);
+ });
+ });
+
+ it('should correctly get the stack index when a group is not specified and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: []},
+ {data: []},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(1);
+ expect(meta.controller.getStackIndex(2)).toBe(2);
+ expect(meta.controller.getStackIndex(3)).toBe(3);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for some', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(0);
+ expect(meta.controller.getStackIndex(2)).toBe(1);
+ expect(meta.controller.getStackIndex(3)).toBe(2);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for some and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(0);
+ expect(meta.controller.getStackIndex(2)).toBe(1);
+ expect(meta.controller.getStackIndex(3)).toBe(1);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for some and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: []},
+ {data: []}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(1);
+ expect(meta.controller.getStackIndex(2)).toBe(2);
+ expect(meta.controller.getStackIndex(3)).toBe(3);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for all', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(0);
+ expect(meta.controller.getStackIndex(2)).toBe(1);
+ expect(meta.controller.getStackIndex(3)).toBe(1);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for all and the scale is stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: true
+ }],
+ yAxes: [{
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(0);
+ expect(meta.controller.getStackIndex(2)).toBe(1);
+ expect(meta.controller.getStackIndex(3)).toBe(1);
+ });
+ });
+
+ it('should correctly get the stack index when a group is specified for all and the scale is not stacked', function() {
+ [
+ 'bar',
+ 'horizontalBar'
+ ].forEach(function(barType) {
+ var chart = window.acquireChart({
+ type: barType,
+ data: {
+ datasets: [
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack1'},
+ {data: [], stack: 'stack2'},
+ {data: [], stack: 'stack2'}
+ ],
+ labels: []
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ stacked: false
+ }],
+ yAxes: [{
+ stacked: false
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+ expect(meta.controller.getStackIndex(0)).toBe(0);
+ expect(meta.controller.getStackIndex(1)).toBe(1);
+ expect(meta.controller.getStackIndex(2)).toBe(2);
+ expect(meta.controller.getStackIndex(3)).toBe(3);
+ });
});
it('should create rectangle elements for each data item during initialization', function() {
options: {
scales: {
xAxes: [{
- type: 'category',
- stacked: true,
- barPercentage: 1
+ type: 'category'
}],
yAxes: [{
type: 'linear',
var meta0 = chart.getDatasetMeta(0);
[
- {b: 290, w: 93, x: 86, y: 161},
- {b: 290, w: 93, x: 202, y: 419},
- {b: 290, w: 93, x: 318, y: 161},
- {b: 290, w: 93, x: 436, y: 419}
+ {b: 290, w: 83, x: 86, y: 161},
+ {b: 290, w: 83, x: 202, y: 419},
+ {b: 290, w: 83, x: 318, y: 161},
+ {b: 290, w: 83, x: 434, y: 419}
].forEach(function(values, i) {
expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
var meta1 = chart.getDatasetMeta(1);
[
- {b: 161, w: 93, x: 86, y: 32},
- {b: 290, w: 93, x: 202, y: 97},
- {b: 161, w: 93, x: 318, y: 161},
- {b: 419, w: 93, x: 436, y: 471}
+ {b: 161, w: 83, x: 86, y: 32},
+ {b: 290, w: 83, x: 202, y: 97},
+ {b: 161, w: 83, x: 318, y: 161},
+ {b: 419, w: 83, x: 434, y: 471}
].forEach(function(values, i) {
expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
options: {
scales: {
xAxes: [{
- type: 'category',
- stacked: true,
- barPercentage: 1
+ type: 'category'
}],
yAxes: [{
type: 'linear',
var meta0 = chart.getDatasetMeta(0);
[
- {b: 290, w: 93, x: 86, y: 161},
- {b: 290, w: 93, x: 202, y: 419},
- {b: 290, w: 93, x: 318, y: 161},
- {b: 290, w: 93, x: 436, y: 419}
+ {b: 290, w: 83, x: 86, y: 161},
+ {b: 290, w: 83, x: 202, y: 419},
+ {b: 290, w: 83, x: 318, y: 161},
+ {b: 290, w: 83, x: 434, y: 419}
].forEach(function(values, i) {
expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
var meta1 = chart.getDatasetMeta(1);
[
- {b: 161, w: 93, x: 86, y: 32},
- {b: 290, w: 93, x: 202, y: 97},
- {b: 161, w: 93, x: 318, y: 161},
- {b: 419, w: 93, x: 436, y: 471}
+ {b: 161, w: 83, x: 86, y: 32},
+ {b: 290, w: 83, x: 202, y: 97},
+ {b: 161, w: 83, x: 318, y: 161},
+ {b: 419, w: 83, x: 434, y: 471}
].forEach(function(values, i) {
expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
});
});
+ it('should get the correct bar points for grouped stacked chart if the group name is same', function() {
+ var chart = window.acquireChart({
+ type: 'bar',
+ data: {
+ datasets: [{
+ data: [10, -10, 10, -10],
+ label: 'dataset1',
+ stack: 'stack1'
+ }, {
+ data: [10, 15, 0, -4],
+ label: 'dataset2',
+ stack: 'stack1'
+ }],
+ labels: ['label1', 'label2', 'label3', 'label4']
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ type: 'category'
+ }],
+ yAxes: [{
+ type: 'linear',
+ stacked: true
+ }]
+ }
+ }
+ });
+
+ var meta0 = chart.getDatasetMeta(0);
+
+ [
+ {b: 290, w: 83, x: 86, y: 161},
+ {b: 290, w: 83, x: 202, y: 419},
+ {b: 290, w: 83, x: 318, y: 161},
+ {b: 290, w: 83, x: 434, y: 419}
+ ].forEach(function(values, i) {
+ expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
+ expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
+ expect(meta0.data[i]._model.x).toBeCloseToPixel(values.x);
+ expect(meta0.data[i]._model.y).toBeCloseToPixel(values.y);
+ });
+
+ var meta = chart.getDatasetMeta(1);
+
+ [
+ {b: 161, w: 83, x: 86, y: 32},
+ {b: 290, w: 83, x: 202, y: 97},
+ {b: 161, w: 83, x: 318, y: 161},
+ {b: 419, w: 83, x: 434, y: 471}
+ ].forEach(function(values, i) {
+ expect(meta.data[i]._model.base).toBeCloseToPixel(values.b);
+ expect(meta.data[i]._model.width).toBeCloseToPixel(values.w);
+ expect(meta.data[i]._model.x).toBeCloseToPixel(values.x);
+ expect(meta.data[i]._model.y).toBeCloseToPixel(values.y);
+ });
+ });
+
+ it('should get the correct bar points for grouped stacked chart if the group name is different', function() {
+ var chart = window.acquireChart({
+ type: 'bar',
+ data: {
+ datasets: [{
+ data: [1, 2],
+ stack: 'stack1'
+ }, {
+ data: [1, 2],
+ stack: 'stack2'
+ }],
+ labels: ['label1', 'label2', 'label3', 'label4']
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ type: 'category'
+ }],
+ yAxes: [{
+ stacked: true,
+ type: 'linear'
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(1);
+
+ [
+ {x: 108, y: 258},
+ {x: 224, y: 32}
+ ].forEach(function(values, i) {
+ expect(meta.data[i]._model.base).toBeCloseToPixel(484);
+ expect(meta.data[i]._model.width).toBeCloseToPixel(40);
+ expect(meta.data[i]._model.x).toBeCloseToPixel(values.x);
+ expect(meta.data[i]._model.y).toBeCloseToPixel(values.y);
+ });
+ });
+
+ it('should get the correct bar points for grouped stacked chart', function() {
+ var chart = window.acquireChart({
+ type: 'bar',
+ data: {
+ datasets: [{
+ data: [1, 2],
+ stack: 'stack1'
+ }, {
+ data: [0.5, 1],
+ stack: 'stack2'
+ }, {
+ data: [0.5, 1],
+ stack: 'stack2'
+ }],
+ labels: ['label1', 'label2', 'label3', 'label4']
+ },
+ options: {
+ scales: {
+ xAxes: [{
+ type: 'category'
+ }],
+ yAxes: [{
+ stacked: true,
+ type: 'linear'
+ }]
+ }
+ }
+ });
+
+ var meta = chart.getDatasetMeta(2);
+
+ [
+ {b: 371, x: 108, y: 258},
+ {b: 258, x: 224, y: 32}
+ ].forEach(function(values, i) {
+ expect(meta.data[i]._model.base).toBeCloseToPixel(values.b);
+ expect(meta.data[i]._model.width).toBeCloseToPixel(40);
+ expect(meta.data[i]._model.x).toBeCloseToPixel(values.x);
+ expect(meta.data[i]._model.y).toBeCloseToPixel(values.y);
+ });
+ });
+
it('should update elements when the scales are stacked and the y axis is logarithmic', function() {
var chart = window.acquireChart({
type: 'bar',
var chart = window.acquireChart(this.config);
var meta = chart.getDatasetMeta(0);
var xScale = chart.scales[meta.xAxisID];
+ var yScale = chart.scales[meta.yAxisID];
var categoryPercentage = xScale.options.categoryPercentage;
var barPercentage = xScale.options.barPercentage;
- var stacked = xScale.options.stacked;
+ var stacked = yScale.options.stacked;
var totalBarWidth = 0;
for (var i = 0; i < chart.data.datasets.length; i++) {
ticks: {
min: 'March',
max: 'May',
- },
- stacked: true,
+ }
+ }],
+ yAxes: [{
+ stacked: true
}]
}
}
afterEach(function() {
var chart = window.acquireChart(this.config);
var meta = chart.getDatasetMeta(0);
+ var xScale = chart.scales[meta.xAxisID];
var yScale = chart.scales[meta.yAxisID];
var categoryPercentage = yScale.options.categoryPercentage;
var barPercentage = yScale.options.barPercentage;
- var stacked = yScale.options.stacked;
+ var stacked = xScale.options.stacked;
var totalBarHeight = 0;
for (var i = 0; i < chart.data.datasets.length; i++) {
data: this.data,
options: {
scales: {
+ xAxes: [{
+ stacked: true
+ }],
yAxes: [{
ticks: {
min: 'March',
max: 'May',
- },
- stacked: true,
+ }
}]
}
}