]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Fix for stacked bar charts with log axes (#4010)
authorEvert Timberg <evert.timberg+github@gmail.com>
Tue, 21 Mar 2017 00:38:15 +0000 (20:38 -0400)
committerGitHub <noreply@github.com>
Tue, 21 Mar 2017 00:38:15 +0000 (20:38 -0400)
* Undo fix for #3585 since it has broken the stacked bar charts when the axis has a user defined minimum value.

* When a value of 0 is requested for a vertical logarithmic axis, return the bottom point

src/controllers/controller.bar.js
src/scales/scale.logarithmic.js
test/specs/controller.bar.tests.js
test/specs/scale.logarithmic.tests.js

index 8f7ba3fa2b5c93b80194744f7b0cb383827b9b02..71a75b3af56df51b6fafcffd426ce4e6820c11de 100644 (file)
@@ -112,10 +112,9 @@ module.exports = function(Chart) {
                        var me = this;
                        var meta = me.getMeta();
                        var yScale = me.getScaleForId(meta.yAxisID);
-                       var base = yScale.getBaseValue();
-                       var original = base;
+                       var base = 0;
 
-                       if ((yScale.options.stacked === true) ||
+                       if (yScale.options.stacked === true ||
                                (yScale.options.stacked === undefined && meta.stack !== undefined)) {
                                var chart = me.chart;
                                var datasets = chart.data.datasets;
@@ -127,7 +126,7 @@ module.exports = function(Chart) {
                                        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);
+                                               base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
                                        }
                                }
 
@@ -227,9 +226,8 @@ module.exports = function(Chart) {
 
                        if (yScale.options.stacked ||
                                (yScale.options.stacked === undefined && meta.stack !== undefined)) {
-                               var base = yScale.getBaseValue();
-                               var sumPos = base,
-                                       sumNeg = base;
+                               var sumPos = 0,
+                                       sumNeg = 0;
 
                                for (var i = 0; i < datasetIndex; i++) {
                                        var ds = me.chart.data.datasets[i];
@@ -418,7 +416,6 @@ module.exports = function(Chart) {
                        var meta = me.getMeta();
                        var xScale = me.getScaleForId(meta.xAxisID);
                        var base = xScale.getBaseValue();
-                       var originalBase = base;
 
                        if (xScale.options.stacked ||
                                (xScale.options.stacked === undefined && meta.stack !== undefined)) {
@@ -432,7 +429,7 @@ module.exports = function(Chart) {
                                        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);
+                                               base += value < 0 ? Math.min(currentVal, 0) : Math.max(currentVal, 0);
                                        }
                                }
 
@@ -512,9 +509,8 @@ module.exports = function(Chart) {
 
                        if (xScale.options.stacked ||
                                (xScale.options.stacked === undefined && meta.stack !== undefined)) {
-                               var base = xScale.getBaseValue();
-                               var sumPos = base,
-                                       sumNeg = base;
+                               var sumPos = 0,
+                                       sumNeg = 0;
 
                                for (var i = 0; i < datasetIndex; i++) {
                                        var ds = me.chart.data.datasets[i];
index 5d1d329f9ab0d21a48a772c9bb0947ad05dc3f39..13d1d5a53129ebb1612a06dbe3ec60d32b403d0e 100644 (file)
@@ -216,6 +216,8 @@ module.exports = function(Chart) {
                                        } else {
                                                pixel = me.top + innerDimension * 0.02 + (innerDimension * 0.98/ range * (helpers.log10(newVal)-helpers.log10(me.minNotZero)));
                                        }
+                               } else if (newVal === 0) {
+                                       pixel = tickOpts.reverse ? me.top : me.bottom;
                                } else {
                                        range = helpers.log10(me.end) - helpers.log10(start);
                                        innerDimension = me.height;
index db3cf07460e03e166209f3aad07f9b888412fb12..9717cff30f238bd0e732726078722e77c186c6f7 100644 (file)
@@ -849,6 +849,65 @@ describe('Bar controller tests', function() {
                });
        });
 
+       it('should update elements when the scales are stacked and the y axis has a user definined minimum', function() {
+               var chart = window.acquireChart({
+                       type: 'bar',
+                       data: {
+                               datasets: [{
+                                       data: [50, 20, 10, 100],
+                                       label: 'dataset1'
+                               }, {
+                                       data: [50, 80, 90, 0],
+                                       label: 'dataset2'
+                               }],
+                               labels: ['label1', 'label2', 'label3', 'label4']
+                       },
+                       options: {
+                               scales: {
+                                       xAxes: [{
+                                               type: 'category'
+                                       }],
+                                       yAxes: [{
+                                               type: 'linear',
+                                               stacked: true,
+                                               ticks: {
+                                                       min: 50,
+                                                       max: 100
+                                               }
+                                       }]
+                               }
+                       }
+               });
+
+               var meta0 = chart.getDatasetMeta(0);
+
+               [
+                       {b: 936, w: 83, x: 87, y: 484},
+                       {b: 936, w: 83, x: 202, y: 755},
+                       {b: 936, w: 83, x: 318, y: 846},
+                       {b: 936, w: 83, x: 434, y: 32}
+               ].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 meta1 = chart.getDatasetMeta(1);
+
+               [
+                       {b: 484, w: 83, x: 87, y: 32},
+                       {b: 755, w: 83, x: 202, y: 32},
+                       {b: 846, w: 83, x: 318, y: 32},
+                       {b: 32, w: 83, x: 434, y: 32}
+               ].forEach(function(values, i) {
+                       expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
+                       expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
+                       expect(meta1.data[i]._model.x).toBeCloseToPixel(values.x);
+                       expect(meta1.data[i]._model.y).toBeCloseToPixel(values.y);
+               });
+       });
+
        it('should update elements when only the category scale is stacked', function() {
                var chart = window.acquireChart({
                        type: 'bar',
@@ -1119,7 +1178,7 @@ describe('Bar controller tests', function() {
                                        }],
                                        yAxes: [{
                                                type: 'logarithmic',
-                                               stacked: true
+                                               stacked: true,
                                        }]
                                }
                        }
@@ -1128,10 +1187,10 @@ describe('Bar controller tests', function() {
                var meta0 = chart.getDatasetMeta(0);
 
                [
-                       {b: 484, w: 92, x: 94, y: 379},
-                       {b: 484, w: 92, x: 208, y: 122},
-                       {b: 484, w: 92, x: 322, y: 379},
-                       {b: 484, w: 92, x: 436, y: 122}
+                       {b: 484, w: 92, x: 94, y: 484},
+                       {b: 484, w: 92, x: 208, y: 136},
+                       {b: 484, w: 92, x: 322, y: 484},
+                       {b: 484, w: 92, x: 436, y: 136}
                ].forEach(function(values, i) {
                        expect(meta0.data[i]._model.base).toBeCloseToPixel(values.b);
                        expect(meta0.data[i]._model.width).toBeCloseToPixel(values.w);
@@ -1142,10 +1201,10 @@ describe('Bar controller tests', function() {
                var meta1 = chart.getDatasetMeta(1);
 
                [
-                       {b: 379, w: 92, x: 94, y: 109},
-                       {b: 122, w: 92, x: 208, y: 109},
-                       {b: 379, w: 92, x: 322, y: 379},
-                       {b: 122, w: 92, x: 436, y: 25}
+                       {b: 484, w: 92, x: 94, y: 122},
+                       {b: 136, w: 92, x: 208, y: 122},
+                       {b: 484, w: 92, x: 322, y: 484},
+                       {b: 136, w: 92, x: 436, y: 32}
                ].forEach(function(values, i) {
                        expect(meta1.data[i]._model.base).toBeCloseToPixel(values.b);
                        expect(meta1.data[i]._model.width).toBeCloseToPixel(values.w);
index 4562aa384f5027b436642d427d03bb42132e9934..a29b28260a3f0670cb45564992f6895203612f7e 100644 (file)
@@ -726,7 +726,7 @@ describe('Logarithmic Scale tests', function() {
                expect(yScale.getPixelForValue(80, 0, 0)).toBeCloseToPixel(32);   // top + paddingTop
                expect(yScale.getPixelForValue(1, 0, 0)).toBeCloseToPixel(484);  // bottom - paddingBottom
                expect(yScale.getPixelForValue(10, 0, 0)).toBeCloseToPixel(246);  // halfway
-               expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(32);   // 0 is invalid. force it on top
+               expect(yScale.getPixelForValue(0, 0, 0)).toBeCloseToPixel(484);   // 0 is invalid. force it on bottom
 
                expect(yScale.getValueForPixel(32)).toBeCloseTo(80, 1e-4);
                expect(yScale.getValueForPixel(484)).toBeCloseTo(1, 1e-4);