]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Ability to fill a line from a specified value along an axis (#7905)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sat, 17 Oct 2020 19:46:56 +0000 (15:46 -0400)
committerGitHub <noreply@github.com>
Sat, 17 Oct 2020 19:46:56 +0000 (15:46 -0400)
docs/docs/charts/area.md
samples/charts/area/analyser.js
samples/charts/area/line-datasets.html
samples/charts/area/radar.html
src/plugins/plugin.filler.js
test/fixtures/plugin.filler/fill-line-value.json [new file with mode: 0644]
test/fixtures/plugin.filler/fill-line-value.png [new file with mode: 0644]
test/fixtures/plugin.filler/fill-radar-value.json [new file with mode: 0644]
test/fixtures/plugin.filler/fill-radar-value.png [new file with mode: 0644]
types/plugins/index.d.ts

index 4ec8edb75a917a6703c97198f31f73b53d6dc6f6..477ece36f907a922130f346d8917e01d0b0a12b2 100644 (file)
@@ -15,11 +15,13 @@ Both [line](./line.mdx) and [radar](./radar.mdx) charts support a `fill` option
 | Boundary <sup>2</sup> | `string` | `'start'`, `'end'`, `'origin'` |
 | Disabled <sup>3</sup> | `boolean` | `false` |
 | Stacked value below <sup>4</sup> | `string` | `'stack'` |
+| Axis value <sup>5</sup> | `object` | `{ value: number; }` |
 
 > <sup>1</sup> dataset filling modes have been introduced in version 2.6.0<br/>
 > <sup>2</sup> prior version 2.6.0, boundary values was `'zero'`, `'top'`, `'bottom'` (not supported anymore)<br/>
 > <sup>3</sup> for backward compatibility, `fill: true` (default) is equivalent to `fill: 'origin'`<br/>
 > <sup>4</sup> stack mode has been introduced in version 3.0.0<br/>
+> <sup>5</sup> axis value mode has been introduced in version 3.0.0<br/>
 
 **Example**
 
@@ -31,7 +33,8 @@ new Chart(ctx, {
             {fill: '+2'},          // 1: fill to dataset 3
             {fill: 1},             // 2: fill to dataset 1
             {fill: false},         // 3: no fill
-            {fill: '-2'}           // 4: fill to dataset 2
+            {fill: '-2'},          // 4: fill to dataset 2
+            {fill: {value: 25}}    // 5: fill to axis value 25
         ]
     }
 });
@@ -41,7 +44,7 @@ If you need to support multiple colors when filling from one dataset to another,
 
 | Param | Type | Description |
 | :--- | :--- | :--- |
-| `target` | `number`, `string`, `boolean` | The accepted values are the same as the filling mode values, so you may use absolute and relative dataset indexes and/or boundaries. |
+| `target` | `number`, `string`, `boolean`, `object` | The accepted values are the same as the filling mode values, so you may use absolute and relative dataset indexes and/or boundaries. |
 | `above` | `Color` | If no color is set, the default color will be the background color of the chart. |
 | `below` | `Color` | Same as the above. |
 
index 5c100541830527007b6dda060ce7f4210cae8f32..592dcbb9df90f7dd9caa713524daf0b503b00c37 100644 (file)
@@ -48,7 +48,7 @@
                                        } else if (isFinite(target)) {
                                                target = 'dataset ' + target;
                                        } else {
-                                               target = 'boundary "' + target + '"';
+                                               target = 'boundary "' + (typeof target === 'object' ? JSON.stringify(target) : target) + '"';
                                        }
 
                                        if (stat.visible) {
index 9a6636161b114fc7ea180659ff5f729569586781..1d1d2706e07396a9a53b63d2f8edb5125509b880 100644 (file)
                                hidden: true,
                                label: 'D8',
                                fill: 'end'
+                       }, {
+                               backgroundColor: utils.transparentize(presets.yellow),
+                               borderColor: presets.yellow,
+                               data: generateData(),
+                               label: 'D9',
+                               fill: {above: 'blue', below: 'red', target: {value: 350}}
                        }]
                };
 
index de30630eda7c85766a92daf4ef3b4499f6cf293b..3c36d670f523cdacb6fd2d7fed2f2d5f49e83a41 100644 (file)
                                data: generateData(),
                                label: 'D5',
                                fill: '-1'
+                       }, {
+                               backgroundColor: utils.transparentize(presets.grey),
+                               borderColor: presets.grey,
+                               data: generateData(),
+                               label: 'D6',
+                               fill: {value: 85},
                        }]
                };
 
index c27e4d377c0920133868542315f0499b36a5c0e2..49d2d9ec9bb1f4470b35955151e8819f113fbbb0 100644 (file)
@@ -7,7 +7,7 @@
 import Line from '../elements/element.line';
 import {_boundSegment, _boundSegments} from '../helpers/helpers.segment';
 import {clipArea, unclipArea} from '../helpers/helpers.canvas';
-import {isArray, isFinite, valueOrDefault} from '../helpers/helpers.core';
+import {isArray, isFinite, isObject, valueOrDefault} from '../helpers/helpers.core';
 import {TAU, _normalizeAngle} from '../helpers/helpers.math';
 
 /**
@@ -57,7 +57,9 @@ function decodeFill(line, index, count) {
        const fill = parseFillOption(line);
        let target = parseFloat(fill);
 
-       if (isFinite(target) && Math.floor(target) === target) {
+       if (isObject(fill)) {
+               return isNaN(fill.value) ? false : fill;
+       } else if (isFinite(target) && Math.floor(target) === target) {
                if (fill[0] === '-' || fill[0] === '+') {
                        target = index + target;
                }
@@ -81,6 +83,8 @@ function computeLinearBoundary(source) {
                target = scale.bottom;
        } else if (fill === 'end') {
                target = scale.top;
+       } else if (isObject(fill)) {
+               target = scale.getPixelForValue(fill.value);
        } else if (scale.getBasePixel) {
                target = scale.getBasePixel();
        }
@@ -135,8 +139,17 @@ function computeCircularBoundary(source) {
        const target = [];
        const start = options.reverse ? scale.max : scale.min;
        const end = options.reverse ? scale.min : scale.max;
-       const value = fill === 'start' ? start : fill === 'end' ? end : scale.getBaseValue();
-       let i, center;
+       let i, center, value;
+
+       if (fill === 'start') {
+               value = start;
+       } else if (fill === 'end') {
+               value = end;
+       } else if (isObject(fill)) {
+               value = fill.value;
+       } else {
+               value = scale.getBaseValue();
+       }
 
        if (options.gridLines.circular) {
                center = scale.getPointPositionForValue(0, start);
diff --git a/test/fixtures/plugin.filler/fill-line-value.json b/test/fixtures/plugin.filler/fill-line-value.json
new file mode 100644 (file)
index 0000000..f8520ea
--- /dev/null
@@ -0,0 +1,42 @@
+{
+    "config": {
+        "type": "line",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(255, 0, 0, 0.25)",
+                "data": [-4, 4, 0, -1, 0, 1, 0, -1, 0],
+                "fill": { "value": 2 }
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scales": {
+                "x": {
+                    "display": false
+                },
+                "y": {
+                    "display": false
+                }
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "tension": 0
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 512
+        }
+    }
+}
diff --git a/test/fixtures/plugin.filler/fill-line-value.png b/test/fixtures/plugin.filler/fill-line-value.png
new file mode 100644 (file)
index 0000000..758b1c1
Binary files /dev/null and b/test/fixtures/plugin.filler/fill-line-value.png differ
diff --git a/test/fixtures/plugin.filler/fill-radar-value.json b/test/fixtures/plugin.filler/fill-radar-value.json
new file mode 100644 (file)
index 0000000..f56be39
--- /dev/null
@@ -0,0 +1,39 @@
+{
+    "config": {
+        "type": "radar",
+        "data": {
+            "labels": ["0", "1", "2", "3", "4", "5", "6", "7", "8"],
+            "datasets": [{
+                "backgroundColor": "rgba(0, 0, 192, 0.25)",
+                "data": [0, -4, 2, 4, 2, 1, -1, 1, 2]
+            }]
+        },
+        "options": {
+            "responsive": false,
+            "spanGaps": false,
+            "legend": false,
+            "title": false,
+            "scale": {
+                "display": false,
+                "gridLines": {
+                    "circular": true
+                }
+            },
+            "elements": {
+                "point": {
+                    "radius": 0
+                },
+                "line": {
+                    "borderColor": "transparent",
+                    "fill": { "value": 3 }
+                }
+            }
+        }
+    },
+    "options": {
+        "canvas": {
+            "height": 256,
+            "width": 256
+        }
+    }
+}
diff --git a/test/fixtures/plugin.filler/fill-radar-value.png b/test/fixtures/plugin.filler/fill-radar-value.png
new file mode 100644 (file)
index 0000000..f74ee51
Binary files /dev/null and b/test/fixtures/plugin.filler/fill-radar-value.png differ
index 414d3f90775f53b60e7713c76e939adab5559757..cecf760a1aa7c1e15c2c705c5cc7aa8effa97620 100644 (file)
@@ -9,7 +9,7 @@ export interface IFillerOptions {
   propagate: boolean;
 }
 
-export type FillTarget = number | string | 'start' | 'end' | 'origin' | 'stack' | false;
+export type FillTarget = number | string | { value: number } | 'start' | 'end' | 'origin' | 'stack' | false;
 
 export interface IFillTarget {
   /**