Skip to content

Commit

Permalink
Bugfix: span gaps over null values beyond scale limits (#11984)
Browse files Browse the repository at this point in the history
* Bugfix: spanGaps not working near min and max limits

* Fix error when meta.dataset.options = null

* Add tests for correct setting of line controller properties _drawStart and _drawCount

* Fix spacing in controller line tests

* Add tension to test

* Add a better test case

* Avoid the use of FindLastIndex

* Avoid taking 0 for null value and improve naming
  • Loading branch information
marisst authored Jan 3, 2025
1 parent 57b5c5b commit 1e3d6e5
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 7 deletions.
30 changes: 23 additions & 7 deletions src/helpers/helpers.extras.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,25 +91,41 @@ export function _getStartAndCountOfVisiblePoints(meta: ChartMeta<'line' | 'scatt
let count = pointCount;

if (meta._sorted) {
const {iScale, _parsed} = meta;
const {iScale, vScale, _parsed} = meta;
const spanGaps = meta.dataset ? meta.dataset.options ? meta.dataset.options.spanGaps : null : null;
const axis = iScale.axis;
const {min, max, minDefined, maxDefined} = iScale.getUserBounds();

if (minDefined) {
start = _limitValue(Math.min(
start = Math.min(
// @ts-expect-error Need to type _parsed
_lookupByKey(_parsed, axis, min).lo,
// @ts-expect-error Need to fix types on _lookupByKey
animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo),
0, pointCount - 1);
animationsDisabled ? pointCount : _lookupByKey(points, axis, iScale.getPixelForValue(min)).lo);
if (spanGaps) {
const distanceToDefinedLo = (_parsed
.slice(0, start + 1)
.reverse()
.findIndex(
point => point[vScale.axis] || point[vScale.axis] === 0));
start -= Math.max(0, distanceToDefinedLo);
}
start = _limitValue(start, 0, pointCount - 1);
}
if (maxDefined) {
count = _limitValue(Math.max(
let end = Math.max(
// @ts-expect-error Need to type _parsed
_lookupByKey(_parsed, iScale.axis, max, true).hi + 1,
// @ts-expect-error Need to fix types on _lookupByKey
animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1),
start, pointCount) - start;
animationsDisabled ? 0 : _lookupByKey(points, axis, iScale.getPixelForValue(max), true).hi + 1);
if (spanGaps) {
const distanceToDefinedHi = (_parsed
.slice(end - 1)
.findIndex(
point => point[vScale.axis] || point[vScale.axis] === 0));
end += Math.max(0, distanceToDefinedHi);
}
count = _limitValue(end, start, pointCount) - start;
} else {
count = pointCount - start;
}
Expand Down
87 changes: 87 additions & 0 deletions test/specs/controller.line.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,93 @@ describe('Chart.controllers.line', function() {
expect(visiblePoints.length).toBe(6);
}, 500);

it('should correctly calc _drawStart and _drawCount when first points beyond scale limits are null and spanGaps=true', async() => {
var chart = window.acquireChart({
type: 'line',
data: {
labels: [0, 10, 20, 30, 40, 50],
datasets: [{
data: [3, null, 2, 3, null, 1.5],
spanGaps: true,
tension: 0.4
}]
},
options: {
scales: {
x: {
type: 'linear',
min: 11,
max: 40,
}
}
}
});

chart.update();
var controller = chart.getDatasetMeta(0).controller;

expect(controller._drawStart).toBe(0);
expect(controller._drawCount).toBe(6);
}, 500);

it('should correctly calc _drawStart and _drawCount when all points beyond scale limits are null and spanGaps=true', async() => {
var chart = window.acquireChart({
type: 'line',
data: {
labels: [0, 10, 20, 30, 40, 50],
datasets: [{
data: [null, null, 2, 3, null, null],
spanGaps: true,
tension: 0.4
}]
},
options: {
scales: {
x: {
type: 'linear',
min: 11,
max: 40,
}
}
}
});

chart.update();
var controller = chart.getDatasetMeta(0).controller;

expect(controller._drawStart).toBe(1);
expect(controller._drawCount).toBe(4);
}, 500);

it('should correctly calc _drawStart and _drawCount when spanGaps=false', async() => {
var chart = window.acquireChart({
type: 'line',
data: {
labels: [0, 10, 20, 30, 40, 50],
datasets: [{
data: [3, null, 2, 3, null, 1.5],
spanGaps: false,
tension: 0.4
}]
},
options: {
scales: {
x: {
type: 'linear',
min: 11,
max: 40,
}
}
}
});

chart.update();
var controller = chart.getDatasetMeta(0).controller;

expect(controller._drawStart).toBe(1);
expect(controller._drawCount).toBe(4);
}, 500);

it('should not override tooltip title and label callbacks', async() => {
const chart = window.acquireChart({
type: 'line',
Expand Down

0 comments on commit 1e3d6e5

Please sign in to comment.