Skip to content

Commit

Permalink
Correct decimation plugin documentation (#8801)
Browse files Browse the repository at this point in the history
* Correct decimation plugin documentation

* The default for decimation is `false`.
* Added a sample for data decimation
* Corrected an issue in the decimation plugin when switched from enabled to disabled
  • Loading branch information
etimberg committed Apr 3, 2021
1 parent 238bfa5 commit bdfaa44
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 9 deletions.
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Expand Up @@ -208,6 +208,7 @@ module.exports = {
{
title: 'Advanced',
children: [
'advanced/data-decimation',
'advanced/progress-bar',
'advanced/radial-gradient',
'advanced/linear-gradient',
Expand Down
6 changes: 5 additions & 1 deletion docs/configuration/decimation.md
Expand Up @@ -8,7 +8,7 @@ Namespace: `options.plugins.decimation`, the global options for the plugin are d

| Name | Type | Default | Description
| ---- | ---- | ------- | -----------
| `enabled` | `boolean` | `true` | Is decimation enabled?
| `enabled` | `boolean` | `false` | Is decimation enabled?
| `algorithm` | `string` | `'min-max'` | Decimation algorithm to use. See the [more...](#decimation-algorithms)
| `samples` | `number` | | If the `'lttb'` algorithm is used, this is the number of samples in the output dataset. Defaults to the canvas width to pick 1 sample per pixel.

Expand All @@ -35,3 +35,7 @@ To use the decimation plugin, the following requirements must be met:
2. The dataset must be a line
3. The X axis for the dataset must be either a `'linear'` or `'time'` type axis
4. The dataset object must be mutable. The plugin stores the original data as `dataset._data` and then defines a new `data` property on the dataset.

## Related Samples

* [Data Decimation Sample](../samples/advanced/data-decimation)
113 changes: 113 additions & 0 deletions docs/samples/advanced/data-decimation.md
@@ -0,0 +1,113 @@
# Data Decimation

This example shows how to use the built-in data decimation to reduce the number of points drawn on the graph for improved performance.

```js chart-editor
// <block:actions:3>
const actions = [
{
name: 'No decimation (default)',
handler(chart) {
chart.options.plugins.decimation.enabled = false;
chart.update();
}
},
{
name: 'min-max decimation',
handler(chart) {
chart.options.plugins.decimation.algorithm = 'min-max';
chart.options.plugins.decimation.enabled = true;
chart.update();
},
},
{
name: 'LTTB decimation (50 samples)',
handler(chart) {
chart.options.plugins.decimation.algorithm = 'lttb';
chart.options.plugins.decimation.enabled = true;
chart.options.plugins.decimation.samples = 50;
chart.update();
}
},
{
name: 'LTTB decimation (500 samples)',
handler(chart) {
chart.options.plugins.decimation.algorithm = 'lttb';
chart.options.plugins.decimation.enabled = true;
chart.options.plugins.decimation.samples = 500;
chart.update();
}
}
];
// </block:actions>

// <block:data:1>
const NUM_POINTS = 100000;
Utils.srand(10);

// parseISODate returns a luxon date object to work with in the samples
// We will create points every 30s starting from this point in time
const start = Utils.parseISODate('2021-04-01T00:00:00Z').toMillis();
const pointData = [];

for (let i = 0; i < NUM_POINTS; ++i) {
// Most data will be in the range [0, 20) but some rare data will be in the range [0, 100)
const max = Math.random() < 0.001 ? 100 : 20;
pointData.push({x: start + (i * 30000), y: Utils.rand(0, max)});
}

const data = {
datasets: [{
borderColor: Utils.CHART_COLORS.red,
borderWidth: 1,
data: pointData,
label: 'Large Dataset',
radius: 0,
}]
};
// </block:data>

// <block:decimation:0>
const decimation = {
enabled: false,
algorithm: 'min-max',
};
// </block:decimation>

// <block:setup:2>
const config = {
type: 'line',
data: data,
options: {
// Turn off animations and data parsing for performance
animation: false,
parsing: false,

interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
plugins: {
decimation: decimation,
},
scales: {
x: {
type: 'time',
ticks: {
source: 'auto',
// Disabled rotation for performance
maxRotation: 0,
autoSkip: true,
}
}
}
}
};
// </block:setup>

module.exports = {
actions: actions,
config: config,
};
```
4 changes: 4 additions & 0 deletions docs/scripts/utils.js
Expand Up @@ -155,3 +155,7 @@ export function newDate(days) {
export function newDateString(days) {
return DateTime.now().plus({days}).toISO();
}

export function parseISODate(str) {
return DateTime.fromISO(str);
}
22 changes: 14 additions & 8 deletions src/plugins/plugin.decimation.js
Expand Up @@ -141,6 +141,17 @@ function minMaxDecimation(data, availableWidth) {
return decimated;
}

function cleanDecimatedData(chart) {
chart.data.datasets.forEach((dataset) => {
if (dataset._decimated) {
const data = dataset._data;
delete dataset._decimated;
delete dataset._data;
Object.defineProperty(dataset, 'data', {value: data});
}
});
}

export default {
id: 'decimation',

Expand All @@ -151,6 +162,8 @@ export default {

beforeElementsUpdate: (chart, args, options) => {
if (!options.enabled) {
// The decimation plugin may have been previously enabled. Need to remove old `dataset._data` handlers
cleanDecimatedData(chart);
return;
}

Expand Down Expand Up @@ -224,13 +237,6 @@ export default {
},

destroy(chart) {
chart.data.datasets.forEach((dataset) => {
if (dataset._decimated) {
const data = dataset._data;
delete dataset._decimated;
delete dataset._data;
Object.defineProperty(dataset, 'data', {value: data});
}
});
cleanDecimatedData(chart);
}
};

0 comments on commit bdfaa44

Please sign in to comment.