Skip to content

subset_ui

Main user-facing subset components

SubsetCard(key) #

Holds filter update info, card structure, and calls to options.

State variables
  • filter: subset crossfilter hook
  • open: whether the panel is expanded or not

Parameters:

Name Type Description Default
key str

subset key

required

Returns:

Name Type Description
main ValueElement

SubsetCard element

Source code in src/sdss_explorer/dashboard/components/sidebar/subset_ui.py
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
@sl.component()
def SubsetCard(key: str) -> ValueElement:
    """Holds filter update info, card structure, and calls to options.

    State variables:
        * `filter`: subset crossfilter hook
        * `open`: whether the panel is expanded or not

    Args:
        key: subset key

    Returns:
        main: SubsetCard element
    """
    subset = SubsetState.subsets.value[key]
    open, set_open = sl.use_state(False)
    df = subset.df
    if df is None:
        df = State.df.value
    filter, _set_filter = use_subset(id(df), key, "subset-summary")
    name = subset.name

    # progress bar logic
    if isinstance(filter, vx.Expression):
        # filter from plots or self
        dff = df[filter]
    else:
        # not filtered at all
        dff = df

    def get_lengths():
        length = df.count()[()]

        # BUG: this bypassses the AssertionError on chunks
        try:
            filtered_length_promise = dff.count(delay=True)
            dff.execute()
            filtered_length = filtered_length_promise.get()[()]
        except AssertionError as e:
            from ...dataclass import Alert

            Alert.update(color="error", message="Failed to retrieve n rows!")
            filtered_length = 0

        return length, filtered_length

    length, filtered_length = sl.use_memo(get_lengths,
                                          dependencies=[dff, filter])

    filtered = filtered_length < length
    denom = max(length, 1)
    progress = filtered_length / denom * 100

    with rv.ExpansionPanel(v_model=open, on_v_model=set_open) as main:
        with rv.ExpansionPanelHeader():
            with sl.Row(gap="0px"):
                rv.Col(cols="4", children=[name])
                rv.Col(
                    cols="8",
                    class_="text--secondary",
                    children=[
                        rv.Icon(
                            children=["mdi-filter"],
                            style_="opacity:e0.1" if not filtered else "",
                        ),
                        f"{filtered_length:,}",
                    ],
                )

        with rv.ExpansionPanelContent():
            # filter bar
            with sl.Column(gap="12px"):
                sl.ProgressLinear(value=progress, color="blue")
                SubsetOptions(key, lambda: SubsetState.remove_subset(key))
    return main

SubsetMenu() #

Control and display subset cards

State variables
  • add: whether the add dialog is open
  • name: the text input state of the name of new subset to be added
  • model: the open model, used to have first subset be open on initialize.
Source code in src/sdss_explorer/dashboard/components/sidebar/subset_ui.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@sl.component()
def SubsetMenu() -> ValueElement:
    """Control and display subset cards

    State variables:
        * `add`: whether the add dialog is open
        * `name`: the text input state of the name of new subset to be added
        * `model`: the open model, used to have first subset be open on initialize.
    """
    add = sl.use_reactive(False)
    name, set_name = sl.use_state("")  # new name of subset
    model, set_model = sl.use_state(0)

    def add_subset(name):
        "Wrapper on Subset Add to support dialog interface"
        if SubsetState.add_subset(name):
            close()

    def close():
        """Dialog close handler; resets state variables."""
        add.set(False)
        set_name("")
        return

    with sl.Column(gap="0px") as main:
        with rv.Card(class_="justify-center",
                     flat=True,
                     style_="width: 100%; height: 100%"):
            rv.CardTitle(
                class_="justify-center",
                children=["Subsets"],
            )
            with rv.CardText():
                with sl.Tooltip("Create filtered subsets of the dataset"):
                    sl.Button(
                        label="Add new subset",
                        on_click=lambda: add.set(True),
                        block=True,
                    )
        with rv.ExpansionPanels(flat=True,
                                popout=True,
                                v_model=model,
                                on_v_model=set_model):
            for key in SubsetState.subsets.value.keys():
                SubsetCard(key).key(key)
        with Dialog(
                add,
                title="Enter a name for the new subset",
                close_on_ok=False,
                on_ok=lambda: add_subset(name),
                on_cancel=lambda: set_name(""),
        ):
            sl.InputText(
                label="Subset name",
                value=name,
                on_value=set_name,
            )

    return main