I have a bar chart where I have drawn 3 vertical lines, each with it's own label at the top. I would like those labels to be above the top of the y-axis (above the 30% line in the example) but below the legend. I can't figure out how to increase the space between the top legend and the chart such that I can have my vertical line labels (15, 24 & 33) be off of the chart itself but below the legend. Any ideas?
13 Answers
If you want do increase spacing in all charts you can put this code before creating :
Chart.Legend.prototype.afterFit = function() {
this.height = this.height + 50;
};
Of course, I don't try but i think you can change it (or copy the original Chart object before, to keep the original padding).
Bye,

- 821
- 1
- 10
- 14
-
4This works perfectly. Exactly what I was looking for, thank you! – Steve Bauman Apr 24 '19 at 13:49
-
1I posted that 2 years ago, I think there is a trick to do this if the legend is below – Dorian Maliszewski Mar 24 '20 at 15:28
-
@DorianMaliszewski Ah nice, do you have a link? I'm currently going through the rounds myself trying to fix this issue... – A Friend Mar 24 '20 at 19:03
-
1@DorianMaliszewski any updated version? Granted I'm very new to chartjs, but it doesn't appear to work with 3.9.1. – Nov 02 '22 at 17:57
-
this no longer works at all in newer versions. – Pepe Alvarez Dec 16 '22 at 17:08
If you want to apply padding below legend for some charts only in your app:
ChartJS >= 2.1.0
Chart.plugins.register({
id: 'paddingBelowLegends',
beforeInit: function(chart, options) {
chart.legend.afterFit = function() {
this.height = this.height + 50;
};
}
});
// ----------------------------------
// disable the plugin only for charts
// where you DO NOT WANT the padding
// ----------------------------------
// for raw ChartJS use:
var chart = new Chart(ctx, {
config: {
plugins: {
paddingBelowLegends: false
}
}
});
// for angular-chartjs:
$scope.myChart.options.plugins = { paddingBelowLegends: false }
// then in template:
// <canvas class="chart ..." chart-options="myChart.options" ... />
ChartJS >= 2.5.0
Specific plugins for each chart are supported, it should be possible to do:
var chart = new Chart(ctx, {
plugins: [{
beforeInit: function(chart, options) {
chart.legend.afterFit = function() {
this.height = this.height + 50;
};
}
}]
});
See ChartJS documentation + inspired by this other answer

- 22,336
- 11
- 85
- 113
If anyone is wondering why the afterFit
solution is not working in Chart.js 3.3.0 it is because the afterFit
function was removed from the legend plugin.
If you want to make this work anyway by taking advantage of the fit
function, you can try this hacky solution / workaround:
const plugin = {
beforeInit(chart) {
// Get a reference to the original fit function
const originalFit = chart.legend.fit;
// Override the fit function
chart.legend.fit = function fit() {
// Call the original function and bind scope in order to use `this` correctly inside it
originalFit.bind(chart.legend)();
// Change the height as suggested in other answers
this.height += 15;
}
}
}
I know that this is not an ideal solution, but until we have native support for this legend padding, I'm afraid this is as good as we can do right now.

- 11
- 3

- 2,694
- 2
- 23
- 23
Unfortunately, since there is no config option to handle this the only way you can achieve the desired result is to extend Chart.Legend and implement the afterFit()
callback.
Here is a quick codepen showing how to do just that. To change the spacing, just change the value in line 9 (currently set to 50). Also, this of course only works with the legend at the top. Hopefully, the example is clear enough for you to modify in case you want to move your legend elsewhere.

- 10,449
- 1
- 37
- 42
-
1I understand the basic concept of what you did here, though I would never had a chance on my own. Thanks. This works perfectly!! – Bryan Lewis Mar 03 '17 at 23:36
-
Ok, so perhaps you can help with one minor issue. This solution looks perfect, but I can no longer click on the individual items in the legend to toggle the data on and off. Any thoughts? – Bryan Lewis Mar 03 '17 at 23:37
-
@BryanLewis In the codepen example, I'm able to click on the legend items without any issue (is it not working for you in the codepen?) If you are talking about your specific implementation (not codepen example) then make sure you copy line 13 - 60 in my example (its what allows the clicks to behave correctly) – jordanwillis Mar 04 '17 at 06:04
-
Your codepen example works and I copied everything, but it still doesn't work for me. I think something else in my chart.js code may be interfering. I will test further. Thanks. – Bryan Lewis Mar 07 '17 at 04:11
-
1@jordanwillis I tried your codepen sample. It worked but in my case legends were aligned in center after applying this legends are no longer center aligned. Legends are at top position. – Sonali Dec 26 '17 at 05:25
-
When you say center aligned do you mean your legend position is set to left? If so then you need to adjust the `width` property in the new legend instead of the `height`. If that is not what you meant then I'm not sure what you mean by center aligned. – jordanwillis Dec 26 '17 at 07:27
This helped me after 2 days of research.
Chart.Legend.prototype.afterFit = function() {
this.height = this.height + 50;
};
update this in module.ts file

- 29,388
- 11
- 94
- 103

- 2,331
- 23
- 25
I'm using react-chartjs-2 (but this is just a port and uses the same configurations object) and I was able to achieve that by changing the labels configuration nested on legend configuration:
chartOptions = {
legend: {
labels: {
padding: 50 -> this one.
}
},
You can check the property description here: https://www.chartjs.org/docs/latest/configuration/legend.html
Hope it helps.

- 378
- 3
- 8
-
20This does add some padding to multiple rows of legend items, but it doesn't explicitly add whitespace between the legend and the graph. – Ringo Nov 19 '19 at 19:20
-
Also, note that the path is chart.options.plugins.legend.labels.padding – BurninLeo Apr 03 '22 at 14:55
I have tried the above approaches on my react(react-chartjs-2) project but no luck. Here I have one different approach like creating custom legends outside the chart. so you can get more control over it
- Hide default legend
- Get legend object using any ref method.
- Loop and make a custom legend using html and css.
- Sample codesanbox
I am aware that OP is not about reactjs component, but as it is a common issue it will help someone.
.

- 4,414
- 4
- 42
- 54
If you want to apply padding below legend for some charts only in your app:
ChartJS >= 2.1.0
Note: make sure to add this in plugins
and not inside options.plugins
.
Chart.plugins.register({
id: 'paddingBelowLegends',
beforeInit: function(chart, options) {
chart.legend.afterFit = function() {
this.height = this.height + 50;
};
}
});
// ----------------------------------
// disable the plugin only for charts
// where you DO NOT WANT the padding
// ----------------------------------
// for raw ChartJS use:
var chart = new Chart(ctx, {
config: {
plugins: {
paddingBelowLegends: false
}
}
});
For React Users using react-chartjs-2
:
import { Line } from "react-chartjs-2";
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from "chart.js";
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend);
<Line
data={{
datasets: trendsData?.map((trend, idx) => ({
type: "line",
label: trend.domainName,
data: trend.domainTrends.map(d => d.value),
backgroundColor: getDomainColor(idx).backgroundColor,
borderColor: getDomainColor(idx).color,
pointRadius: 0,
tension: 0.3
})),
labels: trendsData?.[0]?.domainTrends.map(d => d.date)
}}
options={{
plugins: {
legend: {
display: true,
align: "start",
labels: {
font: { size: 14 }
}
}
}
}}
plugins={[
{
id: "increase-legend-spacing",
beforeInit(chart) {
// Get reference to the original fit function
const originalFit = (chart.legend as any).fit;
// Override the fit function
(chart.legend as any).fit = function fit() {
// Call original function and bind scope in order to use `this` correctly inside it
originalFit.bind(chart.legend)();
this.height += 20;
};
}
}
]}
/>

- 93
- 1
- 7
For ng2-charts@^3.1.0
, following this answer works with an addition:
this.options.labels.padding = 40;
//this.height += 15;
or the title.padding
config (this'll create an invisible title under the graph so it's a bit hacky):
plugins: {
legend: {
display: true,
position: 'bottom',
title: {
display: true,
padding: 10,
},

- 39,722
- 10
- 72
- 98
-
1title actually adds some padding but it is located just above the lexend box, in the position that OP set up its legend. – Pepe Alvarez Dec 16 '22 at 17:06
After searching the chart.js file I found out that the height of the labels bar is defined there in
height = this._fitRows(titleHeight, fontSize, boxWidth, itemHeight)
OR
this.height = Math.min(height, options.maxHeight || this.maxHeight)
in the fit() function
fit() {
const {options, ctx} = this;
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);
} else {
height = this.maxHeight;
width = this._fitCols(titleHeight, fontSize, boxWidth, itemHeight);
}
this.width = Math.min(width, options.maxWidth || this.maxWidth);
this.height = Math.min(height, options.maxHeight || this.maxHeight) + 40;}
And I changed it to +40 as shown above. and it worked fine for me so I wanted to share.

- 13
- 4
I know this is not what OP really wants but at least for newer version, and the one I use - 4.0.1 - there is no way to increase the margin between the legend box and the chart, that I have been able to find at least, so this is an obvious workaround. So in order to avoid this problem:
I had to change the position of the leyend box below the chart with this option configurations:
options = {
layout: {
padding: 30
},
parsing: {
key: 'nested.value'
},
plugins: {
datalabels: {
color: '#36A2EB'
},
tooltip: {
enabled: true
},
legend: {
position: 'bottom',
align: 'center',
labels: {
padding: 20,
}
}
}
};
Note: To add the values at the top of the bars I had to add the npm package chartjs-plugin-datalabels with the following features inside your datasets config:
datasets: [
{
label: "Ejercido",
data: source.map( s => s.ejercidoTotal),
datalabels: {
anchor: 'end',
clamp: true,//this makes one datalabel not visible if it crashed with other one
display: 'auto',
align: 'top',
color: '#333333',
formatter
}
},
...
]
With this as the end result:

- 1,218
- 1
- 9
- 15
If you are using react-chartjs-2
library to show chart in a React app. You can use the below solution:
const plugin = {
beforeInit: function (chart) {
// Get reference to the original fit function
const originalFit = chart.legend.fit
// Override the fit function
chart.legend.fit = function fit() {
// Bind scope in order to use `this` correctly inside it
originalFit.bind(chart.legend)()
this.height += 20 // Change the height
}
}
}
export const ReactChart2Example = (props) => {
const { data = [] } = props;
return (
<div>
<Chart plugins={[plugin]} type ="bar" data={data}/>
</div>
);
};
We have to pass plugins
prop separately in React js Chart component and not inside options
.
Reference: https://github.com/chartjs/Chart.js/issues/10388#issuecomment-1217363379

- 2,338
- 1
- 10
- 14
You can use layout property under options. This helped me:
layout: {
padding: {
left: 50,
right: 130,
top: 0,
bottom: 0
}
}

- 1
- 1
-
3This is wrong. This is the padding around the entire canvas, not between the legend and chart. – kennysong Feb 04 '21 at 11:56