From e0116cbd98b0018331fdc15677d8746031de7597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 28 Mar 2019 15:03:27 -0400 Subject: [PATCH 1/2] don't try to grab position of category '0' ... when computing bounds array for heatmap/contour traces with category x/y coordinates. This lead to a correct position and the `|| 0` fallback got ignored. --- src/traces/heatmap/calc.js | 8 ++++---- src/traces/heatmap/make_bound_array.js | 10 +++++----- test/jasmine/tests/heatmap_test.js | 17 ++++++++++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index 32a82f76d3c..9b362500b05 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -67,10 +67,10 @@ module.exports = function calc(gd, trace) { y = trace.y ? ya.makeCalcdata(trace, 'y') : []; } - x0 = trace.x0 || 0; - dx = trace.dx || 1; - y0 = trace.y0 || 0; - dy = trace.dy || 1; + x0 = trace.x0; + dx = trace.dx; + y0 = trace.y0; + dy = trace.dy; z = clean2dArray(zIn, trace.transpose); diff --git a/src/traces/heatmap/make_bound_array.js b/src/traces/heatmap/make_bound_array.js index 84e09b1ce43..7abc1f6cd2e 100644 --- a/src/traces/heatmap/make_bound_array.js +++ b/src/traces/heatmap/make_bound_array.js @@ -63,20 +63,20 @@ module.exports = function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, } } else { - dv = dvIn || 1; - var calendar = trace[ax._id.charAt(0) + 'calendar']; - if(isHist || ax.type === 'category' || ax.type === 'multicategory') { - v0 = ax.r2c(v0In, 0, calendar) || 0; - } else if(isArrayOrTypedArray(arrayIn) && arrayIn.length === 1) { + if(isArrayOrTypedArray(arrayIn) && arrayIn.length === 1) { v0 = arrayIn[0]; } else if(v0In === undefined) { v0 = 0; + } else if(isHist || ax.type === 'category' || ax.type === 'multicategory') { + v0 = ax.r2c(v0In, 0, calendar); } else { v0 = ax.d2c(v0In, 0, calendar); } + dv = dvIn || 1; + for(i = (isContour || isGL2D) ? 0 : -0.5; i < numbricks; i++) { arrayOut.push(v0 + dv * i); } diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index c6db00e0da5..0ae0005be82 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -287,10 +287,11 @@ describe('heatmap convertColumnXYZ', function() { describe('heatmap calc', function() { 'use strict'; - function _calc(opts) { + function _calc(opts, layout) { var base = { type: 'heatmap' }; var trace = Lib.extendFlat({}, base, opts); var gd = { data: [trace] }; + if(layout) gd.layout = layout; supplyAllDefaults(gd); var fullTrace = gd._fullData[0]; @@ -408,6 +409,20 @@ describe('heatmap calc', function() { expect(out.z).toBeCloseTo2DArray([[17, 18, 19]]); }); + it('should handle the category case (edge case with a *0* category)', function() { + var out = _calc({ + x: ['a', 'b', 0], + y: ['z', 0, 'y'], + z: [[17, 18, 19], [10, 20, 30], [40, 30, 20]] + }, { + xaxis: {type: 'category'}, + yaxis: {type: 'category'} + }); + + expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + }); + it('should handle the category x/y/z/ column case', function() { var out = _calc({ x: ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'], From d3713e1a68184e1cb9ab4672168b13d47698598a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Thu, 28 Mar 2019 15:03:42 -0400 Subject: [PATCH 2/2] add heatmap with '0' x/y category mock --- .../baselines/heatmap-with-zero-category.png | Bin 0 -> 13283 bytes .../mocks/heatmap-with-zero-category.json | 32 ++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 test/image/baselines/heatmap-with-zero-category.png create mode 100644 test/image/mocks/heatmap-with-zero-category.json diff --git a/test/image/baselines/heatmap-with-zero-category.png b/test/image/baselines/heatmap-with-zero-category.png new file mode 100644 index 0000000000000000000000000000000000000000..765ce76bd2a921a9f7c5a0bc8b0d62f6c71fd648 GIT binary patch literal 13283 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 XIt3C6Ei!?RceI=xT^%a-AG`P;J%Y^h literal 0 HcmV?d00001 diff --git a/test/image/mocks/heatmap-with-zero-category.json b/test/image/mocks/heatmap-with-zero-category.json new file mode 100644 index 00000000000..1280d125837 --- /dev/null +++ b/test/image/mocks/heatmap-with-zero-category.json @@ -0,0 +1,32 @@ +{ + "data": [ + { + "x": [ 3, 2, 1, 0 ], + "y": [ 3, 2, 1, 0 ], + "z": [ + [ 98, 97, 96, null ], + [ 88, 87, 86, null ], + [ 78, 77, 76, null ], + [ null, null, null, null ] + ], + "type": "heatmap", + "colorscale": [ + [ 0, "#3D9970" ], + [ 1, "#001f3f" ] + ], + "showscale": false, + "xgap": 1, + "ygap": 1 + } + ], + "layout": { + "height": 450, + "width": 650, + "xaxis": { + "type": "category" + }, + "yaxis": { + "type": "category" + } + } +}