Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions draftlogs/8090_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Fix directional axis automargins that discard anchor coordinates and clip labels [[#8090](https://github.com/plotly/plotly.js/pull/8090)]
5 changes: 3 additions & 2 deletions src/plots/cartesian/axes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3015,12 +3015,13 @@ axes.drawOne = function(gd, ax, opts) {
function filterPush(push, automargin) {
if(!push) return;

var keepMargin = Object.keys(MARGIN_MAPPING).reduce(function(data, nextKey) {
// Anchor coordinates locate enabled margin constraints. They do not enable margin growth.
const keepMargin = Object.keys(MARGIN_MAPPING).reduce((data, nextKey) => {
if(automargin.indexOf(nextKey) !== -1) {
MARGIN_MAPPING[nextKey].forEach(function(key) { data[key] = 1;});
}
return data;
}, {});
}, { x: 1, y: 1 });
Object.keys(push).forEach(function(key) {
if(!keepMargin[key]) {
if(key.length === 1) push[key] = 0;
Expand Down
67 changes: 67 additions & 0 deletions test/jasmine/tests/axes_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4687,6 +4687,73 @@ describe('Test axes', function() {
.then(done, done.fail);
});

['right', 'left', 'top', 'bottom'].forEach((side) => {
[false, true].forEach((free) => {
it(`preserves ${side} anchors for ${free ? 'free' : 'anchored'} partial automargin`, async () => {
const vertical = side === 'right' || side === 'left';
const axis = vertical ? 'yaxis' : 'xaxis';
const id = vertical ? 'y' : 'x';
const edge = side[0];
const fraction = side === 'right' || side === 'top' ? 1 : 0;
const layout = {
width: 500,
height: 300,
margin: { l: 0, r: 0, t: 0, b: 0 },
xaxis: { range: [0, 4], visible: !vertical },
yaxis: { range: [0, 4], visible: vertical }
};
layout[axis] = {
range: [0, 4],
side,
automargin: true,
tickvals: [1, 2, 3],
ticktext: ['Long label', 'Long label', 'Long label'],
tickangle: 0,
...(free ? { anchor: 'free', position: fraction } : {})
};
await Plotly.newPlot(gd, [{ x: [1, 2, 3], y: [1, 2, 3] }], layout);
const automatic = gd._fullLayout._size[edge];
expect(automatic).toBeGreaterThan(0);

for (const flag of [side, vertical ? 'width' : 'height']) {
await Plotly.relayout(gd, { [`${axis}.automargin`]: flag });
expect(gd._fullLayout._size[edge]).toBe(automatic);
expect(gd._fullLayout._pushmargin[`${id}.automargin`][edge].val).toBe(fraction);
for (const other of ['l', 'r', 't', 'b'].filter((value) => value !== edge)) {
expect(gd._fullLayout._size[other]).toBe(0);
}
}

await Plotly.relayout(gd, { [`${axis}.automargin`]: vertical ? 'height' : 'width' });
expect(gd._fullLayout._size[edge]).toBe(0);
await Plotly.relayout(gd, { [`${axis}.automargin`]: true });
expect(gd._fullLayout._size[edge]).toBe(automatic);
await Plotly.relayout(gd, { [`${axis}.automargin`]: false });
expect(gd._fullLayout._size[edge]).toBe(0);
});
});
});

it('keeps right-side labels inside the paper when left automargin is excluded', async () => {
await Plotly.newPlot(gd, [{ x: [0, 1, 2], y: [1000, 2000, 3000] }], {
width: 500,
height: 300,
margin: { l: 40, r: 0, t: 30, b: 40 },
yaxis: { side: 'right', automargin: 'right+top+bottom', tickformat: '.0f' }
});
const rightMargin = gd._fullLayout._size.r;
expect(rightMargin).toBeGreaterThan(0);
expect(gd._fullLayout._size.l).toBe(40);
const paper = gd.querySelector('.main-svg').getBoundingClientRect();
const labels = gd.querySelectorAll('.ytick text');
expect(labels.length).toBeGreaterThan(0);
labels.forEach((label) => {
expect(label.getBoundingClientRect().right).toBeLessThanOrEqual(paper.right + 0.5);
});
await Plotly.relayout(gd, { 'yaxis.automargin': true });
expect(gd._fullLayout._size.r).toBe(rightMargin);
});

it('should handle partial automargin', function(done) {
var initialSize;

Expand Down