I need to edit same dataframes when using Streamlit and found this very nice component AgGrid. However, I'm working with long text and I need to resize the rows to wrap the text in each cell. I need somtheing like st.table does:
How can I get the same type of wrapping AgGrid?
Thanks
EDIT:
Based in the accepted answer:
gb = GridOptionsBuilder.from_dataframe(df)
gb.configure_columns("COLUMN_NAME",wrapText = True)
gb.configure_columns("COLUMN_NAME",autoHeight = True)
You can either add
wrapText: true,
autoHeight: true
to the defaultColdef property of the grid to do this for all columns,
or to specific column definitions in the columnDefs property.
Related
Using the answer provided by aka863 here: How to split merged Excel cells with Python?
I can unmerge, fill values and copy the styling. My questions is how to make the value assigning/filling process configurable.
I want the user to be able to choose whether the values will be filled vertically/horizontally.
I have tried changing the last loop where we assign the top_left_cell_values to unmerged cells. However I couldn't find a way to make it horizontal/vertical configurable. (I'm planning to use radio buttons and tkinter for this)
Its certainly possible to have the code de-merge cells and fill cells in whichever direction, vertically or horizontally regardless of which way the merge was originally. Or not fill at all, so only the top left cell retains the 'value' of the previously merged cells, which is default on unmerge.
Changing the direction of the fill requires some change and re-calculation on the max row and column values in the iter_rows loop, but is simple enough.
However it seems in your last comment you just want to give the user the option to fill or not fill on horizontal merges. In that case you just need to ask the question, and then run the iter_rows loop only if the response is yes.
The code sample below is based on the answer referenced question.
I'm assuming only single line horizontal merges since you dont mention what if anything should be done with vertical merges in the comment.
The code does initially check and indicate the merge direction either vertically or horizontally so it can be included take some action if a merge is vertical.
On code run after displaying the range and direction of the merge, the question is asked to fill, yes or no. If yes the cells are de-merged and all cells filled with the top left cell value using the iter_rows loop. If answer no then the cells are just de-merged.
from openpyxl import load_workbook
from openpyxl.utils.cell import range_boundaries
wb = load_workbook(filename='foo.xlsx')
st = wb['Sheet1']
mcr_coord_list = [mcr.coord for mcr in st.merged_cells.ranges]
direction_dict = {'v': 'vertical', 'h': 'horizontal'}
for mcr in mcr_coord_list:
print('---------------------------------------------------\n')
merge_direction = ''
min_col, min_row, max_col, max_row = range_boundaries(mcr)
top_left_cell_value = st.cell(row=min_row, column=min_col).value
if min_col == max_col:
merge_direction = 'v'
elif min_row == max_row:
merge_direction = 'h'
print(f"The cell range {mcr} is merged {direction_dict[merge_direction]}ly with the data '{top_left_cell_value}'")
while True:
demerge_fill = input('Do you want the de-merge to fill all cells(y|n)? ')
if demerge_fill.lower() in ["y", "n"]:
break
else:
print('Invalid response')
st.unmerge_cells(mcr)
if demerge_fill == 'y':
for row in st.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
else:
print(f"Only the top left cell {mcr.split(':')[0]} will contain the data!")
wb.save('merged_tmp.xlsx')
In ag-Grid, if the columns occupy a smaller space than the width of the grid, a blank hole appears on the right of the last column. Please see below (example taken from ag-Grid docs):
The UX designers on my team don't like that. They would like to see the rows extended all the way to the right to balance out the look. Is this possible to do with ag-Grid?
Edit: We don't want to use the sizeColumnsToFit option, because on large monitors it produces very wide columns and the grid becomes unreadable. We want to use the autoSize option to compact the columns and fill the hole on the RHS with blank stripes as suggested above.
Yes it is possible. You can call the sizeColumnsToFit function on the ag-Grid api which will fill out the width of the table with the columns.
Take a look at documentation.
Here is a plunker example.
EDIT
Use the property suppressSizeToFit and set it to true to when you call sizeColumnsToFit, it won't have an affect. Apply this property to the defaultColDef and set it to false for the last column. This was, when you call sizeColumnsToFit, only the last column will be set to full width. See the updated plunker above.
this is how i do it:
/**
* if there is "dead space" present on the grid, the columns will be auto sized to fill the gap
* #param gridApi
* #param columnApi
*/
resizeColumnsToFit(gridApi: GridApi, columnApi: ColumnApi, allowShrink = false) {
if (allowShrink) {
gridApi.sizeColumnsToFit();
} else {
const gridBodyWidth = document.getElementsByClassName("ag-root-wrapper")[0].clientWidth; // todo: use grid's id instead of [0] to allow multiple grids on a page
const allColumnsWidth = columnApi.getAllDisplayedColumns().map(c => c.getActualWidth()).reduce((a, b) => a + b, 0);
if (gridBodyWidth > allColumnsWidth) {
gridApi.sizeColumnsToFit();
}
}
}
This method will size columns to fit only when there is "dead" space on the right. Optionaly set allowShrink to true to force resizing even if there is no dead space
I had the same situation and resolved with the following css override:
.ag-center-cols-container {
width: 100% !important;
}
One possible option I've been playing with is adding a fake column at the end to fill the remaining space. To do so, you just need to add a column with options similar to the following to the end of your list of columns:
{
flex: 1,
headerName: '',
}
See this plunker forked from #ViqMontana's example above.
It's not a perfect solution, but wanted to mention it here in case it helps.
This works like Craig Weston's answer but without the need for !important:
.ag-center-cols-container {
min-width: 100%;
}
In my developed grid with column grouping, there is white empty space is appear at end when resize the columns. Any Suggestion?[![enter image description here][1]][1]
You can call sizeColumnsToFit() after columnRowGroupChanged event:
columnRowGroupChanged A row group column was added or removed.
.html template event binding
(columnRowGroupChanged)="groupChanged($event)"
or .ts gridOptions event binding (don't forget to define [gridOptions] in .html)
this.gridOptions:{
onColumnRowGroupChanged : this.groupChanged.bind(this)
}
handling
groupChanged(params){
params.api.sizeColumnsToFit();
}
DEMO
Starting from ag-grid 23.1.0, we no longer have to use sizeColumnsToFit. Instead, in column definition, add flex: 1 to the last visible column.
This prevents all annoying jumps and weird grid behavior when resizing columns. In case user enlarge the column, horizontal scrollbar will appear, which is the expected behavior.
Please go over your code and change sizeColumnsToFit to the flex solution.
Flex also gives you control over relative column sizes, you can read more about it in the docs: https://www.ag-grid.com/javascript-grid-resizing/.
Example:
columnDefs = [{...}
...
{
headerName: 'HeaderA',
field: 'name',
...
flex: 1, // Adding this to last column definition
}]
All my searches turned up for sizeColumnsToFit and autoSizeColumns which is not what I want.
My grids have many columns, so it scroll horizontal which is fine
But I cannot know in advance what would be the most space needed for the widest text in a column, so want the grid to auto size all columns to accommodate for whatever is the longest line of text in the cell.
Can one do that? (pretty much like have nowrap on a html table column, not that ag-grid wrap text, it just hide what is too long)
Grid Resizing:
https://www.ag-grid.com/javascript-grid-resizing/
sizeColumnsToFit - this tries to squeeze all the columns in the view - no horizontal scrolling
autoSizeAllColumns - this tries to size all columns to to fit the data - horizontal scrolling
// If you need to resize specific columns
var allColIds = params.columnApi.getAllColumns()
.map(column => column.colId);
params.columnApi.autoSizeColumns(allColIds);
// If you want to resize all columns
params.columnApi.autoSizeAllColumns();
I passed through this and it took me some time to make it work the way I wanted to, by that I mean :
Use all the available space
Make each column take the width required to display its content correctly
Solution :
Add the width parameter for each column (requires some manual tuning to set the right values)
Call gridApi.sizeColumnsToFit() in the onGridReady which will resize to take the available space while making sure that columns having bigger width will take more space
const gridOptions = {
...
columnDefs: [
{
...,
width: 100
},
{
...,
width: 50
},
...
],
...
onGridReady: (event) => event.api.sizeColumnsToFit();
};
Simply use flex instead of width in the column definitions. The grid will adjust automatically.
You can find a complete example for auto resizing all column.
column-sizing
Simply call autoSizeColumns() function, all columns will be resized according to content.
gridColumnApi.autoSizeColumns(allColumnIds, skipHeader);
I want to change font and color of a specific cell in a ListGrid.
I succeeded to change the color of the entire row with the following lines, but not of a single row:
for (ListGrid table : tables)
{
ListGridField[] columns = table.getFields();
for (Record record : table.getRecords())
{
....
record.setAttribute("cssText",
"font-weight:bold; font-size:80%; color:#FF3300;");
I don't want to use getCellCSSText function, i tried the following but it didn't work:
ListGridField gridfield = table.getField(columns[1].getName());
gridfield.setAttribute("cssText",
"font-weight:bold; font-size:80%; color:#FF3300;");
table.refreshFields();
I'm sure there is a better way to do it. But this is how i did it:
I added a hidden column to the table, that contain the color.
In getCellCSSText i read the color and the column name and set the color.
Is there a way to add an invisible parameter to a ListGridRecord? So that i won't add an entire column.