HAVE YOU ALREADY SEARCHED FOR SIMILAR ISSUES? PLEASE HELP US OUT AND DOUBLE-CHECK FIRST!
ALSO, PLEASE DON'T BE THAT PERSON WHO DELETES THIS TEMPLATE. IT'S HERE FOR A REASON.
THANKS!
WHICH VERSION OF REACT ARE YOU USING?
Officially Supported:
[XX] v0.14.x
Community Supported:
[ ] v15.0.x
WHICH BROWSER ARE YOU USING?
Officially Supported:
[ ] IE 9 / IE 10 / IE 11
[ ] Edge
[ XX] Chrome
Should work:
[ ] Firefox
[ ] Safari
I'm submitting a ... (check one with "x")
[ ] bug report
[XX ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/adazzle/react-data-grid/blob/master/CONTRIBUTING.md
Current behavior
The width of the columns change only during resizing
Expected/desired behavior
Need to dynamically update the existing column width. For example: Grid should adjust the column width based on the data received. If the data for a column is very short, then we can apply a min column width or if the data is big, we can apply a bigger column width.
Condition about the width can be derived after we receive the data.
Reproduction of the problem
If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem.
What is the expected behavior?
What is the motivation / use case for changing the behavior?
Sorry, I was able to achieve this.
Hi could you please provide an example how you solved this? I am trying to achieve the same thing :)
Please share how could you able to achieve this.
@bevikram , @slackday ,
It's a bit hacky solution.
I calculated the updated width based upon the longest text. Here is how it works:
If there is any better solution, please feel free to share it.
+1
I'm surprised there isn't more demand for this, I expected this to be default behaviour like a html table header or excel column. @phkavitha are you able to share your code before I reproduce the solution myself?
Thanks
@nevace, Due to my company policy, I don't think I'm allowed to paste the code. I've written the logic in my above comment which I used to calculate the max width of each column based on the values. I can certainly help if we have a dedicated branch to include the feature
@phkavitha no problem, it was mainly for the benefit of any other users with the same issue because I feel like it would be expected behaviour.
My first solution was similar to yours by measuring the string length and multiplying it by an offset. This failed with long headers of multiple of words due to the offset not being large enough. Increasing the offset made the column width of smaller headers far too wide.
I'm currently thinking about getting the scrollWidth of the element with the largest string in an initial render and then updating the columns with the proper width. Sounds hacky but we'll see.
@nevace and @phkavitha , can you share a snippet if your implementations?
Curious to see how you both have handled it with an array of objects.
This is long but works perfectly. I'm calculating the width of the longest column data cell and column data, then setting the width of the column to that + padding of the cell.
Any remaining space left in the width of the grid is distributed equally between the columns (with any remainder going on the first column).
I'm using canvas to measure the text width and it's accurate, you can use any font.
You can remove arrowWidth if you don't have sorting on, it just adds the extra space needed for the arrow when your click to sort.
These are simplified snippets and I haven't tested them, but for the same reason as @phkavitha I can't give the full source. I'm happy to get it working on a codesandbox if you want to set everything up:
formatColumns(data) {
const {columns} = data;
const gridWidth = parseInt(document.querySelector('.data-grid').clientWidth); //selector for grid
let combinedColumnWidth = 0;
for (let column of columns) {
column.width = this.getTextWidth(data, col);
combinedColumnWidth += column.width;
}
if (combinedColumnWidth < gridWidth) {
columns = this.distributeRemainingSpace(combinedColumnWidth, columns, gridWidth)
}
}
getTextWidth(data, col) {
const rowValues = [];
const reducer = (a, b) => a.length > b.length ? a : b;
const cellPadding = 16;
const arrowWidth = 18;
let longestCellData, longestCellDataWidth, longestColName, longestColNameWidth, longestString;
for (let row of data.rows) {
rowValues.push(row[col.key].displayValue || '');
}
longestCellData = rowValues.reduce(reducer);
longestColName = colName.reducer(reducer);
longestCellDataWidth = Math.ceil(this.getCanvas().measureText(longestCellData).width);
longestColNameWidth = Math.ceil(this.getCanvas('bold ').measureText(longestColName).width) + arrowWidth;
longestString = Math.max(longestCellDataWidth, longestColNameWidth);
return longestString + cellPadding;
}
getCanvas(fontWeight = '') {
if (!this.canvas) {
this.canvas = document.createElement('canvas');
this.canvasContext = this.canvas.getContext('2d');
}
this.canvasContext.font = `${fontWeight}13px arial`;
return this.canvasContext;
}
distributeRemainingSpace(combinedColumnWidth, columns, gridWidth) {
const spaceLeftOver = gridWidth - combinedColumnWidth;
const remainder = spaceLeftOver % columns.length;
const equalSpaceLeft = spaceLeftOver - remainder;
columns[0].width += remainder; //any remaining space after distributing equally should go on first column
for (let column of columns) {
col.width += (equalSpaceLeft / columns.length);
}
return columns;
}
Hi, @nevace can you share the complete snippet of your code as i am facing difficulty in implementing your example. Thanks for support Peace
If you can set up a code sandbox or something with a grid on, I'm happy to implement the above into it.
@nevace Thank For your reply i have configured the basic example react data grid https://codesandbox.io/s/z6524w26k4
Hi @OmerAli,
I've made a rough example.. it needs cleaning up but you can see how it works.
https://codesandbox.io/s/rlwpmxwlwp
I didn't realise how rough the code snippet above was, I didn't do it in an editor so didn't realise how many syntax errors there were and what things were missing!
If you look at line 143, set that to your font to get an accurate measurement of text width.
If you notice the description column goes on forever. We ended up adding a max column width with css ellipsis to stop this scenario ie (if text width is more than MAX_WIDTH, column.width = MAX_WIDTH).
Let me know if you have any issues.
@nevace Thanks for your help will update you soon regarding any issue
Thanks A lot peace
@nevace thanks for this 😃. React Data grid is cool, but as per their examples I couldn't find an option to put my description text anywhere else but manipulating tree structure.
Is their any other way, like clicking on a title cell for a given cell, will open up a description box or so?
Thanks ✌
Most helpful comment
Hi could you please provide an example how you solved this? I am trying to achieve the same thing :)