AgGrid: How to change the aggregate values for some of the columns dynamically at run time? - ag-grid

I am using Ag grid's row grouping feature and for some of the columns I have predefined aggFunc.
What I am trying to achieve is that once the grid is loaded with all the data, I want to hide some of the aggregate values (on row as well as leaf children) for some columns based on some conditions.
I checked AgGrid's API docs and tried below but unfortunately nothing works for me.
onButtonClick() {
this.gridApi.forEachNode((node, index) => {
if (node.field === 'xyz') {
// node.aggFunc.abc = 0; // not working
// node.aggData.abc = null; // not working
// node.setDataValue('abc', null); // not working
}
}
}
Any help would be appreciated.
Thanks

try this
columnApi.setColumnAggFunc(colKey, () => '')

Related

How can I update data within Detail table and don't loose range selection and filters?

I have latest enterprise React agGrid table with Master/Detail grid. My data is fetched on the client every 5 seconds and then put immutably to the redux store. React grid component is using deltaRowDataMode={true} props and deltaRowDataMode: true in Detail options.
My master grid performs normally as expected: if I have range selected, grid would keep selection after the data updates, so would filters and visibility menu would be still opened. But Detail grid behaves differently: on data refresh selections are being removed, visibility menu closes and grid jumps if filters were changed.
I've read in docs that when I open Detail grid it's being created from scratch, but in my case I don't close Detail. Anywhere I've tried keepDetailRows=true flag, which solved problems with jumping on update and selection loss, but Detail grid doesn't update data now.
It seems there are only two possible options according to the docs https://www.ag-grid.com/javascript-grid-master-detail/#changing-data-refresh. The first one is a detail table redraws everytime a data in a master row changes and the second one is a detail row doesn't changes at all if a flag suppressRefresh is enabled. Strange decision, awful beahviour...
Update.
Hello again. I found a coupe of solutions.
The first one is to use a detailCellRendererParams in table's options and set suppressRefresh to true. It gives an opportunity to use getDetailGridInfo to get detail-table's api.
While the detail-table's refreshing is disabled, using detailGridInfo allows to set a new data to a detail-table.
useEffect(() => {
const api = gridApiRef;
api && api.forEachNode(node => {
const { detailNode, expanded } = node;
if (detailNode && expanded) {
const detailGridInfo = api.getDetailGridInfo(detailNode.id);
const rowData = detailNode.data.someData; // your nested data
if (detailGridInfo) {
detailGridInfo.api.setRowData(rowData);
}
}
});
}, [results]);
The second one is to use a custom cellRenderer, wicth is much more flexible and allows to use any content inside a cellRenderer.
In table's options set detailCellRenderer: 'yourCustomCellRendereForDetailTable.
In yourCustomCellRendereForDetailTable you can use
this.state = {
rowData: [],
}
Every cellRenderer has a refresh metod which can be used as follow.
refresh(params) {
const newData = [ ...params.data.yourSomeData];
const oldData = this.state.rowData;
if (newData.length !== oldData.length) {
this.setState({
rowData: newData,
});
}
if (newData.length === oldData.length) {
if (newData.some((elem, index) => {
return !isEqual(elem, oldData[index]);
})) {
this.setState({
rowData: newData,
});
}
}
return true;
}
Using method refresh this way gives a fully customizable approach of using a detailCellRenderer.
Note. To get a better performance with using an immutable data like a redux it needs to set immutableData to true in both main and detail tables.

Is there way to auto resize percentage columns when column group is collapsed/expaned in NatTable

I found ResizeColumnHideShowLayer class at nattable version 1.6.
(about https://bugs.eclipse.org/bugs/show_bug.cgi?id=521486)
That is work fine for normal column headers only.
But, if I collapse a column group, no adjust size to fit window. (no increasing column size)
How can I solve the problem?
Is there way to resize other columns to fit window automatically increase?
Thank you.
Currently not because the ColumnGroupExpandCollapseLayer is taking care of hiding collapsed columns.
I found solution by myself!
It works fine very well. :-)
I was run based on NatTable v1.6 version.(downloaded yesterday)
I think this is a basic feature, so I hope this feature will be included in the next NatTable version.
In narrow tables, behavior that collapsing column group means that may be someone want to view other column data more widely.
Overview (Problem screen and solved screen)
I explain using two application(before, after) screen shot.
Refer to bottom image if you want understand my issue easily at once.
Problem screen
enter image description here
Improved screen
enter image description here
Solution summary :
Add event listener to ColumnGroupExpandCollapseLayer.
      (HideColumnPositionsEvent, ShowColumnPositionsEvent)
Handle above events.
      Get column indices which is hidden by collapsed
      Execute MultiColumnHideCommand with the indices
Layer structure of my test code
↑ ViewportLayer (top layer)
| SelectionLayer
| ColumnGroupExpandCollapseLayer
| ResizeColumnHideShowLayer
| ColumnGroupReorderLayer
| ColumnReorderLayer
| DataLayer (base layer)
Implementation code is below:
void method() {
...
columnGroupExpandCollapseLayer.addLayerListener(new ILayerListener() {
#Override
public void handleLayerEvent(ILayerEvent event) {
boolean doRedraw = false;
//It works for HideColumnPositionsEvent and ShowColumnPositionsEvent
// triggered by ColumnGroupExpandCollapseCommandHandler
if (event instanceof HideColumnPositionsEvent) {
HideColumnPositionsEvent hideEvent = (HideColumnPositionsEvent)event;
Collection<Range> columnPositionRanges = hideEvent.getColumnPositionRanges();
Collection<Integer> convertIntegerCollection = convertIntegerCollection(columnPositionRanges);
int[] positions = convertIntPrimitiveArray(convertIntegerCollection);
//Execute command to hide columns that was hidden by collapsed column group.
MultiColumnHideCommand multiColumnHideCommand = new MultiColumnHideCommand(resizeColumnHideShowLayer, positions);
resizeColumnHideShowLayer.doCommand(multiColumnHideCommand);
doRedraw = true;
}else if (event instanceof ShowColumnPositionsEvent) {//called by ColumnGroupCollapsedCollapseCommandHandler
ShowColumnPositionsEvent showEvent = (ShowColumnPositionsEvent)event;
Collection<Range> columnPositionRanges = showEvent.getColumnPositionRanges();
Collection<Integer> positions = convertIntegerCollection(columnPositionRanges);
//Execute command to show columns that was hidden by expanded column group.
MultiColumnShowCommand multiColumnShowCommand = new MultiColumnShowCommand(positions);
resizeColumnHideShowLayer.doCommand(multiColumnShowCommand);
//Set whether or not to redraw table
doRedraw = true;
}
if (doRedraw) {
natTable.redraw();
}
}
/**
* Merge position values within several Ranges to Integer collection
*/
private Collection<Integer> convertIntegerCollection(Collection<Range> rangeCollection) {
Iterator<Range> rangeIterator = rangeCollection.iterator();
Set<Integer> mergedPositionSet = new HashSet<Integer>();
while (rangeIterator.hasNext()) {
Range range = rangeIterator.next();
mergedPositionSet.addAll(range.getMembers());
}
return mergedPositionSet;
}
/**
* Convert Integer wrapper object to primitive value
*/
private int [] convertIntPrimitiveArray(Collection<Integer> integerCollection) {
Integer [] integers = (Integer [])integerCollection.toArray(new Integer[integerCollection.size()]);
int [] positionPrimitives = new int[integers.length];
for (int i = 0 ; i < integers.length ; i++) {
positionPrimitives[i] = integers[i].intValue();
}
return positionPrimitives;
}
});
}

How can I use handleExpandChartChange event to monitor expanded rows in SAPUI5 Gantt Chart?

I need to record the list of rows that expanded in a Gantt chart in a SAPUI5 program.
I found this handleExpandChartChange event but there is no attach function for this. Does anyone have any idea that how do we have to use it or any other method to know about the extended rows?
I solved my problem. We have to use treeTableToggleEvent event to monitor the expanded or collapsed rows.
For this we can use the following function as a event handler for treeTableToggleEvent:
onTreeTableToggleEvent: function (oEvent) {
var oParameters = oEvent.getParameters();
if (oParameters.rowIndex >= 0 && oParameters.expanded) {
if (!this._aExpandedRows.includes(oParameters.rowIndex)) {
this._aExpandedRows.push(oParameters.rowIndex);
}
} else if (oParameters.rowIndex >= 0 && !oParameters.expanded) {
var iIndex = this._aExpandedRows.indexOf(oParameters.rowIndex);
if (iIndex > -1) {
this._aExpandedRows.splice(iIndex, 1);
}
}
},
For using this function we need the _aExpandedRows array to initiate to empty array when we initiate the Gantt chart.
this._aExpandedRows = [];
The expanded row indices are stored in _aExpandedRows array.
I solved the monitoring problem of the expansion of nodes. But still I am interested in how to use handleExpandChartChange event.

How to add a row style dynamically ? - Ag-grid

I want to change the style of a row dynamically in ag-grid. What I'm trying to achieve is to change the background color of my ag-grid row if the row has been edited by the user.
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
this.edittedRows[event.rowIndex.toString()] = event.data;
}
}
I'm keeping track of the edited row by listening to cellValueChanged event. I need to change the row style here.
I've looked into ag-grid documentation and found how to add row styles, row classes and row class rules but I could't find a way to add a style to a row dynamically when the user has changed something on it.
By using redrawRows I was able to achieve this.
First I added rowClassRules for my grid options like below
private initGrid() {
this.gridOptions.rowClassRules = {
'modified' : this.isEditedRow()
};
}
private isEditedRow() {
return (params) => {
return params.data.edited;
}
}
modified is my css class which has all the styles for an edited row.
Then in my row data I'm adding a new property edited.
And changed the cellValueChanged as below,
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
// Setting edited flag to change the background
event.data.edited = true;
this.edittedRows[event.rowIndex.toString()] = event.data;
let row = this.gridApi.getDisplayedRowAtIndex(event.rowIndex);
this.gridApi.redrawRows({ rowNodes: [row] });
}
}
Find the documentation for redrawRows here.
Add below line in your CellValueChanged Function:
gridOptions.rowStyle = {background: 'coral'};
cellValueChanged(event) {
//Add it only if the old value has changed
if (event.oldValue != event.newValue) {
// This will replace with latest edited value if it has been edited already
this.edittedRows[event.rowIndex.toString()] = event.data;
gridOptions.rowStyle = {background: 'coral'};
}
}
Plunker - https://plnkr.co/edit/i1K3YXpGGgNEOU2JjZCf?p=preview

GWT Cell Table Column Sort Handler

Im using a GWT Cell Table with sorting enabled on the columns. I am also providing an option of filtering the column. This is roughly how the header looks.
----ColumnName (Image) -------
When the user clicks on the image, i start off a filtering process. I achieved this using the Cell Table's addCellPreviewHandler. The issue I am facing is , when the image is clicked , the column sorts itself too. Can anyone tell me how to prevent this from happening ? To be clearer, I want the sort to be called when the user clicks anywhere in the header but the image.
Thanks.
breakDownCellTable.addColumn(indexedColumn, columnHeader);
final int currentColumnIndex = columnIndex;
// Add a ColumnSortEvent.ListHandler to connect sorting to the
// java.util.List.
ListHandler<List<GwtContributorCellData>> columnSortHandler = new ListHandler<List<GwtContributorCellData>>(contributorList);
columnSortHandler.setComparator(indexedColumn, new Comparator<List<CustomClass>>() {
public int compare(List<CustomClass> o1, List<CustomClass> o2) {
if (o1 == o2) {
return 0;
}
// Compare the columns.
if (o1 != null) {
return (o2 != null) ? o1.get(currentColumnIndex).compareTo(o2.get(currentColumnIndex)) : 1;
}
return -1;
}
});
breakDownCellTable.addColumnSortHandler(columnSortHandler);
and in the onBrowserEvent method:
if("click".equals(event.getType())){
EventTarget eventTarget = event.getEventTarget();
if(eventTarget.toString().contains("img") && !eventTarget.toString().contains("<th")){
//event.stopPropagation();
// Window.alert("here");
//breakDownCellTable.fireEvent()
ColumnSortEvent.fire(breakDownCellTable, breakDownCellTable.getColumnSortList());
Your can implement a subclass of the cell you're using and override the onBrowserEvent() method.
This post explains how to find out which DOM element is the exact source of the event.
Once you know that the image has been clicked or not, fire the filtering / sorting event accordingly.