From: Jukka Kurkela Date: Mon, 5 Jul 2021 21:03:19 +0000 (+0300) Subject: Add 'shape' mode for filler-plugin (#9360) X-Git-Tag: v3.5.0~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=840599637f2af797d42731ec27d91e0c82325134;p=thirdparty%2FChart.js.git Add 'shape' mode for filler-plugin (#9360) --- diff --git a/docs/charts/area.md b/docs/charts/area.md index 39e7f2221..5dc8a5049 100644 --- a/docs/charts/area.md +++ b/docs/charts/area.md @@ -16,6 +16,7 @@ This feature is implemented by the [`filler` plugin](https://github.com/chartjs/ | Disabled 1 | `boolean` | `false` | | Stacked value below | `string` | `'stack'` | | Axis value | `object` | `{ value: number; }` | +| Shape (fill inside line) | `string` | `'shape'` | > 1 for backward compatibility, `fill: true` is equivalent to `fill: 'origin'`
diff --git a/src/plugins/plugin.filler.js b/src/plugins/plugin.filler.js index 4b70e2cf4..9e3e3b8f5 100644 --- a/src/plugins/plugin.filler.js +++ b/src/plugins/plugin.filler.js @@ -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) { @@ -315,6 +315,10 @@ function getTarget(source) { return buildStackLine(source); } + if (fill === 'shape') { + return true; + } + const boundary = computeBoundary(source); if (boundary instanceof simpleArc) { @@ -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(); diff --git a/test/fixtures/plugin.filler/line/shape.js b/test/fixtures/plugin.filler/line/shape.js new file mode 100644 index 000000000..3a78bc745 --- /dev/null +++ b/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 + }, + }, + } + } +}; diff --git a/test/fixtures/plugin.filler/line/shape.png b/test/fixtures/plugin.filler/line/shape.png new file mode 100644 index 000000000..08e59986c Binary files /dev/null and b/test/fixtures/plugin.filler/line/shape.png differ diff --git a/types/index.esm.d.ts b/types/index.esm.d.ts index 1598bc828..d26a63396 100644 --- a/types/index.esm.d.ts +++ b/types/index.esm.d.ts @@ -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 { /**