Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correct decimation plugin documentation #8801

Merged
merged 2 commits into from Apr 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);
}
};