From 7c3f07cb0231e225dac3444d380fa2ca777f3fd0 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Sat, 3 Apr 2021 12:49:16 -0400 Subject: [PATCH 1/2] 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 --- docs/.vuepress/config.js | 1 + docs/configuration/decimation.md | 6 +- docs/samples/advanced/data-decimation.md | 113 +++++++++++++++++++++++ docs/scripts/utils.js | 4 + src/plugins/plugin.decimation.js | 22 +++-- 5 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 docs/samples/advanced/data-decimation.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 6a5595cb5bc..701b23a8e35 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -208,6 +208,7 @@ module.exports = { { title: 'Advanced', children: [ + 'advanced/data-decimation', 'advanced/progress-bar', 'advanced/radial-gradient', 'advanced/linear-gradient', diff --git a/docs/configuration/decimation.md b/docs/configuration/decimation.md index 8e1ad1a3171..2b828fc8a58 100644 --- a/docs/configuration/decimation.md +++ b/docs/configuration/decimation.md @@ -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. @@ -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) diff --git a/docs/samples/advanced/data-decimation.md b/docs/samples/advanced/data-decimation.md new file mode 100644 index 00000000000..aef2c21dfb7 --- /dev/null +++ b/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 to improve performance. + +```js chart-editor +// +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(); + } + } +]; +// + +// +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, + }] +}; +// + +// +const decimation = { + enabled: false, + algorithm: 'min-max', +}; +// + +// +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, + } + } + } + } +}; +// + +module.exports = { + actions: actions, + config: config, +}; +``` diff --git a/docs/scripts/utils.js b/docs/scripts/utils.js index 772b27505f7..59a07d7ebe3 100644 --- a/docs/scripts/utils.js +++ b/docs/scripts/utils.js @@ -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); +} diff --git a/src/plugins/plugin.decimation.js b/src/plugins/plugin.decimation.js index d0204dc817d..988526413d1 100644 --- a/src/plugins/plugin.decimation.js +++ b/src/plugins/plugin.decimation.js @@ -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', @@ -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; } @@ -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); } }; From 2622789bcd43dc7327cc82f371afe0dff49e6e7d Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Sat, 3 Apr 2021 12:57:57 -0400 Subject: [PATCH 2/2] Language update --- docs/samples/advanced/data-decimation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/samples/advanced/data-decimation.md b/docs/samples/advanced/data-decimation.md index aef2c21dfb7..0d691990ae2 100644 --- a/docs/samples/advanced/data-decimation.md +++ b/docs/samples/advanced/data-decimation.md @@ -1,6 +1,6 @@ # Data Decimation -This example shows how to use the built-in data decimation to reduce the number of points drawn on the graph to improve performance. +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 //