score:11
There are a few ways to control padding between scales/legends in chart.js (some official ways documented in the docs and some "hacky" ways described elsewhere). The problem is, there just isn't a way to use the existing configuration options to control padding through out the chart (left scale, bottom scale, top scale...or bottom of legend, etc.).
Fortunately, because of the flexible chart.js interfaces (and because we can create new scale types, etc.), it is still possible to control the padding without too much fuss. Let me explain the way to add left, top, and bottom padding and then provide a working example at the end very end (skip ahead if you so desire).
Left Padding
This one is easy. There is a documented option to control this. Just set the scales.yAxes.ticks.padding
option to whatever value you want. Here is an example.
scales: {
yAxes: [{
ticks: {
beginAtZero: true,
padding: 25,
}
}]
}
Top Padding (or Legend Padding)
There is no option to control this so we have to build it in. I built it in by creating a new Legend object and overwriting the afterFit()
function that uses a paddingBottom
option set on the options object. This isn't too difficult but requires a round around way to do it. Here is the relevant code.
function getBoxWidth(labelOpts, fontSize) {
return labelOpts.usePointStyle ?
fontSize * Math.SQRT2 :
labelOpts.boxWidth;
};
Chart.NewLegend = Chart.Legend.extend({
afterFit: function() {
this.height = this.height + this.options.paddingBottom;
},
});
function createNewLegendAndAttach(chartInstance, legendOpts) {
var legend = new Chart.NewLegend({
ctx: chartInstance.chart.ctx,
options: legendOpts,
chart: chartInstance
});
if (chartInstance.legend) {
Chart.layoutService.removeBox(chartInstance, chartInstance.legend);
delete chartInstance.newLegend;
}
chartInstance.newLegend = legend;
Chart.layoutService.addBox(chartInstance, legend);
}
// Register the legend plugin
Chart.plugins.register({
beforeInit: function(chartInstance) {
var legendOpts = chartInstance.options.legend;
if (legendOpts) {
createNewLegendAndAttach(chartInstance, legendOpts);
}
},
beforeUpdate: function(chartInstance) {
var legendOpts = chartInstance.options.legend;
if (legendOpts) {
legendOpts = Chart.helpers.configMerge(Chart.defaults.global.legend, legendOpts);
if (chartInstance.newLegend) {
chartInstance.newLegend.options = legendOpts;
} else {
createNewLegendAndAttach(chartInstance, legendOpts);
}
} else {
Chart.layoutService.removeBox(chartInstance, chartInstance.newLegend);
delete chartInstance.newLegend;
}
},
afterEvent: function(chartInstance, e) {
var legend = chartInstance.newLegend;
if (legend) {
legend.handleEvent(e);
}
}
});
Bottom Padding
There is also no option to control this, so we have to also build it in. Since we are dealing with a scale here, the best way to do this is extending the 'category' scale and add logic to handle a scale paddingTop
option. After reading through the source, we need to overwrite the draw()
function to do this. Here is the relevant code (see my example for the full implementation).
// ...
if (isHorizontal) {
if (options.position === 'bottom') {
// bottom
textBaseline = !isRotated? 'top':'middle';
textAlign = !isRotated? 'center': 'right';
labelY = me.top + tl + me.options.paddingTop;
} else {
// top
textBaseline = !isRotated? 'bottom':'middle';
textAlign = !isRotated? 'center': 'left';
labelY = me.bottom - tl;
}
}
// ...
Here is a codepen example showing all this put together.
score:0
This does not add padding between the chart and legend but the above code no longer seems to work on Chart.js v3 and above. Here is a workaround plugin that pads the y-axis to ensure labels (only checked with chartjs-plugin-datalabels) fall within the chart.
var pluginAutoAdjustRangeY = {
id: 'autoAdjustRangeY',
beforeInit: function(chartInstance) {
var legendOpts = chartInstance.options.legend;
if (legendOpts) {
chartInstance.legend.afterFit = function(){
var max = 0;
var min = 0;
var datasets = chartInstance.data.datasets.length
for(let i = 0; i < datasets; i++){
var points = chartInstance.data.datasets[i].data.length
for(let p = 0; p < points; p++){
var v = parseFloat(chartInstance.data.datasets[i].data[p]);
if(v > max) max = v;
if(v < min) min = v;
}
}
var range = parseInt((max - min) * ((chartInstance.options.legend.padding) || 0));
chartInstance.options.scales.y.max = parseInt(max + range);
if(min !== 0) chartInstance.options.scales.y.min = parseInt(min - range);
}
}
},
beforeLayout: function(chartInstance) { //2
if(chartInstance.options.legend){
if(chartInstance.legend.afterFit){
chartInstance.legend.afterFit();
}
}
},
};
And can be used by as such:
options: {
legend: {
padding: 0.15, //percentage of Y range to pad ends of axis
}
}
score:1
For ChartJs version 3 you can remove tickLenght:
scales: {
x: {
grid: {
tickWidth:0,
tickLength: 0,
},
y: {
grid: {
tickWidth:0,
tickLength: 0,
},
...
}
score:8
Edit: This does not provide provide padding inside the chart (which is what this question is originally about), but rather adds a padding around the chart
For those still looking for this that might end up here in a google search (like me), it seems to have been solved in a later version: https://www.chartjs.org/docs/latest/configuration/layout.html#padding
let chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
layout: {
padding: {
left: 50,
right: 0,
top: 0,
bottom: 0
}
}
}
});
Source: stackoverflow.com
Related Query
- chartjs - top and bottom padding of a chart area
- ChartJS Line chart cut off at the top and bottom
- ChartJs multiaxis chart show different label bottom and top
- Show X axis on top and bottom in line chart rendered with Chart.js 2.4.0
- ChartJs - Double tooltip Top and Bottom on hover
- how to write labels along with data on top and bottom of each stack in bar chart
- How do you create rounded corners on the top and bottom of a bar chart and the between 2 part still draw like image?
- Chart.js adds unwanted padding on top and below chart with padding set to 0
- ChartJs - width scale of chart area and label area
- Chart area background color chartjs
- Chartjs 2 - Stacked bar and unstacked line on same chart with same y axis
- chartjs datalabels change font and color of text displaying inside pie chart
- Category scale on Y-axis and time on x-axis in bubble chart in Chartjs
- ChartJS disable gridlines outside chart area
- Chartjs not rendering chart and no error thrown
- Increase padding between legend and chart with react-chartjs-2
- Add a custom label to the top or bottom of a stacked bar chart
- How to show data values in top of bar chart and line chart in chart.js 3
- ChartJS line chart drag and zoom
- ChartJS (React) Line Chart - How to show single tooltip with data and labels from 3 (multiple) dataset?
- Create Chart using Reactjs Chartjs and axios
- Why would a ChartJS chart end up with width 0 and height 0?
- Points cut at half at the edges of top and bottom, at chartjs
- Meteor and ChartJS dynamically create a chart
- Remove padding from chartJs horizontal bar chart
- Grouped Bar Chart from mySQL database using ChartJS and PHP
- Chartjs - Set start and end value into a Bar Chart
- ChartJS and Radar Chart animation
- how to highlight a specific area on chartjs line chart
- ChartJS automatically scaled chart has undefined min and max
More Query from same tag
- create a multi line chart using Chart.js
- Chartjs columns does not appear by value
- Charts.js graph not displaying
- Chart js display empty plot
- Custom tooltip callback on one dataset (chartjs v 2.5)
- Chartjs updating point titles
- Chart.js canvas rendered by ng-repeat does not show charts
- Beginner in JS,Stuck with ChartJS and multiple filters and ways to display
- Chart.js moment locale
- Chart.js, adding footer to chart
- How to disable event during a state change
- Chart.js two categorical scales
- How to have chart.js automatically build x-axis labels based on x,y dataset?
- Resizing vue-chartjs height while keeping it responsive
- Changing color of specific chartjs point
- ng-chart.js - First data set always has color gray
- Proper way to use a counter variable in HTML/Javascript
- ChartJS date reformatting for use?
- Alternating bars in bar chart in chart.js are not labelled
- Chart area background color chartjs
- Chart.js different scaleLine color of radar chart (angular)
- Chart.js legend alignment
- Auto-Remove old Datapoints in Chart.js
- ChartJS GridLine Dynamically
- How to use set the color for each bar in a bar chart using chartjs?
- Chart.js - Toggle visibility of charts
- Plot time on Y axis
- Chart js logarithmic line chart showing NaN values instead of null
- Cannot create property 'datasets' on string
- Removing axes lines on chart.js