Skip to content

Commit 0699f9b

Browse files
etimbergEvert Timberg
authored andcommitted
Refactor the decimation plugin to support configurable algorithms
1 parent d5b202e commit 0699f9b

File tree

1 file changed

+55
-37
lines changed

1 file changed

+55
-37
lines changed

src/plugins/plugin.decimation.js

Lines changed: 55 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,55 @@
11
import {isNullOrUndef} from '../helpers';
22

3+
function minMaxDecimation(data, availableWidth) {
4+
let i, point, x, y, prevX, minIndex, maxIndex, minY, maxY;
5+
const decimated = [];
6+
7+
const xMin = data[0].x;
8+
const xMax = data[data.length - 1].x;
9+
const dx = xMax - xMin;
10+
11+
for (i = 0; i < data.length; ++i) {
12+
point = data[i];
13+
x = (point.x - xMin) / dx * availableWidth;
14+
y = point.y;
15+
const truncX = x | 0;
16+
17+
if (truncX === prevX) {
18+
// Determine `minY` / `maxY` and `avgX` while we stay within same x-position
19+
if (y < minY) {
20+
minY = y;
21+
minIndex = i;
22+
} else if (y > maxY) {
23+
maxY = y;
24+
maxIndex = i;
25+
}
26+
} else {
27+
// Push up to 4 points, 3 for the last interval and the first point for this interval
28+
if (minIndex && maxIndex) {
29+
decimated.push(data[minIndex], data[maxIndex]);
30+
}
31+
if (i > 0) {
32+
// Last point in the previous interval
33+
decimated.push(data[i - 1]);
34+
}
35+
decimated.push(point);
36+
prevX = truncX;
37+
minY = maxY = y;
38+
minIndex = maxIndex = i;
39+
}
40+
}
41+
42+
return decimated;
43+
}
44+
345
export default {
446
id: 'decimation',
547

48+
defaults: {
49+
algorithm: 'min-max',
50+
enabled: false,
51+
},
52+
653
beforeElementsUpdate: (chart, args, options) => {
754
if (!options.enabled) {
855
return;
@@ -16,7 +63,6 @@ export default {
1663
const availableWidth = chart.width - (verticalAxisCount * 50);
1764

1865
chart.data.datasets.forEach((dataset, datasetIndex) => {
19-
let i, point, x, y, prevX, minIndex, maxIndex, minY, maxY;
2066
const {_originalDataKey} = dataset;
2167
const meta = chart.getDatasetMeta(datasetIndex);
2268
const dataKey = !isNullOrUndef(_originalDataKey) ? _originalDataKey : meta.controller.getDataKey();
@@ -48,44 +94,16 @@ export default {
4894
return;
4995
}
5096

51-
const decimated = [];
52-
53-
const xMin = data[0].x;
54-
const xMax = data[data.length - 1].x;
55-
const dx = xMax - xMin;
56-
57-
for (i = 0; i < data.length; ++i) {
58-
point = data[i];
59-
x = (point.x - xMin) / dx * availableWidth;
60-
y = point.y;
61-
const truncX = x | 0;
62-
63-
if (truncX === prevX) {
64-
// Determine `minY` / `maxY` and `avgX` while we stay within same x-position
65-
if (y < minY) {
66-
minY = y;
67-
minIndex = i;
68-
} else if (y > maxY) {
69-
maxY = y;
70-
maxIndex = i;
71-
}
72-
} else {
73-
// Push up to 4 points, 3 for the last interval and the first point for this interval
74-
if (minIndex && maxIndex) {
75-
decimated.push(data[minIndex], data[maxIndex]);
76-
}
77-
if (i > 0) {
78-
// Last point in the previous interval
79-
decimated.push(data[i - 1]);
80-
}
81-
decimated.push(point);
82-
prevX = truncX;
83-
minY = maxY = y;
84-
minIndex = maxIndex = i;
85-
}
97+
// Point the chart to the decimated data
98+
let decimated;
99+
switch (options.algorithm) {
100+
case 'min-max':
101+
decimated = minMaxDecimation(data, availableWidth);
102+
break;
103+
default:
104+
throw new Error(`Unsupported decimation algorithm '${options.algorithm}'`);
86105
}
87106

88-
// Point the chart to the decimated data
89107
dataset._decimated = decimated;
90108
dataset.dataKey = '_decimated';
91109
});

0 commit comments

Comments
 (0)