Better Support for Removing Margins/Padding
See original GitHub issueI’m working on developing a plugin for the Wavesurfer project (https://github.com/katspaugh/wavesurfer.js) which will use Chart.js to overlay a line chart on top of an audio waveform, per the screenshot below:

As you can see from the screenshot, I have a 20 second audio file with the initial data point at 0 seconds and the final data point at 20 seconds. I need the initial and final data points to line up with the beginning and end of the graph so that each data point corresponds precisely to the timestamps in the audio file but this is proving difficult.
Ideally, there would be an option to place the X and Y axis labels inside the graph itself, rather than treating them as having a discrete width/height that acts as a padding around the graph. This setting would vastly simplify things, so I guess that would be the “feature request” part of this issue.
Failing this setting, this is the current approach I’m using (which gets me very close to where I want to be):
Step 1 – Remove the Y-Axis label with “display: false”. This removes most but not all of the padding on the right-hand side.
Step 2 – Suppress the initial and final labels from displaying via:
ticks: {
callback: function(value, index, values) {
if (index !== 0 && index !== 10) {
return value;
} else {
return '';
}
},
This gets me very close to having no padding but there is still 5px or so of padding at the beginning and end:

This seems like a bug to me. Why is there a 5px margin by default when there are no labels to draw? An additional potential bug is that I can only reduce the padding in the ticks callback by returning an empty string. If I return null instead, the resulting padding is much larger than is produced by using an empty string (which is counter-intuitive so I almost didn’t think to try the empty string).
Step 3 – Use negative margins in an xAxes afterBuildTicks callback to remove the slim padding that’s left:
afterBuildTicks: function(axis) {
axis.margins.left = '-5px';
axis.margins.right = '-5px';
},
This gets us where we want to be:

Step 4 – You can actually reintroduce the xAxes labels now by manually adding spaces into the values to pad them out so the first and last labels are offset inward:
ticks: {
callback: function(value, index, values) {
const padding = ' ',
lastValue = values.length - 1;
if (index !== 0 && index !== lastValue) {
return value;
} else if (index) {
return value + padding;
} else {
return padding + value;
}
},
You can see I’m almost there…

Step 5 – Step 5 would be to find a way to reintroduce the Y-Axes label in a way that won’t add more padding back in. Note that increasing the amount of negative padding to compensate does not work. I suspect I can theoretically render a second graph which does contain the Y-Axis labels and overlay this second graph on top of the first to achieve the effect of having the labels visible inside the graph. Unfortunately, I’m not sure how I’d have the second graph show the labels but not the data. Is that possible?
Anyway, I wanted to submit all this as an issue because when I googled what I’m trying to do, all that came up is https://github.com/chartjs/Chart.js/issues/4135
In that issue, other users were asking essentially about my use case and (in my opinion) an incorrect answer was given – that the desired styling is only possible by modifying the core library. I believe that through the use of what I outlined above, you can eliminate the padding in many cases without touching Chart.js source.
That said:
-
I’d love to see the whole thing simplified via a setting that lets all the labels render inside the chart area itself, instead of in the margins. Is this doable currently via using the lifecycle hooks to manually manipulate certain values?
-
I still am not sure how I can render the YAxes labels without reintroducing padding, so I’d also appreciate any help there.
Thanks!
Issue Analytics
- State:
- Created 6 years ago
- Reactions:12
- Comments:6 (3 by maintainers)
To remove a bit more padding on the Y axis you could try setting
gridLines.drawTicks
tofalse
.@etimberg thank you 👍
gridLines.drawTicks
tofalse
worked for me.