SlickGrid icon indicating copy to clipboard operation
SlickGrid copied to clipboard

Auto width columns based on column header length

Open alexcroox opened this issue 8 years ago • 6 comments

Apologies if this is already configurable, I couldn't find anything in the docs/wiki.

Is there a way to have the columns auto expand to the width of the column header?

I don't know the column headers ahead of time so I cannot set a custom minWidth as the table is using dynamic data from different sources every time.

The default looks like this for me on load:

https://cl.ly/iiT3/Screen%20Shot%202017-01-11%20at%2009.32.10.png

alexcroox avatar Jan 11 '17 09:01 alexcroox

how about forceFitColumns ? https://github.com/mleibman/SlickGrid/wiki/Grid-Options

6pac avatar Jan 11 '17 13:01 6pac

Unfortunately there could be a very large number of columns that would require horizontal scrolling.

For now I'm counting the char length of the column header, then taking an average of all the data char lengths for each column and setting the column minWidth based on the larger of the 2.

That gives me this

https://cl.ly/iiiz/Screen%20Shot%202017-01-11%20at%2013.14.33.png

alexcroox avatar Jan 11 '17 13:01 alexcroox

That sounds pretty optimal. Much better than a simple 1/n proportional model. Might be worth posting the code, it could be made a new option or plugin, since it's a pretty common need.

6pac avatar Jan 11 '17 13:01 6pac

It's fairly simple but sure I've ripped out the relevant parts:

// Generate random test data
function RandomDataItem(i) {
    this.id = "id_" + i;
    this.num = i;
    this.title = "Task " + i;
    this.duration = "5 days";
    this.percentComplete = Math.round(Math.random() * 100);
    this.start = "01/01/2009";
    this.finish = "01/05/2009";
    this.matchConfidence = (i % 5 == 0);
};

var data = [];
var columns = [
    { id: "sel", name: "#", field: "num", sortable: true },
    { id: "title", name: "Title", field: "title", sortable: true },
    { id: "duration", name: "Duration", field: "duration", sortable: true },
    { id: "%", name: "% Complete", field: "percentComplete", sortable: true },
    { id: "start", name: "Start", field: "start", sortable: true },
    { id: "finish", name: "Finish", field: "finish", sortable: true },
    { id: "match-confidence", name: "Match Confidence", field: "matchConfidence", sortable: true }
];

// Fill our example data
for (var i = 0; i < 500000; i++) {
    data[i] = new RandomDataItem(i);
}

var dataLengths = {};

// Loop through our data set and store the sum length and count for each column's data
_.each(data, function(dataItem) {

    _.each(dataItem, function(value, key) {

        // ID is used internally by SlickGrid and
        // isn't one of our columns
        if(key == "id")
            return true;

        if(typeof dataLengths[key] === "undefined")
            dataLengths[key] = { count: 0, sum: 0 };

        dataLengths[key].sum += String(value).length;
        dataLengths[key].count++;
    });
});

// Adjust column minWidth option based on title and data length
_.each(columns, function(col) {

    var titleLength = col.name.length;
    var colAverageLength = Math.round(dataLengths[col.field].sum / dataLengths[col.field].count) - 2;

    // Get the larger of the 2 and multiply by an arbitrary number based on custom column padding
    col.minWidth = Math.max(titleLength, colAverageLength) * 15;
});

// Init SlickGrid...

alexcroox avatar Jan 11 '17 13:01 alexcroox

thanks, saves probably 45 minutes of drudge!

6pac avatar Jan 11 '17 13:01 6pac

No worries, could prob be a bit smarter about taking into account cell padding css so you don't need weird arbitrary numbers like I put in the last 2 lines

alexcroox avatar Jan 11 '17 13:01 alexcroox

cleaning up old issues... this should now be supported per Ben's column auto-resize implementation, see Example - size by content

ghiscoding avatar May 12 '23 22:05 ghiscoding