Repository: plotly/dash-ag-grid (language: python)

Issue:
Bug-PivotComparator Sorting Issue in Ag-Grid Pivoted Table
**Description:**

When attempting to implement the pivotComparator property on a pivoted table, using the function code from the [Ag-Grid documentation](https://www.ag-grid.com/javascript-data-grid/pivoting-column-groups/#reference-pivoting-pivotComparator) for sorting, the pivot table fails to work as expected. The data is neither compared nor sorted correctly.

**dash-ag-grid version:**
- 2.4.0 and 31.0.0

**Sample:**

```
import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd

import os

app = Dash(__name__)


df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)


columnDefs = [
    {"field": "country", "rowGroup": True, "enableRowGroup": True},
    {"field": "sport", "pivot": True, 
    "pivotComparator": {"function" : "(a, b) =>  {b.localeCompare(a)}"}
    },
    {"field": "year"},
    {"field": "date"},
    {"field": "gold", "aggFunc": "sum"},
]

defaultColDef = {"flex": 1, "minWidth": 150}


app.layout = html.Div(
    [
        dcc.Markdown("Demonstration of pivot in a Dash AG Grid."),
        dcc.Markdown(
            "The example below shows a simple pivot on the Sport column using the Gold, Silver and Bronze columns for values."
        ),
        dag.AgGrid(
            id="pivot-ag-grid-example",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            dashGridOptions={
                "autoGroupColumnDef": {"minWidth": 250},
                "animateRows": False,
                "pivotMode": True,
            },
            defaultColDef=defaultColDef,
            # Pivot groupings is an ag-grid Enterprise feature.
            # A license key should be provided if it is used.
            # License keys can be passed to the `licenseKey` argument of dag.AgGrid
            enableEnterpriseModules=True,
        ),
    ]
)


if __name__ == "__main__":
    app.run(debug=True)  
```


Note: Same behavior with the function on a JS file.
Bug-PivotComparator Sorting Issue in Ag-Grid Pivoted Table
**Description:**

When attempting to implement the pivotComparator property on a pivoted table, using the function code from the [Ag-Grid documentation](https://www.ag-grid.com/javascript-data-grid/pivoting-column-groups/#reference-pivoting-pivotComparator) for sorting, the pivot table fails to work as expected. The data is neither compared nor sorted correctly.

**dash-ag-grid version:**
- 2.4.0 and 31.0.0

**Sample:**

```
import dash_ag_grid as dag
from dash import Dash, html, dcc
import pandas as pd

import os

app = Dash(__name__)


df = pd.read_csv(
    "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
)


columnDefs = [
    {"field": "country", "rowGroup": True, "enableRowGroup": True},
    {"field": "sport", "pivot": True, 
    "pivotComparator": {"function" : "(a, b) =>  {b.localeCompare(a)}"}
    },
    {"field": "year"},
    {"field": "date"},
    {"field": "gold", "aggFunc": "sum"},
]

defaultColDef = {"flex": 1, "minWidth": 150}


app.layout = html.Div(
    [
        dcc.Markdown("Demonstration of pivot in a Dash AG Grid."),
        dcc.Markdown(
            "The example below shows a simple pivot on the Sport column using the Gold, Silver and Bronze columns for values."
        ),
        dag.AgGrid(
            id="pivot-ag-grid-example",
            columnDefs=columnDefs,
            rowData=df.to_dict("records"),
            dashGridOptions={
                "autoGroupColumnDef": {"minWidth": 250},
                "animateRows": False,
                "pivotMode": True,
            },
            defaultColDef=defaultColDef,
            # Pivot groupings is an ag-grid Enterprise feature.
            # A license key should be provided if it is used.
            # License keys can be passed to the `licenseKey` argument of dag.AgGrid
            enableEnterpriseModules=True,
        ),
    ]
)


if __name__ == "__main__":
    app.run(debug=True)  
```


Note: Same behavior with the function on a JS file.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3446337..aa819ac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ Links "DE#nnn" prior to version 2.0 point to the Dash Enterprise closed-source D
 
 ## unreleased
 ### Fixed
+ - [#325](https://github.com/plotly/dash-ag-grid/pull/325).  Fixes issue #324 where `pivotComparator` functions were not sorting columns correctly because they were only being passed `params`.
  - [#314](https://github.com/plotly/dash-ag-grid/pull/314)
    - locking selenium for tests that were failing due to missing import
  - [#313](https://github.com/plotly/dash-ag-grid/pull/313)
diff --git a/src/lib/utils/propCategories.js b/src/lib/utils/propCategories.js
index d0e9205..957cab1 100644
--- a/src/lib/utils/propCategories.js
+++ b/src/lib/utils/propCategories.js
@@ -184,6 +184,7 @@ export const COLUMN_MAYBE_FUNCTIONS_NO_PARAMS = {
 
     // Columns: Sort
     comparator: 1,
+    pivotComparator: 1,
 
     // filter params custom option
     predicate: 1,
@@ -223,9 +224,6 @@ export const COLUMN_MAYBE_FUNCTIONS = {
     suppressHeaderKeyboardEvent: 1,
     headerCheckboxSelection: 1,
 
-    // Columns: Pivoting
-    pivotComparator: 1,
-
     // Columns: Rendering and Styling
     cellStyle: 1,
     cellClass: 1,


Test patch:
diff --git a/tests/assets/dashAgGridFunctions.js b/tests/assets/dashAgGridFunctions.js
index b949b25..2128fa6 100644
--- a/tests/assets/dashAgGridFunctions.js
+++ b/tests/assets/dashAgGridFunctions.js
@@ -492,4 +492,10 @@ dagfuncs.showOutput = (params, setGridProps) => {
     setGridProps({'cellClicked': cellClicked})
 }
 
-// END test_event_listeners.py
\ No newline at end of file
+// END test_event_listeners.py
+
+// BEGIN test_pivot_column_order.py
+
+dagfuncs.sortColumns = (a, b) => b.localeCompare(a)
+
+// BEGIN test_pivot_column_order.py
diff --git a/tests/test_pivot_column_order.py b/tests/test_pivot_column_order.py
new file mode 100644
index 0000000..9358fa1
--- /dev/null
+++ b/tests/test_pivot_column_order.py
@@ -0,0 +1,64 @@
+import dash_ag_grid as dag
+from dash import Dash, html, dcc, Input, Output
+import pandas as pd
+
+
+
+def test_pi001_pivot_column_order(dash_duo):
+    app = Dash(__name__)
+
+    df = pd.read_csv(
+        "https://raw.githubusercontent.com/plotly/datasets/master/ag-grid/olympic-winners.csv"
+    )
+
+    columnDefs = [
+        {"field": "country", "rowGroup": True},
+        {"field": "sport", "pivot": True, "pivotComparator": {"function": "sortColumns"}},
+        {"field": "year"},
+        {"field": "date"},
+        {"field": "gold", "aggFunc": "sum"},
+    ]
+
+    app.layout = html.Div(
+        [
+            dag.AgGrid(
+                id="grid",
+                columnDefs=columnDefs,
+                rowData=df.to_dict("records"),
+                dashGridOptions={
+                    "autoGroupColumnDef": {"minWidth": 250},
+                    "pivotMode": True,
+                },
+                enableEnterpriseModules=True,
+            ),
+            html.Div(id="col-order"),
+        ],
+    )
+
+    @app.callback(
+        Output("col-order", "children"),
+        Input("grid", "columnState"),
+        prevent_initial_call=True,
+    )
+    def display_state(col_state):
+
+        # Pivot columns are identified in `columnState` by `colId`.
+        # If not specified by the user, the `colId` is auto-generated with a `pivot_{field name}` prefix.
+
+        pivot_columns = [
+            c["colId"] for c in col_state if c["colId"].startswith("pivot_sport")
+        ]
+
+        # By default, the columns are sorted in ascending order.
+        # This app uses a custom `pivotComparator` function to sort the columns in descending order.
+        # The following check verifies if the columns are correctly sorted in descending order.
+        descending = pivot_columns == sorted(pivot_columns, reverse=True)
+        return f"pivot columns sorted in reverse order? {descending}"
+
+    dash_duo.start_server(app)
+
+    dash_duo.wait_for_text_to_equal(
+        "#col-order", "pivot columns sorted in reverse order? True"
+    )
+
+