]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Correct decimation plugin documentation (#8801)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sat, 3 Apr 2021 17:06:31 +0000 (13:06 -0400)
committerJukka Kurkela <jukka.kurkela@gmail.com>
Sun, 4 Apr 2021 11:51:06 +0000 (14:51 +0300)
* 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
docs/configuration/decimation.md
docs/samples/advanced/data-decimation.md [new file with mode: 0644]
docs/scripts/utils.js
src/plugins/plugin.decimation.js

index a5a4ba77103204ba68bb2c92595cfbdcddc1c166..3b5596e4579972c378ebe8cef3e9e8dbee2c2b51 100644 (file)
@@ -205,6 +205,7 @@ module.exports = {
         {
           title: 'Advanced',
           children: [
+            'advanced/data-decimation',
             'advanced/progress-bar',
             'advanced/radial-gradient',
             'advanced/linear-gradient',
index 8e1ad1a3171a21db1c6b9a8f80fb83be6e3eafb1..2b828fc8a5862858d2c03f5145e792430456061c 100644 (file)
@@ -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 (file)
index 0000000..0d69199
--- /dev/null
@@ -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,
+};
+```
index 772b27505f77872c186ccb9bc23b8bc7cca41df2..59a07d7ebe3957c2d279e13a44cd8bd147aaacde 100644 (file)
@@ -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);
+}
index d0204dc817d75c021bf9b1257cedfc6417fbd79e..988526413d1476c7ea9d74b14805d5bea9bf4c21 100644 (file)
@@ -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);
   }
 };