diff --git a/src/plugins/plugin.filler/filler.drawing.js b/src/plugins/plugin.filler/filler.drawing.js index 0a718355da8..e3f7cbb3cf7 100644 --- a/src/plugins/plugin.filler/filler.drawing.js +++ b/src/plugins/plugin.filler/filler.drawing.js @@ -12,12 +12,31 @@ export function _drawfill(ctx, source, area) { const meta = chart.getDatasetMeta(index); const clip = getDatasetClipArea(chart, meta); if (target && line.points.length) { - clipArea(ctx, area); + clipArea(ctx, clipToIndexBounds(area, meta.iScale)); doFill(ctx, {line, target, above, below, area, scale, axis, clip}); unclipArea(ctx); } } +// The line's stroke is limited to the index scale's min/max pixel bounds +// (see LineController#update -> _getStartAndCountOfVisiblePoints). Clip the +// fill to the same bounds so it doesn't extend past the stroke when +// `offset: true` insets tick pixels from the chart area edges. +function clipToIndexBounds(area, iScale) { + // Radial scales (e.g. radar charts) aren't cartesian: min/max pixels + // don't correspond to a left/right or top/bottom bound. + if (!iScale || iScale.getPointPositionForValue) { + return area; + } + const p1 = iScale.getPixelForValue(iScale.min); + const p2 = iScale.getPixelForValue(iScale.max); + const lo = Math.min(p1, p2); + const hi = Math.max(p1, p2); + return iScale.isHorizontal() + ? {...area, left: Math.max(area.left, lo), right: Math.min(area.right, hi)} + : {...area, top: Math.max(area.top, lo), bottom: Math.min(area.bottom, hi)}; +} + function doFill(ctx, cfg) { const {line, target, above, below, area, scale, clip} = cfg; const property = line._loop ? 'angle' : cfg.axis; diff --git a/test/fixtures/plugin.filler/line/offset-scale-minmax.js b/test/fixtures/plugin.filler/line/offset-scale-minmax.js new file mode 100644 index 00000000000..9dce8836791 --- /dev/null +++ b/test/fixtures/plugin.filler/line/offset-scale-minmax.js @@ -0,0 +1,38 @@ +module.exports = { + description: 'https://github.com/chartjs/Chart.js/issues/12280', + config: { + type: 'line', + data: { + labels: ['a', 'b', 'c', 'd', 'e', 'f'], + datasets: [{ + data: [10, 25, 15, 40, 30, 45], + fill: true, + backgroundColor: 'red', + borderColor: 'blue' + }] + }, + options: { + plugins: { + legend: false, + title: false, + tooltip: false + }, + elements: { + point: { + radius: 0 + } + }, + scales: { + x: { + display: false, + offset: true, + min: 'a', + max: 'd' + }, + y: { + display: false + } + } + } + }, +}; diff --git a/test/fixtures/plugin.filler/line/offset-scale-minmax.png b/test/fixtures/plugin.filler/line/offset-scale-minmax.png new file mode 100644 index 00000000000..e037c4c44cb Binary files /dev/null and b/test/fixtures/plugin.filler/line/offset-scale-minmax.png differ