diff --git a/src/plugins/plugin.legend.js b/src/plugins/plugin.legend.js index 6ed99413536..86197370aaf 100644 --- a/src/plugins/plugin.legend.js +++ b/src/plugins/plugin.legend.js @@ -17,6 +17,9 @@ import { import {_alignStartEnd, _textX, _toLeftRightCenter} from '../helpers/helpers.extras.js'; import {toTRBLCorners} from '../helpers/helpers.options.js'; + + + /** * @typedef { import('../types/index.js').ChartEvent } ChartEvent */ @@ -119,40 +122,74 @@ export class Legend extends Element { this.legendItems = legendItems; } +fit() { + const { options, ctx } = this; + if (!options.display) { + this.width = this.height = 0; + return; + } - fit() { - const {options, ctx} = this; - - // The legend may not be displayed for a variety of reasons including - // the fact that the defaults got set to `false`. - // When the legend is not displayed, there are no guarantees that the options - // are correctly formatted so we need to bail out as early as possible. - if (!options.display) { - this.width = this.height = 0; - return; - } + const labelOpts = options.labels; + const labelFont = toFont(labelOpts.font); + const fontSize = labelFont.size; + const titleHeight = this._computeTitleHeight(); + const { boxWidth, itemHeight } = getBoxSize(labelOpts, fontSize); + + let width, height; + ctx.font = labelFont.string; + + if (this.isHorizontal()) { + width = this.maxWidth; + height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10; + } else { + height = this.maxHeight; + width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10; + } - const labelOpts = options.labels; - const labelFont = toFont(labelOpts.font); - const fontSize = labelFont.size; - const titleHeight = this._computeTitleHeight(); - const {boxWidth, itemHeight} = getBoxSize(labelOpts, fontSize); + // --- handle scroll height limit --- + const scrollOpts = options.scroll || {}; + if (scrollOpts.enabled && scrollOpts.maxItems) { + const singleItemHeight = itemHeight + labelOpts.padding; + const visibleHeight = singleItemHeight * scrollOpts.maxItems + titleHeight + labelOpts.padding * 2; + this.height = Math.min(this.height, visibleHeight); - let width, height; + // wrap legend in scroll container + this._wrapLegendScroll(visibleHeight); + } - ctx.font = labelFont.string; + this.width = Math.min(width, options.maxWidth || this.maxWidth); + this.height = Math.min(height, options.maxHeight || this.maxHeight); +} - if (this.isHorizontal()) { - width = this.maxWidth; // fill all the width - height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight) + 10; - } else { - height = this.maxHeight; // fill all the height - width = this._fitCols(titleHeight, labelFont, boxWidth, itemHeight) + 10; - } +/** + * Private helper to wrap the