diff --git a/packages/picasso.js/src/core/chart-components/labels/strategies/__tests__/bars.spec.js b/packages/picasso.js/src/core/chart-components/labels/strategies/__tests__/bars.spec.js index f7f5c1b0c..6e9fab697 100644 --- a/packages/picasso.js/src/core/chart-components/labels/strategies/__tests__/bars.spec.js +++ b/packages/picasso.js/src/core/chart-components/labels/strategies/__tests__/bars.spec.js @@ -972,6 +972,65 @@ describe('labeling - bars', () => { fontFamily: 'simpsons', }); }); + + it('should accept padding top/bottom/left/right as functions, and filter out label that is not inside container', () => { + const settings = { + direction: () => 'right', + align: 0.4, + justify: 0.8, + labels: [ + { + placements: [ + { + position: 'inside', + justify: 0.2, + align: 0.5, + fill: () => 'red', + padding: { + left: ({ width }) => width / 5, + right: ({ width, height }) => (width + height) / 7.5, + top: ({ height }) => height / 2.5, + bottom: ({ height }) => height - 6, + }, + }, + ], + label: () => 'etikett', + }, + ], + }; + const nodes = [ + { + localBounds: { + x: 10, + y: 20, + width: 40, + height: 50, + }, + }, + ]; + renderer.measureText.returns({ width: 20, height: 10 }); + let labels = bars({ + settings, + chart, + nodes, + rect: { + x: 0, + y: 37, + width: 100, + height: 200, + }, + renderer, + style: { + label: { + fontSize: '16px', + fontFamily: 'simpsons', + fill: 'green', + }, + }, + }); + + expect(labels.length).to.eql(0); + }); }); describe('orientation', () => { diff --git a/packages/picasso.js/src/core/chart-components/labels/strategies/bars.js b/packages/picasso.js/src/core/chart-components/labels/strategies/bars.js index 9e11f25d5..cf6ec0de5 100644 --- a/packages/picasso.js/src/core/chart-components/labels/strategies/bars.js +++ b/packages/picasso.js/src/core/chart-components/labels/strategies/bars.js @@ -209,6 +209,10 @@ export function findBestPlacement( function approxTextBounds(label, textMetrics, rotated, rect, padding = {}) { const { top = PADDING, bottom = PADDING, left = PADDING, right = PADDING } = padding; + const leftPadding = typeof left === 'function' ? left(textMetrics) : left; + const rightPadding = typeof right === 'function' ? right(textMetrics) : right; + const topPadding = typeof top === 'function' ? top(textMetrics) : top; + const bottomPadding = typeof bottom === 'function' ? bottom(textMetrics) : bottom; const x0 = label.x + label.dx; const y0 = label.y + label.dy; const height = rotated ? Math.min(textMetrics.width, rect.height) : Math.min(textMetrics.height, rect.width); @@ -218,10 +222,10 @@ function approxTextBounds(label, textMetrics, rotated, rect, padding = {}) { const x = rotated ? x0 - offset : x0; const y = rotated ? y0 : y0 - offset; const bounds = { - x: x - left - PADDING_OFFSET, - y: y - top - PADDING_OFFSET, - width: width + (left + right) - PADDING_OFFSET, - height: height + (top + bottom) - PADDING_OFFSET, + x: x - leftPadding - PADDING_OFFSET, + y: y - topPadding - PADDING_OFFSET, + width: width + (leftPadding + rightPadding) - PADDING_OFFSET, + height: height + (topPadding + bottomPadding) - PADDING_OFFSET, }; return bounds; }