Source code for meerkat.interactive.app.src.lib.component.core.sort

import uuid
from typing import Any, Dict, List, Sequence, Union

from pydantic import BaseModel

from meerkat.dataframe import DataFrame
from meerkat.interactive.app.src.lib.component.abstract import Component
from meerkat.interactive.graph import reactive


class SortCriterion(BaseModel):
    id: str
    is_enabled: bool
    column: str
    ascending: bool
    source: str = ""


def _format_criteria(
    criteria: Sequence[Union[SortCriterion, Dict[str, Any]]]
) -> List[SortCriterion]:
    # since the criteria can either be a list of dictionary or of SortCriterion
    # we need to convert them to SortCriterion
    return [
        criterion
        if isinstance(criterion, SortCriterion)
        else SortCriterion(**criterion)
        for criterion in criteria
    ]


@reactive()
def sort_by_criteria(
    data: DataFrame,
    criteria: Sequence[Union[SortCriterion, Dict[str, Any]]],
) -> DataFrame:
    """Wrapper around mk.sort that adds unpacking of store to the DAG."""
    import meerkat as mk

    # Since the criteria can either be a list of dictionary or of SortCriterion
    # we need to convert them to SortCriterion
    criteria = _format_criteria(criteria)

    # Filter out criteria that are disabled.
    criteria = [criterion for criterion in criteria if criterion.is_enabled]
    if len(criteria) == 0:
        return data.view()

    sort_by = [criterion.column for criterion in criteria]
    ascending = [criterion.ascending for criterion in criteria]

    return mk.sort(data, by=sort_by, ascending=ascending)


[docs]class Sort(Component): df: DataFrame criteria: Union[List[SortCriterion], SortCriterion] = [] title: str = "Sort" classes: str = ""
[docs] def __init__( self, df: DataFrame, *, criteria: List[SortCriterion] = [], title: str = "Sort", classes: str = "", ): """This component handles a sort_by list and a sort_order list. Sorting criteria are maintained in a Store. On change of these values, the dataframe is sorted. This component will return a Reference object, which is a sorted view of the dataframe. The sort operation is out-of-place, so a new dataframe will be returned as a result of the op. Args: df: The dataframe to sort. criteria: The sorting criteria to use. """ super().__init__(df=df, criteria=criteria, title=title, classes=classes)
def __call__(self, df: DataFrame = None) -> DataFrame: if df is None: df = self.df return sort_by_criteria(df, self.criteria) @staticmethod @reactive() def create_criterion(column: str, ascending: bool, source: str = ""): return SortCriterion( id=str(uuid.uuid4()), is_enabled=True, column=column, ascending=ascending, source=source, )