import Element from '../core/core.element';
import layouts from '../core/core.layouts';
import {drawPoint} from '../helpers/helpers.canvas';
-import {callback as call, mergeIf, valueOrDefault} from '../helpers/helpers.core';
+import {callback as call, mergeIf, valueOrDefault, isNullOrUndef} from '../helpers/helpers.core';
import {toFont, toPadding} from '../helpers/helpers.options';
import {getRtlAdapter, overrideTextDirection, restoreTextDirection} from '../helpers/helpers.rtl';
* @return {number} width of the color box area
*/
function getBoxWidth(labelOpts, fontSize) {
- return labelOpts.usePointStyle && labelOpts.boxWidth > fontSize ?
+ const {boxWidth} = labelOpts;
+ return (labelOpts.usePointStyle && boxWidth > fontSize) || isNullOrUndef(boxWidth) ?
fontSize :
- labelOpts.boxWidth;
+ boxWidth;
+}
+
+/**
+ * Helper function to get the box height
+ * @param {object} labelOpts - the label options on the legend
+ * @param {*} fontSize - the label font size
+ * @return {number} height of the color box area
+ */
+function getBoxHeight(labelOpts, fontSize) {
+ const {boxHeight} = labelOpts;
+ return (labelOpts.usePointStyle && boxHeight > fontSize) || isNullOrUndef(boxHeight) ?
+ fontSize :
+ boxHeight;
}
export class Legend extends Element {
const ctx = me.ctx;
const labelFont = toFont(labelOpts.font);
const fontSize = labelFont.size;
+ const boxWidth = getBoxWidth(labelOpts, fontSize);
+ const boxHeight = getBoxHeight(labelOpts, fontSize);
+ const itemHeight = Math.max(boxHeight, fontSize);
// Reset hit boxes
const hitboxes = me.legendHitBoxes = [];
ctx.textBaseline = 'middle';
me.legendItems.forEach((legendItem, i) => {
- const boxWidth = getBoxWidth(labelOpts, fontSize);
const width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
if (i === 0 || lineWidths[lineWidths.length - 1] + width + 2 * labelOpts.padding > minSize.width) {
- totalHeight += fontSize + labelOpts.padding;
+ totalHeight += itemHeight + labelOpts.padding;
lineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;
}
left: 0,
top: 0,
width,
- height: fontSize
+ height: itemHeight
};
lineWidths[lineWidths.length - 1] += width + labelOpts.padding;
const heightLimit = minSize.height - titleHeight;
me.legendItems.forEach((legendItem, i) => {
- const boxWidth = getBoxWidth(labelOpts, fontSize);
const itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;
// If too tall, go to new column
left: 0,
top: 0,
width: itemWidth,
- height: fontSize
+ height: itemHeight,
};
});
ctx.font = labelFont.string;
const boxWidth = getBoxWidth(labelOpts, fontSize);
+ const boxHeight = getBoxHeight(labelOpts, fontSize);
+ const height = Math.max(fontSize, boxHeight);
const hitboxes = me.legendHitBoxes;
// current position
const drawLegendBox = function(x, y, legendItem) {
- if (isNaN(boxWidth) || boxWidth <= 0) {
+ if (isNaN(boxWidth) || boxWidth <= 0 || isNaN(boxHeight) || boxHeight < 0) {
return;
}
drawPoint(ctx, drawOptions, centerX, centerY);
} else {
// Draw box as legend symbol
- ctx.fillRect(rtlHelper.leftForLtr(x, boxWidth), y, boxWidth, fontSize);
+ // Adjust position when boxHeight < fontSize (want it centered)
+ const yBoxTop = y + Math.max((fontSize - boxHeight) / 2, 0);
+
+ ctx.fillRect(rtlHelper.leftForLtr(x, boxWidth), yBoxTop, boxWidth, boxHeight);
if (lineWidth !== 0) {
- ctx.strokeRect(rtlHelper.leftForLtr(x, boxWidth), y, boxWidth, fontSize);
+ ctx.strokeRect(rtlHelper.leftForLtr(x, boxWidth), yBoxTop, boxWidth, boxHeight);
}
}
const fillText = function(x, y, legendItem, textWidth) {
const halfFontSize = fontSize / 2;
const xLeft = rtlHelper.xPlus(x, boxWidth + halfFontSize);
- const yMiddle = y + halfFontSize;
-
+ const yMiddle = y + (height / 2);
ctx.fillText(legendItem.text, xLeft, yMiddle);
if (legendItem.hidden) {
overrideTextDirection(me.ctx, opts.textDirection);
- const itemHeight = fontSize + labelOpts.padding;
+ const itemHeight = height + labelOpts.padding;
me.legendItems.forEach((legendItem, i) => {
const textWidth = ctx.measureText(legendItem.text).width;
const width = boxWidth + (fontSize / 2) + textWidth;