From b7f794485c2df36b264da8d4a9eca5ec3c7059f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 5 Jul 2016 13:58:03 -0400 Subject: [PATCH 1/6] bar: skip over bars with non-numeric size in setPositions - before dd2251d7f1e61a62e10cd1107c107c3a0fea23ae bar for non-numeric size were excluded from the calcdata, which led to wrong bar widths in traces with gaps. However, this made setPositions stack non-numeric bars. --- src/traces/bar/calc.js | 6 ++++++ src/traces/bar/set_positions.js | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/src/traces/bar/calc.js b/src/traces/bar/calc.js index 7468cebdb48..dc8ee1e77e4 100644 --- a/src/traces/bar/calc.js +++ b/src/traces/bar/calc.js @@ -39,7 +39,13 @@ module.exports = function calc(gd, trace) { // create the "calculated data" to plot var serieslen = Math.min(pos.length, size.length), cd = []; + for(i = 0; i < serieslen; i++) { + + // add bars with non-numeric sizes to calcdata + // so that ensure that traces with gaps are + // plotted in the correct order + if(isNumeric(pos[i])) { cd.push({p: pos[i], s: size[i], b: 0}); } diff --git a/src/traces/bar/set_positions.js b/src/traces/bar/set_positions.js index 14daefccfe4..dbc68616224 100644 --- a/src/traces/bar/set_positions.js +++ b/src/traces/bar/set_positions.js @@ -142,6 +142,11 @@ module.exports = function setPositions(gd, plotinfo) { for(i = 0; i < bl.length; i++) { // trace index ti = gd.calcdata[bl[i]]; for(j = 0; j < ti.length; j++) { + + // skip over bars with no size, + // so that we don't try to stack them + if(!isNumeric(ti[j].s)) continue; + sv = Math.round(ti[j].p / sumround); // store the negative sum value for p at the same key, with sign flipped if(relative && ti[j].s < 0) sv = -sv; From fa8aa5c7832bfc77e230d59588a0c9f08059b826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 5 Jul 2016 14:00:40 -0400 Subject: [PATCH 2/6] test: add stack with gaps mock --- test/image/baselines/bar_stack-with-gaps.png | Bin 0 -> 19235 bytes test/image/mocks/bar_stack-with-gaps.json | 175 +++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 test/image/baselines/bar_stack-with-gaps.png create mode 100644 test/image/mocks/bar_stack-with-gaps.json diff --git a/test/image/baselines/bar_stack-with-gaps.png b/test/image/baselines/bar_stack-with-gaps.png new file mode 100644 index 0000000000000000000000000000000000000000..2d08e07c8db4f2d3eda1e295c8a98310952e4713 GIT binary patch literal 19235 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 Date: Tue, 5 Jul 2016 14:01:48 -0400 Subject: [PATCH 3/6] test-assets: add msg-extra argument to is-close array matchers --- test/jasmine/assets/custom_matchers.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/jasmine/assets/custom_matchers.js b/test/jasmine/assets/custom_matchers.js index fc1e710bd19..09e5946c04a 100644 --- a/test/jasmine/assets/custom_matchers.js +++ b/test/jasmine/assets/custom_matchers.js @@ -3,7 +3,7 @@ module.exports = { // toBeCloseTo... but for arrays toBeCloseToArray: function() { return { - compare: function(actual, expected, precision) { + compare: function(actual, expected, precision, msgExtra) { precision = coercePosition(precision); var tested = actual.map(function(element, i) { @@ -15,9 +15,13 @@ module.exports = { tested.indexOf(false) < 0 ); + var message = [ + 'Expected', actual, 'to be close to', expected, msgExtra + ].join(' '); + return { pass: passed, - message: 'Expected ' + actual + ' to be close to ' + expected + '.' + message: message }; } }; @@ -26,7 +30,7 @@ module.exports = { // toBeCloseTo... but for 2D arrays toBeCloseTo2DArray: function() { return { - compare: function(actual, expected, precision) { + compare: function(actual, expected, precision, msgExtra) { precision = coercePosition(precision); var passed = true; @@ -54,7 +58,8 @@ module.exports = { 'Expected', arrayToStr(actual.map(arrayToStr)), 'to be close to', - arrayToStr(expected.map(arrayToStr)) + arrayToStr(expected.map(arrayToStr)), + msgExtra ].join(' '); return { From a2ad253d292a31f52b07813742c3e69d19f211ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 5 Jul 2016 14:02:22 -0400 Subject: [PATCH 4/6] test-assets: don't try to compute dist between non-numeric elements --- test/jasmine/assets/custom_matchers.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/test/jasmine/assets/custom_matchers.js b/test/jasmine/assets/custom_matchers.js index 09e5946c04a..75d88f5bdb1 100644 --- a/test/jasmine/assets/custom_matchers.js +++ b/test/jasmine/assets/custom_matchers.js @@ -1,3 +1,8 @@ +'use strict'; + +var isNumeric = require('fast-isnumeric'); + + module.exports = { // toBeCloseTo... but for arrays @@ -7,7 +12,7 @@ module.exports = { precision = coercePosition(precision); var tested = actual.map(function(element, i) { - return Math.abs(expected[i] - element) < precision; + return isClose(element, expected[i], precision); }); var passed = ( @@ -44,9 +49,7 @@ module.exports = { } for(var j = 0; j < expected[i].length; ++j) { - var isClose = Math.abs(expected[i][j] - actual[i][j]) < precision; - - if(!isClose) { + if(!isClose(actual[i][j], expected[i][j], precision)) { passed = false; break; } @@ -71,6 +74,14 @@ module.exports = { } }; +function isClose(actual, expected, precision) { + if(isNumeric(actual) && isNumeric(expected)) { + return Math.abs(actual - expected) < precision; + } + + return actual === expected; +} + function coercePosition(precision) { if(precision !== 0) { precision = Math.pow(10, -precision) / 2 || 0.005; From 4cc00660a93f3995bad3184cdae2fc9dea27731d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 5 Jul 2016 14:04:10 -0400 Subject: [PATCH 5/6] lint: flatten bar test suite --- test/jasmine/tests/bar_test.js | 100 ++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/test/jasmine/tests/bar_test.js b/test/jasmine/tests/bar_test.js index 7645b93c2cd..753c0b4c409 100644 --- a/test/jasmine/tests/bar_test.js +++ b/test/jasmine/tests/bar_test.js @@ -1,60 +1,70 @@ var Bar = require('@src/traces/bar'); +describe('bar supplyDefaults', function() { + 'use strict'; + + var traceIn, + traceOut; + + var defaultColor = '#444'; + + var supplyDefaults = Bar.supplyDefaults; + + beforeEach(function() { + traceOut = {}; + }); + + it('should set visible to false when x and y are empty', function() { + traceIn = {}; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + + traceIn = { + x: [], + y: [] + }; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + }); + + it('should set visible to false when x or y is empty', function() { + traceIn = { + x: [] + }; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + + traceIn = { + x: [], + y: [1, 2, 3] + }; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + + traceIn = { + y: [] + }; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + + traceIn = { + x: [1, 2, 3], + y: [] + }; + supplyDefaults(traceIn, traceOut, defaultColor); + expect(traceOut.visible).toBe(false); + }); +}); -describe('Test bar', function() { 'use strict'; - describe('supplyDefaults', function() { - var traceIn, - traceOut; - var defaultColor = '#444'; - var supplyDefaults = Bar.supplyDefaults; - beforeEach(function() { - traceOut = {}; }); - it('should set visible to false when x and y are empty', function() { - traceIn = {}; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); - - traceIn = { - x: [], - y: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); }); - it('should set visible to false when x or y is empty', function() { - traceIn = { - x: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); - - traceIn = { - x: [], - y: [1, 2, 3] - }; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); - - traceIn = { - y: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); - - traceIn = { - x: [1, 2, 3], - y: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor); - expect(traceOut.visible).toBe(false); }); }); From ef0c67fda41ecd06f6d97d4314e5192157d0dc90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Tue, 5 Jul 2016 14:04:28 -0400 Subject: [PATCH 6/6] test: add bar calc / setPositions tests --- test/jasmine/tests/bar_test.js | 114 +++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/test/jasmine/tests/bar_test.js b/test/jasmine/tests/bar_test.js index 753c0b4c409..365891170d9 100644 --- a/test/jasmine/tests/bar_test.js +++ b/test/jasmine/tests/bar_test.js @@ -1,5 +1,10 @@ +var Plots = require('@src/plots/plots'); +var Lib = require('@src/lib'); + var Bar = require('@src/traces/bar'); +var customMatchers = require('../assets/custom_matchers'); + describe('bar supplyDefaults', function() { 'use strict'; @@ -56,17 +61,126 @@ describe('bar supplyDefaults', function() { }); }); +describe('heatmap calc / setPositions', function() { 'use strict'; + beforeAll(function() { + jasmine.addMatchers(customMatchers); + }); + + function _calc(dataOpts, layout) { + var baseData = { type: 'bar' }; + + var data = dataOpts.map(function(traceOpts) { + return Lib.extendFlat({}, baseData, traceOpts); + }); + + var gd = { + data: data, + layout: layout, + calcdata: [] + }; + + Plots.supplyDefaults(gd); + + gd._fullData.forEach(function(fullTrace) { + var cd = Bar.calc(gd, fullTrace); + + cd[0].t = {}; + cd[0].trace = fullTrace; + + gd.calcdata.push(cd); + }); + + var plotinfo = { + x: function() { return gd._fullLayout.xaxis; }, + y: function() { return gd._fullLayout.yaxis; } + }; + + Bar.setPositions(gd, plotinfo); + + return gd.calcdata; + } + function assertPtField(calcData, prop, expectation) { + var values = []; + + calcData.forEach(function(calcTrace) { + var vals = calcTrace.map(function(pt) { + return Lib.nestedProperty(pt, prop).get(); + }); + + values.push(vals); + }); + expect(values).toBeCloseTo2DArray(expectation, undefined, '- field ' + prop); + } + function assertTraceField(calcData, prop, expectation) { + var values = calcData.map(function(calcTrace) { + return Lib.nestedProperty(calcTrace[0], prop).get(); }); + expect(values).toBeCloseToArray(expectation, undefined, '- field ' + prop); + } + + it('should fill in calc pt fields (stack case)', function() { + var out = _calc([{ + y: [2, 1, 2] + }, { + y: [3, 1, 2] + }, { + y: [null, null, 2] + }], { + barmode: 'stack' }); + assertPtField(out, 'x', [[0, 1, 2], [0, 1, 2], [0, 1, 2]]); + assertPtField(out, 'y', [[2, 1, 2], [5, 2, 4], [undefined, undefined, 6]]); + assertPtField(out, 'b', [[0, 0, 0], [2, 1, 2], [0, 0, 4]]); + assertPtField(out, 's', [[2, 1, 2], [3, 1, 2], [undefined, undefined, 2]]); + assertPtField(out, 'p', [[0, 1, 2], [0, 1, 2], [0, 1, 2]]); + assertTraceField(out, 't.barwidth', [0.8, 0.8, 0.8]); + assertTraceField(out, 't.poffset', [-0.4, -0.4, -0.4]); + assertTraceField(out, 't.dbar', [1, 1, 1]); + }); + + it('should fill in calc pt fields (overlay case)', function() { + var out = _calc([{ + y: [2, 1, 2] + }, { + y: [3, 1, 2] + }], { + barmode: 'overlay' + }); + + assertPtField(out, 'x', [[0, 1, 2], [0, 1, 2]]); + assertPtField(out, 'y', [[2, 1, 2], [3, 1, 2]]); + assertPtField(out, 'b', [[0, 0, 0], [0, 0, 0]]); + assertPtField(out, 's', [[2, 1, 2], [3, 1, 2]]); + assertPtField(out, 'p', [[0, 1, 2], [0, 1, 2]]); + assertTraceField(out, 't.barwidth', [0.8, 0.8]); + assertTraceField(out, 't.poffset', [-0.4, -0.4]); + assertTraceField(out, 't.dbar', [1, 1]); + }); + + it('should fill in calc pt fields (group case)', function() { + var out = _calc([{ + y: [2, 1, 2] + }, { + y: [3, 1, 2] + }], { + barmode: 'group' }); + assertPtField(out, 'x', [[-0.2, 0.8, 1.8], [0.2, 1.2, 2.2]]); + assertPtField(out, 'y', [[2, 1, 2], [3, 1, 2]]); + assertPtField(out, 'b', [[0, 0, 0], [0, 0, 0]]); + assertPtField(out, 's', [[2, 1, 2], [3, 1, 2]]); + assertPtField(out, 'p', [[0, 1, 2], [0, 1, 2]]); + assertTraceField(out, 't.barwidth', [0.4, 0.4]); + assertTraceField(out, 't.poffset', [-0.4, 0]); + assertTraceField(out, 't.dbar', [1, 1]); }); });