| Name | Type | Scriptable | Default | Description
| ---- | ---- | :-------------------------------: | ------- | -----------
+| `alignment` | `string` | | `'center'` | The tick alignment along the axis. Can be `'start'`, `'center'`, or `'end'`.
| `callback` | `function` | | | Returns the string representation of the tick value as it should be displayed on the chart. See [callback](../axes/labelling.md#creating-custom-tick-formats).
| `display` | `boolean` | | `true` | If true, show tick labels.
| `font` | `Font` | Yes | `defaults.font` | See [Fonts](../general/fonts.md)
}, {
title: 'Filtering Labels',
path: 'scales/filtering-labels.html'
+ }, {
+ title: 'Label Text Alignment',
+ path: 'scales/label-text-alignment.html'
}, {
title: 'Non numeric Y Axis',
path: 'scales/non-numeric-y.html'
--- /dev/null
+<!doctype html>
+<html>
+
+<head>
+ <title>Label Text Alignment</title>
+ <script src="../../dist/chart.min.js"></script>
+ <script src="../utils.js"></script>
+ <style>
+ canvas {
+ -moz-user-select: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ }
+ .chart-container {
+ width: 500px;
+ margin-left: 40px;
+ margin-right: 40px;
+ }
+ .container {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: center;
+ }
+ </style>
+</head>
+
+<body>
+ <div class="container">
+ <div class="chart-container">
+ <canvas id="chart-start-start"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-start-center"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-start-end"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-center-start"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-center-center"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-center-end"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-end-start"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-end-center"></canvas>
+ </div>
+ <div class="chart-container">
+ <canvas id="chart-end-end"></canvas>
+ </div>
+ </div>
+ <script>
+ var color = Chart.helpers.color;
+ function createConfig(xAlign, yAlign, colorName) {
+ return {
+ type: 'line',
+ data: {
+ labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
+ datasets: [{
+ label: 'My First dataset',
+ data: [
+ randomScalingFactor(),
+ randomScalingFactor(),
+ randomScalingFactor(),
+ randomScalingFactor(),
+ randomScalingFactor(),
+ randomScalingFactor(),
+ randomScalingFactor()
+ ],
+ backgroundColor: color(window.chartColors[colorName]).alpha(0.5).rgbString(),
+ borderColor: window.chartColors[colorName],
+ borderWidth: 1
+ }]
+ },
+ options: {
+ responsive: true,
+ legend: {
+ display: false,
+ },
+ scales: {
+ x: {
+ display: true,
+ ticks: {
+ alignment: xAlign,
+ }
+ },
+ y: {
+ display: true,
+ ticks: {
+ alignment: yAlign
+ }
+ }
+ },
+ title: {
+ display: true,
+ text: 'X Tick Alignment: ' + xAlign + ', Y Tick Alignment ' + yAlign
+ }
+ }
+ };
+ }
+
+ window.onload = function() {
+ [{
+ id: 'chart-start-start',
+ xAlign: 'start',
+ yAlign: 'start',
+ color: 'red'
+ }, {
+ id: 'chart-start-center',
+ xAlign: 'start',
+ yAlign: 'center',
+ color: 'orange'
+ }, {
+ id: 'chart-start-end',
+ xAlign: 'start',
+ yAlign: 'end',
+ color: 'yellow'
+ }, {
+ id: 'chart-center-start',
+ xAlign: 'center',
+ yAlign: 'start',
+ color: 'green'
+ }, {
+ id: 'chart-center-center',
+ xAlign: 'center',
+ yAlign: 'center',
+ color: 'blue'
+ }, {
+ id: 'chart-center-end',
+ xAlign: 'center',
+ yAlign: 'end',
+ color: 'purple'
+ }, {
+ id: 'chart-end-start',
+ xAlign: 'end',
+ yAlign: 'start',
+ color: 'grey'
+ }, {
+ id: 'chart-end-center',
+ xAlign: 'end',
+ yAlign: 'center',
+ color: 'red'
+ }, {
+ id: 'chart-end-end',
+ xAlign: 'end',
+ yAlign: 'end',
+ color: 'orange'
+ }].forEach(function(details) {
+ var ctx = document.getElementById(details.id).getContext('2d');
+ var config = createConfig(details.xAlign, details.yAlign, details.color);
+ new Chart(ctx, config);
+ });
+ };
+ </script>
+</body>
+
+</html>
// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.
callback: Ticks.formatters.values,
minor: {},
- major: {}
+ major: {},
+ alignment: 'center',
}
});
paddingRight = labelsBelowTicks ?
sinRotation * (lastLabelSize.height - lastLabelSize.offset) :
cosRotation * lastLabelSize.width + sinRotation * lastLabelSize.offset;
+ } else if (tickOpts.alignment === 'start') {
+ paddingLeft = 0;
+ paddingRight = lastLabelSize.width;
+ } else if (tickOpts.alignment === 'end') {
+ paddingLeft = firstLabelSize.width;
+ paddingRight = 0;
} else {
paddingLeft = firstLabelSize.width / 2;
paddingRight = lastLabelSize.width / 2;
minSize.width = Math.min(me.maxWidth, minSize.width + labelWidth);
- me.paddingTop = lastLabelSize.height / 2;
- me.paddingBottom = firstLabelSize.height / 2;
+ let paddingTop = lastLabelSize.height / 2;
+ let paddingBottom = firstLabelSize.height / 2;
+
+ if (tickOpts.alignment === 'start') {
+ paddingTop = 0;
+ paddingBottom = firstLabelSize.height;
+ } else if (tickOpts.alignment === 'end') {
+ paddingTop = lastLabelSize.height;
+ paddingBottom = 0;
+ }
+
+ me.paddingTop = paddingTop;
+ me.paddingBottom = paddingBottom;
}
}
const rotation = -toRadians(me.labelRotation);
const items = [];
let i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;
+ let textBaseline = 'middle';
if (position === 'top') {
y = me.bottom - tl - tickPadding;
- textAlign = !rotation ? 'center' : 'left';
+ textAlign = me._getXAxisLabelAlignment();
} else if (position === 'bottom') {
y = me.top + tl + tickPadding;
- textAlign = !rotation ? 'center' : 'right';
+ textAlign = me._getXAxisLabelAlignment();
} else if (position === 'left') {
x = me.right - (isMirrored ? 0 : tl) - tickPadding;
textAlign = isMirrored ? 'left' : 'right';
const value = position[positionAxisID];
y = me.chart.scales[positionAxisID].getPixelForValue(value) + tl + tickPadding;
}
- textAlign = !rotation ? 'center' : 'right';
+ textAlign = me._getXAxisLabelAlignment();
} else if (axis === 'y') {
if (position === 'center') {
x = ((chartArea.left + chartArea.right) / 2) - tl - tickPadding;
textAlign = 'right';
}
+ if (axis === 'y') {
+ if (optionTicks.alignment === 'start') {
+ textBaseline = 'top';
+ } else if (optionTicks.alignment === 'end') {
+ textBaseline = 'bottom';
+ }
+ }
+
for (i = 0, ilen = ticks.length; i < ilen; ++i) {
tick = ticks[i];
label = tick.label;
label,
font,
textOffset,
- textAlign
+ textAlign,
+ textBaseline,
});
}
return items;
}
+ _getXAxisLabelAlignment() {
+ const me = this;
+ const {position, ticks} = me.options;
+ const rotation = -toRadians(me.labelRotation);
+
+ if (rotation) {
+ return position === 'top' ? 'left' : 'right';
+ }
+
+ let align = 'center';
+
+ if (ticks.alignment === 'start') {
+ align = 'left';
+ } else if (ticks.alignment === 'end') {
+ align = 'right';
+ }
+
+ return align;
+ }
+
/**
* @protected
*/
ctx.rotate(item.rotation);
ctx.font = tickFont.string;
ctx.fillStyle = tickFont.color;
- ctx.textBaseline = 'middle';
ctx.textAlign = item.textAlign;
+ ctx.textBaseline = item.textBaseline;
if (useStroke) {
ctx.strokeStyle = tickFont.strokeStyle;
--- /dev/null
+module.exports = {
+ config: {
+ type: 'line',
+ data: {
+ datasets: [{
+ data: [1, 2, 3],
+ }],
+ labels: ['Label1', 'Label2', 'Label3']
+ },
+ options: {
+ legend: false,
+ title: false,
+ scales: {
+ x: {
+ ticks: {
+ alignment: 'center',
+ },
+ },
+ y: {
+ ticks: {
+ alignment: 'center',
+ }
+ }
+ }
+ }
+ },
+ options: {
+ spriteText: true,
+ canvas: {
+ height: 256,
+ width: 512
+ }
+ }
+};
--- /dev/null
+module.exports = {
+ config: {
+ type: 'line',
+ data: {
+ datasets: [{
+ data: [1, 2, 3],
+ }],
+ labels: ['Label1', 'Label2', 'Label3']
+ },
+ options: {
+ legend: false,
+ title: false,
+ scales: {
+ x: {
+ ticks: {
+ alignment: 'end',
+ },
+ },
+ y: {
+ ticks: {
+ alignment: 'end',
+ }
+ }
+ }
+ }
+ },
+ options: {
+ spriteText: true,
+ canvas: {
+ height: 256,
+ width: 512
+ }
+ }
+};
--- /dev/null
+module.exports = {
+ config: {
+ type: 'line',
+ data: {
+ datasets: [{
+ data: [1, 2, 3],
+ }],
+ labels: ['Label1', 'Label2', 'Label3']
+ },
+ options: {
+ legend: false,
+ title: false,
+ scales: {
+ x: {
+ ticks: {
+ alignment: 'start',
+ },
+ },
+ y: {
+ ticks: {
+ alignment: 'start',
+ }
+ }
+ }
+ }
+ },
+ options: {
+ spriteText: true,
+ canvas: {
+ height: 256,
+ width: 512
+ }
+ }
+};
* @default ticks.length
*/
sampleSize: number;
+ /**
+ * The label alignment
+ * @default 'center'
+ */
+ alignment: 'start' | 'center' | 'end';
/**
* If true, automatically calculates how many labels can be shown and hides labels accordingly. Labels will be rotated up to maxRotation before skipping any. Turn autoSkip off to show all labels no matter what.
* @default true