export const _toLeftRightCenter = (align) => align === 'start' ? 'left' : align === 'end' ? 'right' : 'center';
/**
- * Returns `start`, `end` or `(start + end) / 2` depending on `align`
+ * Returns `start`, `end` or `(start + end) / 2` depending on `align`. Defaults to `center`
* @param {string} align start, end, center
* @param {number} start value for start
* @param {number} end value for end
* @private
*/
export const _alignStartEnd = (align, start, end) => align === 'start' ? start : align === 'end' ? end : (start + end) / 2;
+
+/**
+ * Returns `left`, `right` or `(left + right) / 2` depending on `align`. Defaults to `left`
+ * @param {string} align start, end, center
+ * @param {number} left value for start
+ * @param {number} right value for end
+ * @private
+ */
+export const _textX = (align, left, right) => align === 'right' ? right : align === 'center' ? (left + right) / 2 : left;
import layouts from '../core/core.layouts';
import {drawPoint, renderText} from '../helpers/helpers.canvas';
import {
- callback as call, valueOrDefault, toFont, isObject,
+ callback as call, valueOrDefault, toFont,
toPadding, getRtlAdapter, overrideTextDirection, restoreTextDirection,
clipArea, unclipArea
} from '../helpers/index';
-import {_toLeftRightCenter, _alignStartEnd} from '../helpers/helpers.extras';
+import {_toLeftRightCenter, _alignStartEnd, _textX} from '../helpers/helpers.extras';
/**
* @typedef { import("../platform/platform.base").ChartEvent } ChartEvent
*/
const labelFont = toFont(labelOpts.font);
const {color: fontColor, padding} = labelOpts;
const fontSize = labelFont.size;
+ const halfFontSize = fontSize / 2;
let cursor;
me.drawTitle();
borderWidth: lineWidth
};
const centerX = rtlHelper.xPlus(x, boxWidth / 2);
- const centerY = y + fontSize / 2;
+ const centerY = y + halfFontSize;
// Draw pointStyle as legend symbol
drawPoint(ctx, drawOptions, centerX, centerY);
};
const fillText = function(x, y, legendItem) {
- const halfFontSize = fontSize / 2;
- const xLeft = rtlHelper.xPlus(x, boxWidth + halfFontSize);
- renderText(ctx, legendItem.text, xLeft, y + (itemHeight / 2), labelFont, {strikethrough: legendItem.hidden});
+ renderText(ctx, legendItem.text, x, y + (itemHeight / 2), labelFont, {
+ strikethrough: legendItem.hidden,
+ textAlign: legendItem.textAlign
+ });
};
// Horizontal
const lineHeight = itemHeight + padding;
me.legendItems.forEach((legendItem, i) => {
const textWidth = ctx.measureText(legendItem.text).width;
+ const textAlign = rtlHelper.textAlign(legendItem.textAlign || (legendItem.textAlign = labelOpts.textAlign));
const width = boxWidth + (fontSize / 2) + textWidth;
let x = cursor.x;
let y = cursor.y;
legendHitBoxes[i].left = rtlHelper.leftForLtr(realX, legendHitBoxes[i].width);
legendHitBoxes[i].top = y;
+ x = _textX(textAlign, x + boxWidth + halfFontSize, me.right);
+
// Fill the actual label
- fillText(realX, y, legendItem);
+ fillText(rtlHelper.x(x), y, legendItem);
if (isHorizontal) {
cursor.x += width + padding;
// lineWidth :
generateLabels(chart) {
const datasets = chart.data.datasets;
- const {labels} = chart.legend.options;
- const usePointStyle = labels.usePointStyle;
- const overrideStyle = labels.pointStyle;
+ const {labels: {usePointStyle, pointStyle, textAlign}} = chart.legend.options;
return chart._getSortedDatasetMetas().map((meta) => {
const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
- const borderWidth = isObject(style.borderWidth) ? (valueOrDefault(style.borderWidth.top, 0) + valueOrDefault(style.borderWidth.left, 0) + valueOrDefault(style.borderWidth.bottom, 0) + valueOrDefault(style.borderWidth.right, 0)) / 4 : style.borderWidth;
+ const borderWidth = toPadding(style.borderWidth);
return {
text: datasets[meta.index].label,
lineDash: style.borderDash,
lineDashOffset: style.borderDashOffset,
lineJoin: style.borderJoinStyle,
- lineWidth: borderWidth,
+ lineWidth: (borderWidth.width + borderWidth.height) / 4,
strokeStyle: style.borderColor,
- pointStyle: overrideStyle || style.pointStyle,
+ pointStyle: pointStyle || style.pointStyle,
rotation: style.rotation,
+ textAlign: textAlign || style.textAlign,
// Below is extra data used for toggling the datasets
datasetIndex: meta.index
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}, {
text: 'dataset2',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 1
}, {
text: 'dataset3',
strokeStyle: 'green',
pointStyle: 'crossRot',
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 2
}]);
});
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}, {
text: 'dataset2',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 1
}, {
text: 'dataset3',
strokeStyle: 'green',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 2
}]);
});
strokeStyle: 'green',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 2
}, {
text: 'dataset2',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 1
}, {
text: 'dataset1',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}]);
});
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}, {
text: 'dataset3',
strokeStyle: 'green',
pointStyle: 'crossRot',
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 2
}]);
});
strokeStyle: 'green',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 2
}, {
text: 'dataset2',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 1
}, {
text: 'dataset1',
strokeStyle: 'rgba(0,0,0,0.1)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}]);
});
strokeStyle: 'red',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}]);
});
strokeStyle: 'rgb(205, 0, 0)',
pointStyle: undefined,
rotation: undefined,
+ textAlign: undefined,
datasetIndex: 0
}]);
});
strokeStyle: 'green',
pointStyle: 'crossRot',
rotation: 0,
+ textAlign: undefined,
datasetIndex: 0
}, {
text: 'dataset2',
strokeStyle: '#f31',
pointStyle: 'crossRot',
rotation: 15,
+ textAlign: undefined,
datasetIndex: 1
}]);
});
strokeStyle: 'green',
pointStyle: 'star',
rotation: 0,
+ textAlign: undefined,
datasetIndex: 0
}, {
text: 'dataset2',
strokeStyle: '#f31',
pointStyle: 'star',
rotation: 15,
+ textAlign: undefined,
datasetIndex: 1
}]);
});