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
 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
153
154
155
156
157
158
159
160
161
@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:
        logger.debug(
            "we had a None df in SubsetCard, loading directly from State.")
        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():
        logger.debug(key + ": promising length")
        length = df[df.pipeline == subset.dataset].count()[()]

        # BUG: this bypassses the AssertionError on chunks
        try:
            filtered_length_promise = dff.count(delay=True)
            logger.debug(key + ": promising length")
            dff.execute()
            filtered_length = filtered_length_promise.get()[()]
            logger.debug(key + ": length received = " + str(filtered_length))
        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])

    # check if filtered and set progress percentage
    not_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:0.4" 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
76
@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():
                logger.debug("rendering card" + str(key))
                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