From 4b1da2475a7e9f08035901062f008f00bbad9282 Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 15 Jun 2021 16:50:38 -0400 Subject: [PATCH 1/4] limit minDiff maximum to 1 for category axes --- src/lib/search.js | 8 ++------ src/traces/bar/cross_trace_calc.js | 9 ++++++--- src/traces/bar/sieve.js | 9 ++++++--- src/traces/box/calc.js | 2 +- src/traces/box/cross_trace_calc.js | 7 ++++--- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/lib/search.js b/src/lib/search.js index 738864f330d..c85ed5f975d 100644 --- a/src/lib/search.js +++ b/src/lib/search.js @@ -62,9 +62,7 @@ exports.sorterDes = function(a, b) { return b - a; }; * just be off by a rounding error * return the distinct values and the minimum difference between any two */ -exports.distinctVals = function(valsIn, opts) { - var unitMinDiff = (opts || {}).unitMinDiff; - +exports.distinctVals = function(valsIn) { var vals = valsIn.slice(); // otherwise we sort the original array... vals.sort(exports.sorterAsc); // undefined listed in the end - also works on IE11 @@ -73,9 +71,7 @@ exports.distinctVals = function(valsIn, opts) { if(vals[last] !== BADNUM) break; } - var minDiff = 1; - if(!unitMinDiff) minDiff = (vals[last] - vals[0]) || 1; - + var minDiff = (vals[last] - vals[0]) || 1; var errDiff = minDiff / (last || 1) / 10000; var newVals = []; var preV; diff --git a/src/traces/bar/cross_trace_calc.js b/src/traces/bar/cross_trace_calc.js index 00e14812244..f1cad80924d 100644 --- a/src/traces/bar/cross_trace_calc.js +++ b/src/traces/bar/cross_trace_calc.js @@ -172,7 +172,7 @@ function setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) { var calcTrace = calcTraces[i]; var sieve = new Sieve([calcTrace], { - unitMinDiff: opts.xCat || opts.yCat, + posAxis: pa, sepNegVal: false, overlapNoMerge: !opts.norm }); @@ -196,6 +196,7 @@ function setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) { function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces, opts) { var sieve = new Sieve(calcTraces, { + posAxis: pa, sepNegVal: false, overlapNoMerge: !opts.norm }); @@ -205,7 +206,7 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces, opts) { // relative-stack bars within the same trace that would otherwise // be hidden - unhideBarsWithinTrace(sieve); + unhideBarsWithinTrace(sieve, pa); // set bar bases and sizes, and update size axis if(opts.norm) { @@ -218,6 +219,7 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces, opts) { function setGroupPositionsInStackOrRelativeMode(gd, pa, sa, calcTraces, opts) { var sieve = new Sieve(calcTraces, { + posAxis: pa, sepNegVal: opts.mode === 'relative', overlapNoMerge: !(opts.norm || opts.mode === 'stack' || opts.mode === 'relative') }); @@ -610,7 +612,7 @@ function sieveBars(sieve) { } } -function unhideBarsWithinTrace(sieve) { +function unhideBarsWithinTrace(sieve, pa) { var calcTraces = sieve.traces; for(var i = 0; i < calcTraces.length; i++) { @@ -619,6 +621,7 @@ function unhideBarsWithinTrace(sieve) { if(fullTrace.base === undefined) { var inTraceSieve = new Sieve([calcTrace], { + posAxis: pa, sepNegVal: true, overlapNoMerge: true }); diff --git a/src/traces/bar/sieve.js b/src/traces/bar/sieve.js index 14e994f34a1..75b48a7f223 100644 --- a/src/traces/bar/sieve.js +++ b/src/traces/bar/sieve.js @@ -40,14 +40,17 @@ function Sieve(traces, opts) { } this.positions = positions; - var dv = distinctVals(positions, { - unitMinDiff: opts.unitMinDiff - }); + var dv = distinctVals(positions); this.distinctPositions = dv.vals; if(dv.vals.length === 1 && width1 !== Infinity) this.minDiff = width1; else this.minDiff = Math.min(dv.minDiff, width1); + var type = (opts.posAxis || {}).type; + if(type === 'category' || type === 'multicategory') { + this.minDiff = Math.min(1, this.minDiff); + } + this.binWidth = this.minDiff; this.bins = {}; diff --git a/src/traces/box/calc.js b/src/traces/box/calc.js index f08e80f8713..2b810f07679 100644 --- a/src/traces/box/calc.js +++ b/src/traces/box/calc.js @@ -40,7 +40,7 @@ module.exports = function calc(gd, trace) { var allPosArrays = getPosArrays(trace, posLetter, posAxis, fullLayout[numKey]); var posArray = allPosArrays[0]; var origPos = allPosArrays[1]; - var dv = Lib.distinctVals(posArray); + var dv = Lib.distinctVals(posArray, posAxis); var posDistinct = dv.vals; var dPos = dv.minDiff / 2; diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index 34eb60528ac..c95a81ae7e1 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -60,9 +60,10 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { if(!pointList.length) return; // box plots - update dPos based on multiple traces - var boxdv = Lib.distinctVals(pointList, { - unitMinDiff: posAxis.type === 'category' || posAxis.type === 'multicategory' - }); + var boxdv = Lib.distinctVals(pointList); + if(posAxis.type === 'category' || posAxis.type === 'multicategory') { + boxdv.minDiff = Math.min(1, boxdv.minDiff); + } var dPos0 = boxdv.minDiff / 2; From 7aecfb2c221b2f03ded43a0b0e897fc72a9ccd1b Mon Sep 17 00:00:00 2001 From: archmoj Date: Tue, 15 Jun 2021 18:04:35 -0400 Subject: [PATCH 2/4] add jasmine test to lock issue 5731 --- test/jasmine/tests/bar_test.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/jasmine/tests/bar_test.js b/test/jasmine/tests/bar_test.js index 62d74d99d71..3379549953c 100644 --- a/test/jasmine/tests/bar_test.js +++ b/test/jasmine/tests/bar_test.js @@ -981,12 +981,10 @@ describe('Bar.crossTraceCalc (formerly known as setPositions)', function() { it('should set unit width for categories in overlay mode', function() { var gd = mockBarPlot([{ - type: 'bar', x: ['a', 'b', 'c'], y: [2, 2, 2] }, { - type: 'bar', x: ['a', 'c'], y: [1, 1] }], { @@ -996,6 +994,20 @@ describe('Bar.crossTraceCalc (formerly known as setPositions)', function() { expect(gd.calcdata[1][0].t.bardelta).toBe(1); }); + it('should set unit width for categories case of missing data for defined category', function() { + var gd = mockBarPlot([{ + x: ['a', 'c'], + y: [1, 2] + }, { + x: ['a', 'c'], + y: [1, 2], + }], { + xaxis: { categoryarray: ['a', 'b', 'c'] } + }); + + expect(gd.calcdata[1][0].t.bardelta).toBe(1); + }); + describe('should relative-stack bar within the same trace that overlap under barmode=group', function() { it('- base case', function() { var gd = mockBarPlot([{ From 6e6bfa693492867bd9a4c35d2ff75a6755fede8c Mon Sep 17 00:00:00 2001 From: archmoj Date: Wed, 16 Jun 2021 13:48:22 -0400 Subject: [PATCH 3/4] set minDiff for category axes to one --- src/traces/bar/sieve.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traces/bar/sieve.js b/src/traces/bar/sieve.js index 75b48a7f223..ad7eec482f8 100644 --- a/src/traces/bar/sieve.js +++ b/src/traces/bar/sieve.js @@ -48,7 +48,7 @@ function Sieve(traces, opts) { var type = (opts.posAxis || {}).type; if(type === 'category' || type === 'multicategory') { - this.minDiff = Math.min(1, this.minDiff); + this.minDiff = 1; } this.binWidth = this.minDiff; From 42a74c46581061ef51f193898d4ba631d097b21d Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi <33888540+archmoj@users.noreply.github.com> Date: Thu, 17 Jun 2021 11:50:20 -0400 Subject: [PATCH 4/4] Update src/traces/box/cross_trace_calc.js Co-authored-by: Alex Johnson --- src/traces/box/cross_trace_calc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traces/box/cross_trace_calc.js b/src/traces/box/cross_trace_calc.js index c95a81ae7e1..00632d0dbb2 100644 --- a/src/traces/box/cross_trace_calc.js +++ b/src/traces/box/cross_trace_calc.js @@ -62,7 +62,7 @@ function setPositionOffset(traceType, gd, boxList, posAxis) { // box plots - update dPos based on multiple traces var boxdv = Lib.distinctVals(pointList); if(posAxis.type === 'category' || posAxis.type === 'multicategory') { - boxdv.minDiff = Math.min(1, boxdv.minDiff); + boxdv.minDiff = 1; } var dPos0 = boxdv.minDiff / 2;