Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question [v2]: Align for legendItems #3367

Closed
Kurtas opened this issue Sep 26, 2016 · 7 comments
Closed

Question [v2]: Align for legendItems #3367

Kurtas opened this issue Sep 26, 2016 · 7 comments

Comments

@Kurtas
Copy link

Kurtas commented Sep 26, 2016

Hi,

When I had set ``postion: 'bottom'` for legend, then the legend is generated under the chart but legendItems are centered. Is there any way how to align legendItems to left in bottom position (like 2 example in picture)?

Preview

Thanks

@etimberg
Copy link
Member

This looks like a general case of needing to change the alignment for legend rows. Right now we assume center alignment.

@rodrigoimenes
Copy link

@Kurtas @etimberg Any update about this?

@etimberg
Copy link
Member

No work has been done on this. If someone wants to trying making this work, we can look over a PR but it's not likely to be done soon

@rodrigoimenes
Copy link

I will try to modify this behavior for always left aligning... Any hint where i can modify that?

@etimberg
Copy link
Member

The legend is in https://github.com/chartjs/Chart.js/blob/master/src/core/core.legend.js

Likely need changes to the update and draw methods

@rodrigoimenes
Copy link

rodrigoimenes commented Oct 11, 2016

I made some changes to the code that served for my case, and i know this solution is VERY UGLY, but i think that can help somebody in a future solution...

In file Chart.bundle.js, find this:

var itemHeight = fontSize + labelOpts.padding;
helpers.each(me.legendItems, function(legendItem, i) {

And change this:

var itemHeight = fontSize + labelOpts.padding;
helpers.each(me.legendItems, function(legendItem, i) {
    var textWidth = ctx.measureText(legendItem.text).width,
         width = labelOpts.usePointStyle ?
          fontSize + (fontSize / 2) + textWidth :
          boxWidth + (fontSize / 2) + textWidth,
         x = cursor.x,
         y = cursor.y;

    if (isHorizontal) {
        if (x + width >= legendWidth) {
            y = cursor.y += itemHeight;
            cursor.line++;
            x = cursor.x = me.left + ((legendWidth - lineWidths[cursor.line]) / 2);
        }
    } else if (y + itemHeight > me.bottom) {
        x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
        y = cursor.y = me.top;
        cursor.line++;
    }

For this:

var minX = false, maxTextWidth = 0, temp = 0;
var itemHeight = fontSize + labelOpts.padding;
// iterate over legend Itens to get the MAX SIZE of an legend item based on its text
helpers.each(me.legendItems, function(legendItem, i) {
    temp = ctx.measureText(legendItem.text).width;
    if (temp > maxTextWidth) {
        maxTextWidth = temp;
    }
});

//Max itens per column
var itemsPerColumn = parseInt(legendWidth / (maxTextWidth + me.left + labelOpts.padding));

//Get the size of the line and the itens per column, with this we can put it on "center"
var spaceBorder = ((legendWidth / itemsPerColumn) - maxTextWidth) / 2;

helpers.each(me.legendItems, function(legendItem, i) {
// Here we change the width based on legend text for a default size based on max length of all legends
    var textWidth = maxTextWidth,
          width = labelOpts.usePointStyle ?
            fontSize + (fontSize / 2) + textWidth :
            boxWidth + (fontSize / 2) + textWidth,
          x = cursor.x,
          y = cursor.y;

    // On first iteration, we set x based on space used to center things
    if (!minX) {
        minX = cursor.x = x = spaceBorder;
    }

    if (isHorizontal) {
        // This + 10 represents a little tolerance for dont breaking lines
        if (x + width >= legendWidth + 10) {
            y = cursor.y += itemHeight;
            cursor.line++;
            // Here we set spaceBorder when lines are breaking, making them align by it
            x = cursor.x = minX;
        }
    } else if (y + itemHeight > me.bottom) {
        x = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;
        y = cursor.y = me.top;
        cursor.line++;
    }

Hope this helps. Im out of time to get this on, but i will try make it best someday.

@etimberg
Copy link
Member

General legend alignment got discussed in #3175
Closing in favour of that issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants