Skip to content

Commit

Permalink
Merge pull request #5072 from plotly/fix5058-overlay-missing-category
Browse files Browse the repository at this point in the history
Set width of categorical bars & boxes to category unit i.e. 1
  • Loading branch information
archmoj authored Aug 18, 2020
2 parents eae3bda + 081cb77 commit 3781f48
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 4 deletions.
8 changes: 6 additions & 2 deletions src/lib/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ 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) {
exports.distinctVals = function(valsIn, opts) {
var unitMinDiff = (opts || {}).unitMinDiff;

var vals = valsIn.slice(); // otherwise we sort the original array...
vals.sort(exports.sorterAsc); // undefined listed in the end - also works on IE11

Expand All @@ -80,7 +82,9 @@ exports.distinctVals = function(valsIn) {
if(vals[last] !== BADNUM) break;
}

var minDiff = (vals[last] - vals[0]) || 1;
var minDiff = 1;
if(!unitMinDiff) minDiff = (vals[last] - vals[0]) || 1;

var errDiff = minDiff / (last || 1) / 10000;
var newVals = [];
var preV;
Expand Down
4 changes: 4 additions & 0 deletions src/traces/bar/cross_trace_calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ function crossTraceCalc(gd, plotinfo) {
}

var opts = {
xCat: xa.type === 'category' || xa.type === 'multicategory',
yCat: ya.type === 'category' || ya.type === 'multicategory',

mode: fullLayout.barmode,
norm: fullLayout.barnorm,
gap: fullLayout.bargap,
Expand Down Expand Up @@ -177,6 +180,7 @@ function setGroupPositionsInOverlayMode(pa, sa, calcTraces, opts) {
var calcTrace = calcTraces[i];

var sieve = new Sieve([calcTrace], {
unitMinDiff: opts.xCat || opts.yCat,
sepNegVal: false,
overlapNoMerge: !opts.norm
});
Expand Down
5 changes: 4 additions & 1 deletion src/traces/bar/sieve.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ function Sieve(traces, opts) {
}
this.positions = positions;

var dv = distinctVals(positions);
var dv = distinctVals(positions, {
unitMinDiff: opts.unitMinDiff
});

this.distinctPositions = dv.vals;
if(dv.vals.length === 1 && width1 !== Infinity) this.minDiff = width1;
else this.minDiff = Math.min(dv.minDiff, width1);
Expand Down
5 changes: 4 additions & 1 deletion src/traces/box/cross_trace_calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ function setPositionOffset(traceType, gd, boxList, posAxis) {
if(!pointList.length) return;

// box plots - update dPos based on multiple traces
var boxdv = Lib.distinctVals(pointList);
var boxdv = Lib.distinctVals(pointList, {
unitMinDiff: posAxis.type === 'category' || posAxis.type === 'multicategory'
});

var dPos0 = boxdv.minDiff / 2;

// check for forced minimum dtick
Expand Down
17 changes: 17 additions & 0 deletions test/jasmine/tests/bar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,23 @@ describe('Bar.crossTraceCalc (formerly known as setPositions)', function() {
assertPointField(gd.calcdata, 'b', [[0, 0, 0, 0]]);
});

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]
}], {
barmode: 'overlay'
});

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([{
Expand Down
48 changes: 48 additions & 0 deletions test/jasmine/tests/box_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1534,3 +1534,51 @@ describe('Test box calc', function() {
});
});
});


describe('Box crossTraceCalc', function() {
'use strict';

function mockBoxPlot(dataWithoutTraceType, layout) {
var traceTemplate = { type: 'box' };

var dataWithTraceType = dataWithoutTraceType.map(function(trace) {
return Lib.extendFlat({}, traceTemplate, trace);
});

var gd = {
data: dataWithTraceType,
layout: layout || {},
calcdata: [],
_context: {locale: 'en', locales: {}}
};

supplyAllDefaults(gd);
Plots.doCalcdata(gd);

return gd;
}

it('should set unit width for categories in overlay mode', function() {
var gd = mockBoxPlot([{
y: [1, 2, 3]
},
{
y: [null, null, null]
},
{
y: [null, null, null]
},
{
y: [4, 5, 6]
}], {
boxgap: 0,
xaxis: {
range: [-0.5, 3.5],
type: 'category'
}
});

expect(gd.calcdata[0][0].t.dPos).toBe(0.5);
});
});

0 comments on commit 3781f48

Please sign in to comment.