From: FabTechAT Date: Tue, 15 Apr 2025 13:31:58 +0000 (+0200) Subject: feature: make above/below colors in filler plugin work with pivoted line charts ... X-Git-Tag: v4.5.0~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b1306ab0a397ac51a256255770da99f2543afcf;p=thirdparty%2FChart.js.git feature: make above/below colors in filler plugin work with pivoted line charts (#12058) * adapted filler plugin to make above/below colors work with pivoted line charts resolved conflicts in src/plugins/plugin.filler/filler.drawing.js * fixed doFill; added tests --- diff --git a/src/plugins/plugin.filler/filler.drawing.js b/src/plugins/plugin.filler/filler.drawing.js index 9abb513cf..0a718355d 100644 --- a/src/plugins/plugin.filler/filler.drawing.js +++ b/src/plugins/plugin.filler/filler.drawing.js @@ -24,14 +24,24 @@ function doFill(ctx, cfg) { ctx.save(); - if (property === 'x' && below !== above) { - clipVertical(ctx, target, area.top); - fill(ctx, {line, target, color: above, scale, property, clip}); - ctx.restore(); - ctx.save(); - clipVertical(ctx, target, area.bottom); + let fillColor = below; + if (below !== above) { + if (property === 'x') { + clipVertical(ctx, target, area.top); + fill(ctx, {line, target, color: above, scale, property, clip}); + ctx.restore(); + ctx.save(); + clipVertical(ctx, target, area.bottom); + } else if (property === 'y') { + clipHorizontal(ctx, target, area.left); + fill(ctx, {line, target, color: below, scale, property, clip}); + ctx.restore(); + ctx.save(); + clipHorizontal(ctx, target, area.right); + fillColor = above; + } } - fill(ctx, {line, target, color: below, scale, property, clip}); + fill(ctx, {line, target, color: fillColor, scale, property, clip}); ctx.restore(); } @@ -66,6 +76,36 @@ function clipVertical(ctx, target, clipY) { ctx.clip(); } +function clipHorizontal(ctx, target, clipX) { + const {segments, points} = target; + let first = true; + let lineLoop = false; + + ctx.beginPath(); + for (const segment of segments) { + const {start, end} = segment; + const firstPoint = points[start]; + const lastPoint = points[_findSegmentEnd(start, end, points)]; + if (first) { + ctx.moveTo(firstPoint.x, firstPoint.y); + first = false; + } else { + ctx.lineTo(clipX, firstPoint.y); + ctx.lineTo(firstPoint.x, firstPoint.y); + } + lineLoop = !!target.pathSegment(ctx, segment, {move: lineLoop}); + if (lineLoop) { + ctx.closePath(); + } else { + ctx.lineTo(clipX, lastPoint.y); + } + } + + ctx.lineTo(clipX, target.first().y); + ctx.closePath(); + ctx.clip(); +} + function fill(ctx, cfg) { const {line, target, property, color, scale, clip} = cfg; const segments = _segments(line, target, property); diff --git a/test/fixtures/plugin.filler/line/above-below-vertical-linechart.js b/test/fixtures/plugin.filler/line/above-below-vertical-linechart.js new file mode 100644 index 000000000..82ada178f --- /dev/null +++ b/test/fixtures/plugin.filler/line/above-below-vertical-linechart.js @@ -0,0 +1,46 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [1, 2, 3, 4], + datasets: [ + { + data: [200, 400, 200, 400], + cubicInterpolationMode: 'monotone', + tension: 0.4, + spanGaps: true, + borderColor: 'blue', + pointRadius: 0, + fill: { + target: 1, + below: 'rgba(255, 0, 0, 0.4)', + above: 'rgba(53, 221, 53, 0.4)', + } + }, + { + data: [400, 200, 400, 200], + cubicInterpolationMode: 'monotone', + tension: 0.4, + spanGaps: true, + borderColor: 'orange', + pointRadius: 0, + }, + ] + }, + options: { + indexAxis: 'y', + // maintainAspectRatio: false, + plugins: { + filler: { + propagate: false + }, + datalabels: { + display: false + }, + legend: { + display: false + }, + } + } + } +}; diff --git a/test/fixtures/plugin.filler/line/above-below-vertical-linechart.png b/test/fixtures/plugin.filler/line/above-below-vertical-linechart.png new file mode 100644 index 000000000..2052737e7 Binary files /dev/null and b/test/fixtures/plugin.filler/line/above-below-vertical-linechart.png differ