8000 Unhide overlapping grouped bars within trace by etpinard · Pull Request #3680 · plotly/plotly.js · GitHub
[go: up one dir, main page]

Skip to content

Unhide overlapping grouped bars within trace 8000 #3680

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 28, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
relative-stack bars within the same trace that would otherwise be hidden
... under barmode:'group'
  • Loading branch information
etpinard committed Mar 25, 2019
commit 8a5c655cc2bdfedca5e6d74c3e0b4b87e3e22aff
34 changes: 34 additions & 0 deletions src/traces/bar/cross_trace_calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ function setGroupPositionsInGroupMode(gd, pa, sa, calcTraces) {
// set bar offsets and widths, and update position axis
setOffsetAndWidthInGroupMode(gd, pa, sieve);

// relative-stack bars within the same trace that would otherwise
// be hidden
unhideBarsWithinTrace(gd, sa, sieve);

// set bar bases and sizes, and update size axis
if(barnorm) {
sieveBars(gd, sa, sieve);
Expand Down Expand Up @@ -578,6 +582,36 @@ function sieveBars(gd, sa, sieve) {
}
}

function unhideBarsWithinTrace(gd, sa, sieve) {
var calcTraces = sieve.traces;

for(var i = 0; i < calcTraces.length; i++) {
var calcTrace = calcTraces[i];
var fullTrace = calcTrace[0].trace;

if(fullTrace.base === undefined) {
var inTraceSieve = new Sieve([calcTrace], {
separateNegativeValues: true,
dontMergeOverlappingData: true
});

for(var j = 0; j < calcTrace.length; j++) {
var bar = calcTrace[j];

if(bar.p !== BADNUM) {
// stack current bar and get previous sum
var barBase = inTraceSieve.put(bar.p, bar.b + bar.s);

// if previous sum if non-zero, this means:
// multiple bars have same starting point are potentially hidden,
// shift them vertically so that all bars are visible by default
if(barBase) bar.b = barBase;
}
}
}
}
}

// Note:
//
// normalizeBars requires that either sieveBars or stackBars has been
Expand Down
Binary file added test/image/baselines/bar_unhidden.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions test/image/mocks/bar_unhidden.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"data": [
{
"type": "bar",
"x": [ 0, 0, 0 ],
"y": [ 1, 1, -1 ],
"marker": {
"color": [ "red", "green", "blue" ]
}
},
{
"type": "bar",
"x": [ 0, 0, 0 ],
"y": [ 1, 1, -1 ],
"marker": {
"color": [ "cyan", "magenta", "yellow" ]
}
}
],
"layout": {
"margin": { "t": 30, "b": 30, "l": 30, "r": 30 },
"width": 400,
"height": 400,
"showlegend": false,
"hovermode": "closest"
}
}
61 changes: 61 additions & 0 deletions test/jasmine/tests/bar_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,67 @@ describe('Bar.crossTraceCalc (formerly known as setPositions)', function() {
expect(gd._fullLayout.xaxis.type).toBe('multicategory');
assertPointField(gd.calcdata, 'b', [[0, 0, 0, 0]]);
});

describe('should relative-stack bar within the same trace that overlap under barmode=group', function() {
it('- base case', function() {
var gd = mockBarPlot([{
x: [0, 0, 0],
y: [1, -2, -1]
}]);

assertPointField(gd.calcdata, 'b', [[0, 0, -2]]);
assertPointField(gd.calcdata, 'y', [[1, -2, -3]]);
});

it('- with blank positions', function() {
var gd = mockBarPlot([{
x: [0, null, 0, null, 0],
y: [1, null, -2, null, -1]
}]);

assertPointField(gd.calcdata, 'b', [[0, 0, 0, 0, -2]]);
assertPointField(gd.calcdata, 'y', [[1, NaN, -2, NaN, -3]]);
});

it('- with barnorm set', function() {
var gd = mockBarPlot([{
x: [0, 0, 0],
y: [1, -2, -1],
}], {
barnorm: 'fraction'
});

assertPointField(gd.calcdata, 'b', [[0, 0, -0.5]]);
assertPointField(gd.calcdata, 'y', [[0.25, -0.5, -0.75]]);
});

it('- skipped when base is set', function() {
var gd = mockBarPlot([{
x: [0, 0, 0],
y: [1, -2, -1],
base: 10
}, {
x: [0, 0, 0],
y: [1, -2, -1],
base: [1, 2, 1]
}]);

assertPointField(gd.calcdata, 'b', [[10, 10, 10], [1, 2, 1]]);
assertPointField(gd.calcdata, 'y', [[11, 8, 9], [2, 0, 0]]);
});

it('- skipped when barmode=overlay', function() {
var gd = mockBarPlot([{
x: [0, 0, 0],
y: [1, -2, -1]
}], {
barmode: 'overlay'
});

assertPointField(gd.calcdata, 'b', [[0, 0, 0]]);
assertPointField(gd.calcdata, 'y', [[1, -2, -1]]);
});
});
});

describe('A bar plot', function() {
Expand Down
0