Skip to content

Commit bc8385e

Browse files
authored
Fix layout refit logic (#8567)
* Fix layout refit logic * CC * Update fixture
1 parent 24b1419 commit bc8385e

File tree

7 files changed

+89
-21
lines changed

7 files changed

+89
-21
lines changed

src/core/core.layouts.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ function setLayoutDims(layouts, params) {
6060

6161
function buildLayoutBoxes(boxes) {
6262
const layoutBoxes = wrapBoxes(boxes);
63+
const fullSize = sortByWeight(layoutBoxes.filter(wrap => wrap.box.fullSize), true);
6364
const left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);
6465
const right = sortByWeight(filterByPosition(layoutBoxes, 'right'));
6566
const top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);
@@ -68,6 +69,7 @@ function buildLayoutBoxes(boxes) {
6869
const centerVertical = filterDynamicPositionByAxis(layoutBoxes, 'y');
6970

7071
return {
72+
fullSize,
7173
leftAndTop: left.concat(top),
7274
rightAndBottom: right.concat(centerVertical).concat(bottom).concat(centerHorizontal),
7375
chartArea: filterByPosition(layoutBoxes, 'chartArea'),
@@ -80,13 +82,20 @@ function getCombinedMax(maxPadding, chartArea, a, b) {
8082
return Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);
8183
}
8284

85+
function updateMaxPadding(maxPadding, boxPadding) {
86+
maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
87+
maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
88+
maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
89+
maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
90+
}
91+
8392
function updateDims(chartArea, params, layout) {
8493
const box = layout.box;
8594
const maxPadding = chartArea.maxPadding;
8695

8796
if (isObject(layout.pos)) {
8897
// dynamically placed boxes are not considered
89-
return;
98+
return {same: false, other: false};
9099
}
91100
if (layout.size) {
92101
// this layout was already counted for, lets first reduce old size
@@ -96,23 +105,23 @@ function updateDims(chartArea, params, layout) {
96105
chartArea[layout.pos] += layout.size;
97106

98107
if (box.getPadding) {
99-
const boxPadding = box.getPadding();
100-
maxPadding.top = Math.max(maxPadding.top, boxPadding.top);
101-
maxPadding.left = Math.max(maxPadding.left, boxPadding.left);
102-
maxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);
103-
maxPadding.right = Math.max(maxPadding.right, boxPadding.right);
108+
updateMaxPadding(maxPadding, box.getPadding());
104109
}
105110

106111
const newWidth = Math.max(0, params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right'));
107112
const newHeight = Math.max(0, params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom'));
108113

109-
if (newWidth !== chartArea.w || newHeight !== chartArea.h) {
114+
const widthChanged = newWidth !== chartArea.w;
115+
const heightChanged = newHeight !== chartArea.h;
116+
if (widthChanged || heightChanged) {
110117
chartArea.w = newWidth;
111118
chartArea.h = newHeight;
112-
113-
// return true if chart area changed in layout's direction
114-
return layout.horizontal ? newWidth !== chartArea.w : newHeight !== chartArea.h;
115119
}
120+
121+
// return booleans on the changes per direction
122+
return layout.horizontal
123+
? {same: widthChanged, other: heightChanged}
124+
: {same: heightChanged, other: widthChanged};
116125
}
117126

118127
function handleMaxPadding(chartArea) {
@@ -158,13 +167,15 @@ function fitBoxes(boxes, chartArea, params) {
158167
layout.height || chartArea.h,
159168
getMargins(layout.horizontal, chartArea)
160169
);
161-
if (updateDims(chartArea, params, layout)) {
170+
const {same, other} = updateDims(chartArea, params, layout);
171+
if (same && refitBoxes.length) {
172+
// Dimensions changed and there were non full width boxes before this
173+
// -> we have to refit those
174+
refit = true;
175+
}
176+
if (other) {
177+
// Chart area changed in the opposite direction
162178
changed = true;
163-
if (refitBoxes.length) {
164-
// Dimensions changed and there were non full width boxes before this
165-
// -> we have to refit those
166-
refit = true;
167-
}
168179
}
169180
if (!box.fullSize) { // fullSize boxes don't need to be re-fitted in any case
170181
refitBoxes.push(layout);
@@ -365,7 +376,10 @@ export default {
365376

366377
setLayoutDims(verticalBoxes.concat(horizontalBoxes), params);
367378

368-
// First fit vertical boxes
379+
// First fit the fullSize boxes, to reduce probability of re-fitting.
380+
fitBoxes(boxes.fullSize, chartArea, params);
381+
382+
// Then fit vertical boxes
369383
fitBoxes(verticalBoxes, chartArea, params);
370384

371385
// Then fit horizontal boxes

src/core/core.scale.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import defaults from './core.defaults';
22
import Element from './core.element';
33
import {_alignPixel, _measureText, renderText, clipArea, unclipArea} from '../helpers/helpers.canvas';
44
import {callback as call, each, finiteOrDefault, isArray, isFinite, isNullOrUndef, isObject, valueOrDefault} from '../helpers/helpers.core';
5-
import {_factorize, toDegrees, toRadians, _int16Range, HALF_PI} from '../helpers/helpers.math';
5+
import {_factorize, toDegrees, toRadians, _int16Range, HALF_PI, _limitValue} from '../helpers/helpers.math';
66
import {toFont, toPadding} from '../helpers/helpers.options';
77
import Ticks from './core.ticks';
88

@@ -734,7 +734,7 @@ export default class Scale extends Element {
734734

735735
// Estimate the width of each grid based on the canvas width, the maximum
736736
// label width and the number of tick intervals
737-
const maxWidth = Math.min(me.maxWidth, me.chart.width - maxLabelWidth);
737+
const maxWidth = _limitValue(me.chart.width - maxLabelWidth, 0, me.maxWidth);
738738
tickWidth = options.offset ? me.maxWidth / numTicks : maxWidth / (numTicks - 1);
739739

740740
// Allow 3 pixels x2 padding either side for label readability
-730 Bytes
Loading
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module.exports = {
2+
config: {
3+
type: 'line',
4+
data: {
5+
labels: [
6+
'Aaron',
7+
'Adam',
8+
'Albert',
9+
'Alex',
10+
'Allan',
11+
'Aman',
12+
'Anthony',
13+
'Autoenrolment',
14+
'Avril',
15+
'Bernard'
16+
],
17+
datasets: [{
18+
backgroundColor: 'rgba(252,233,79,0.5)',
19+
borderColor: 'rgba(252,233,79,1)',
20+
borderWidth: 1,
21+
data: [101,
22+
185,
23+
24,
24+
311,
25+
17,
26+
21,
27+
462,
28+
340,
29+
140,
30+
24
31+
]
32+
}]
33+
},
34+
options: {
35+
maintainAspectRatio: false,
36+
plugins: {
37+
legend: true,
38+
title: {
39+
display: true,
40+
text: 'test'
41+
}
42+
}
43+
}
44+
},
45+
options: {
46+
spriteText: true,
47+
canvas: {
48+
height: 185,
49+
width: 185
50+
}
51+
}
52+
};
12.8 KB
Loading
-1.54 KB
Loading

test/specs/core.controller.tests.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,14 +1430,16 @@ describe('Chart', function() {
14301430
update: [
14311431
'beforeUpdate',
14321432
'beforeLayout',
1433-
'beforeDataLimits',
1433+
'beforeDataLimits', // y-axis fit
14341434
'afterDataLimits',
14351435
'beforeBuildTicks',
14361436
'afterBuildTicks',
1437-
'beforeDataLimits',
1437+
'beforeDataLimits', // x-axis fit
14381438
'afterDataLimits',
14391439
'beforeBuildTicks',
14401440
'afterBuildTicks',
1441+
'beforeBuildTicks', // y-axis re-fit
1442+
'afterBuildTicks',
14411443
'afterLayout',
14421444
'beforeDatasetsUpdate',
14431445
'beforeDatasetUpdate',

0 commit comments

Comments
 (0)