9 thoughts on “Pie Graph legend on left or right is not vertically centered.

  1. If not resolved yet, here is what he did:

    var textWidth = ctx.measureText(legendItem.text).width,
    width = boxWidth + (fontSize / 2) + textWidth,
    x = cursor.x,
    y = cursor.y;
    y += (ctx.canvas.clientHeight - (itemHeight * me.legendItems.length)) / 2;

    And the results:




    Thanks btw, I was looking for it.

    I added the following because it seems to bug the legend when it is not on the side of the chart.

    if(me.options.position == 'left' || me.options.position == 'right')
    y += (ctx.canvas.clientHeight - (itemHeight * me.legendItems.length)) / 2;

  2. I took a look at this and noticed that the proposed solution would exhibit the following issues

    1. ctx.canvas.clientHeight is not guaranteed to be the render height of the canvas. When window.devicePixelRatio > 1 the canvas will have more pixels that it’s CSS height
    2. itemHeight * me.legendItems.length will only give the legend height when there is one column of items. If there are enough data points, there will be multiple columns, and it will be incorrect

    Proposed Solution

    I think the better solution to this problem would be to update fit to store the height of each column. We already know it here. What we could do is save it into a new me._columnHeights array.

    Then, we provide a new config option

    legendOptions = {
      // options are 'start', 'end', 'center'. Default is 'start' which matches old behaviour
      align: 'start' 

    During drawing, if the option is 'start' the legend draws at the top. If it’s 'end' its at the bottom. 'center' does as expected. This option would apply to both horizontal and vertical legends and would need to be implemented accordingly for the horizontal case.

    CC @chartjs/maintainers for input

  3. Some additional thoughts:


    Edit: updated proposal, pack renamed to align, align renamed to labels.align, labels.boxAlign replaced by labels.stretch

  4. Any news on this? Currently I’m turning off the built-in legend and using the legendCallback to build my own for this reason — which works well, but there are certain contexts where I want to use the built-in version

  5. I found that @guschnwg hack works a bit incorrectly when we have paddings

    So I changed this code:

    y += (ctx.canvas.clientHeight - (itemHeight * me.legendItems.length)) / 2;


    To the following:

    y += (ctx.canvas.clientHeight - (itemHeight * me.legendItems.length) - labelOpts.padding) / 2;


Comments are closed.