plotly / dash-core-components

OBSOLETE: now part of https://github.com/plotly/dash
https://dash.plotly.com
MIT License
270 stars 147 forks source link

Add Case-Insensitive Sorting Option to Dash Data Table Component #1013

Open andre996 opened 2 months ago

andre996 commented 2 months ago

Description:

Implement a property in the Dash data table component to toggle between case-sensitive and case-insensitive sorting. In the current setup, sorting is case-sensitive, resulting in unexpected order. For example, when sorting alphabetically in descending order, 'CII' comes before 'Cee' due to case sensitivity. By introducing a case-insensitive sorting option, we can ensure consistent and expected behavior in sorting operations.

Workaround:

import dash
from dash import dcc, html, Input, Output
import dash_table
import pandas as pd

# Sample data
data = {
    'Name': ['A', 'CII', 'b', 'Cee'],
    'Age': [30, 25, 35, 28]
}

df = pd.DataFrame(data)

# Define the custom sorting function
def custom_sorting(data, column, direction):
    if direction == 'asc':
        return sorted(data, key=lambda x: x[column].lower())
    elif direction == 'desc':
        return sorted(data, key=lambda x: x[column].lower(), reverse=True)
    else:
        return data

app = dash.Dash(__name__)

app.layout = html.Div([
    dash_table.DataTable(
        id='datatable',
        columns=[{'name': i, 'id': i} for i in df.columns],
        data=df.to_dict('records'),
        sort_action='custom',  # Enable custom sorting
        sort_mode='multi',  # Allow sorting by multiple columns
        style_table={'overflowX': 'scroll'},
        style_cell={'minWidth': '100px', 'width': '100px', 'maxWidth': '100px'},
    ),
])

# Callback to update the DataTable with custom sorting
@app.callback(
    Output('datatable', 'data'),
    [Input('datatable', 'data_timestamp'),
     Input('datatable', 'sort_by')]
)
def update_table(timestamp, sort_by):
    if sort_by:
        column_id = sort_by[0]['column_id']
        direction = sort_by[0]['direction']
        return custom_sorting(df.to_dict('records'), column_id, direction)
    else:
        # If no sorting, return original data
        return df.to_dict('records')

if __name__ == '__main__':
    app.run_server(debug=True)