mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Ability to fill a line from a specified value along an axis (#7905)
This commit is contained in:
parent
4a191d5af9
commit
c22d3bedea
@ -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. |
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -102,6 +102,12 @@
|
||||
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}}
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
@ -85,6 +85,12 @@
|
||||
data: generateData(),
|
||||
label: 'D5',
|
||||
fill: '-1'
|
||||
}, {
|
||||
backgroundColor: utils.transparentize(presets.grey),
|
||||
borderColor: presets.grey,
|
||||
data: generateData(),
|
||||
label: 'D6',
|
||||
fill: {value: 85},
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
42
test/fixtures/plugin.filler/fill-line-value.json
vendored
Normal file
42
test/fixtures/plugin.filler/fill-line-value.json
vendored
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/fixtures/plugin.filler/fill-line-value.png
vendored
Normal file
BIN
test/fixtures/plugin.filler/fill-line-value.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
39
test/fixtures/plugin.filler/fill-radar-value.json
vendored
Normal file
39
test/fixtures/plugin.filler/fill-radar-value.json
vendored
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/fixtures/plugin.filler/fill-radar-value.png
vendored
Normal file
BIN
test/fixtures/plugin.filler/fill-radar-value.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.2 KiB |
2
types/plugins/index.d.ts
vendored
2
types/plugins/index.d.ts
vendored
@ -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 {
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user