From: Evert Timberg Date: Tue, 21 Mar 2017 00:38:15 +0000 (-0400) Subject: Fix for stacked bar charts with log axes (#4010) X-Git-Tag: v2.6.0~2^2~41 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=36ccf40946ae732e3614999ae86eadac7f248d20;p=thirdparty%2FChart.js.git Fix for stacked bar charts with log axes (#4010) * 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 --- diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 8f7ba3fa2..71a75b3af 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -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]; diff --git a/src/scales/scale.logarithmic.js b/src/scales/scale.logarithmic.js index 5d1d329f9..13d1d5a53 100644 --- a/src/scales/scale.logarithmic.js +++ b/src/scales/scale.logarithmic.js @@ -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; diff --git a/test/specs/controller.bar.tests.js b/test/specs/controller.bar.tests.js index db3cf0746..9717cff30 100644 --- a/test/specs/controller.bar.tests.js +++ b/test/specs/controller.bar.tests.js @@ -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); diff --git a/test/specs/scale.logarithmic.tests.js b/test/specs/scale.logarithmic.tests.js index 4562aa384..a29b28260 100644 --- a/test/specs/scale.logarithmic.tests.js +++ b/test/specs/scale.logarithmic.tests.js @@ -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);