Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chart.js - Increase spacing between legend and chart

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?

Example Chart

like image 328
Bryan Lewis Avatar asked Mar 03 '17 18:03

Bryan Lewis


People also ask

How do I set the size of a ChartJS?

To set the chart size in ChartJS, we recommend using the responsive option, which makes the Chart fill its container. You must wrap the chart canvas tag in a div in order for responsive to take effect. You cannot set the canvas element size directly with responsive .

How do you wrap a legend text in ChartJS?

To make this behave the same as standard Chart. js charts, the function onLegendClicked is invoked when a mouse click occurs on a legend label. This function toggles the hidden state of individual datasets and changes label text style between normal and strike-through.


4 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,

like image 76
Dorian Maliszewski Avatar answered Oct 28 '22 15:10

Dorian Maliszewski


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

like image 43
Frosty Z Avatar answered Oct 28 '22 15:10

Frosty Z


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.

like image 20
jordanwillis Avatar answered Oct 28 '22 15:10

jordanwillis


If anyone is wondering why the afterFit solution is not working in Chart.js 3.3.0 it is because afterFit function was removed from the legend plugin.

If you want to make this work anyway by taking advantage over the fit function, you can try this hacky solution / workaround:

const plugin = {
  beforeInit(chart) {
    // Get reference to the original fit function
    const originalFit = chart.legend.fit;

    // Override the fit function
    chart.legend.fit = function fit() {
      // Call original function and bind scope in order to use `this` correctly inside it
      originalFit.bind(chart.legend)();
      // Change the height as suggested in another 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 we can do right now.

like image 17
Glogo Avatar answered Oct 28 '22 14:10

Glogo