in Hands-on lab/lab-files/starter-project/NorthwindMVC/wwwroot/lib/Chart.js/chart.js [9455:9500]
function lttbDecimation(data, start, count, availableWidth, options) {
const samples = options.samples || availableWidth;
if (samples >= count) {
return data.slice(start, start + count);
}
const decimated = [];
const bucketWidth = (count - 2) / (samples - 2);
let sampledIndex = 0;
const endIndex = start + count - 1;
let a = start;
let i, maxAreaPoint, maxArea, area, nextA;
decimated[sampledIndex++] = data[a];
for (i = 0; i < samples - 2; i++) {
let avgX = 0;
let avgY = 0;
let j;
const avgRangeStart = Math.floor((i + 1) * bucketWidth) + 1 + start;
const avgRangeEnd = Math.min(Math.floor((i + 2) * bucketWidth) + 1, count) + start;
const avgRangeLength = avgRangeEnd - avgRangeStart;
for (j = avgRangeStart; j < avgRangeEnd; j++) {
avgX += data[j].x;
avgY += data[j].y;
}
avgX /= avgRangeLength;
avgY /= avgRangeLength;
const rangeOffs = Math.floor(i * bucketWidth) + 1 + start;
const rangeTo = Math.min(Math.floor((i + 1) * bucketWidth) + 1, count) + start;
const {x: pointAx, y: pointAy} = data[a];
maxArea = area = -1;
for (j = rangeOffs; j < rangeTo; j++) {
area = 0.5 * Math.abs(
(pointAx - avgX) * (data[j].y - pointAy) -
(pointAx - data[j].x) * (avgY - pointAy)
);
if (area > maxArea) {
maxArea = area;
maxAreaPoint = data[j];
nextA = j;
}
}
decimated[sampledIndex++] = maxAreaPoint;
a = nextA;
}
decimated[sampledIndex++] = data[endIndex];
return decimated;
}