Skip to content

Commit

Permalink
Add 'shape' mode for filler-plugin (#9360)
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Jul 5, 2021
1 parent b4dee55 commit 8405996
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 12 deletions.
1 change: 1 addition & 0 deletions docs/charts/area.md
Expand Up @@ -16,6 +16,7 @@ This feature is implemented by the [`filler` plugin](https://github.com/chartjs/
| Disabled <sup>1</sup> | `boolean` | `false` |
| Stacked value below | `string` | `'stack'` |
| Axis value | `object` | `{ value: number; }` |
| Shape (fill inside line) | `string` | `'shape'` |

> <sup>1</sup> for backward compatibility, `fill: true` is equivalent to `fill: 'origin'`<br/>
Expand Down
32 changes: 21 additions & 11 deletions src/plugins/plugin.filler.js
Expand Up @@ -74,7 +74,7 @@ function decodeFill(line, index, count) {
return target;
}

return ['origin', 'start', 'end', 'stack'].indexOf(fill) >= 0 && fill;
return ['origin', 'start', 'end', 'stack', 'shape'].indexOf(fill) >= 0 && fill;
}

function computeLinearBoundary(source) {
Expand Down Expand Up @@ -315,6 +315,10 @@ function getTarget(source) {
return buildStackLine(source);
}

if (fill === 'shape') {
return true;
}

const boundary = computeBoundary(source);

if (boundary instanceof simpleArc) {
Expand Down Expand Up @@ -481,24 +485,30 @@ function _fill(ctx, cfg) {

for (const {source: src, target: tgt, start, end} of segments) {
const {style: {backgroundColor = color} = {}} = src;
const notShape = target !== true;

ctx.save();
ctx.fillStyle = backgroundColor;

clipBounds(ctx, scale, getBounds(property, start, end));
clipBounds(ctx, scale, notShape && getBounds(property, start, end));

ctx.beginPath();

const lineLoop = !!line.pathSegment(ctx, src);
if (lineLoop) {
ctx.closePath();
} else {
interpolatedLineTo(ctx, target, end, property);
}

const targetLoop = !!target.pathSegment(ctx, tgt, {move: lineLoop, reverse: true});
const loop = lineLoop && targetLoop;
if (!loop) {
interpolatedLineTo(ctx, target, start, property);
let loop;
if (notShape) {
if (lineLoop) {
ctx.closePath();
} else {
interpolatedLineTo(ctx, target, end, property);
}

const targetLoop = !!target.pathSegment(ctx, tgt, {move: lineLoop, reverse: true});
loop = lineLoop && targetLoop;
if (!loop) {
interpolatedLineTo(ctx, target, start, property);
}
}

ctx.closePath();
Expand Down
35 changes: 35 additions & 0 deletions test/fixtures/plugin.filler/line/shape.js
@@ -0,0 +1,35 @@
const data = [];
for (let rad = 0; rad <= Math.PI * 2; rad += Math.PI / 45) {
data.push({
x: Math.cos(rad),
y: Math.sin(rad)
});
}

module.exports = {
config: {
type: 'line',
data: {
datasets: [{
data,
fill: 'shape',
backgroundColor: 'rgba(255, 0, 0, 0.5)',
}]
},
options: {
plugins: {
legend: false
},
scales: {
x: {
type: 'linear',
display: false
},
y: {
type: 'linear',
display: false
},
},
}
}
};
Binary file added test/fixtures/plugin.filler/line/shape.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion types/index.esm.d.ts
Expand Up @@ -2011,7 +2011,7 @@ export interface FillerOptions {
propagate: boolean;
}

export type FillTarget = number | string | { value: number } | 'start' | 'end' | 'origin' | 'stack' | boolean;
export type FillTarget = number | string | { value: number } | 'start' | 'end' | 'origin' | 'stack' | 'shape' | boolean;

export interface ComplexFillTarget {
/**
Expand Down

0 comments on commit 8405996

Please sign in to comment.