Skip to content

Commit

Permalink
Add max_items parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
wch committed Jul 17, 2023
1 parent 634fffc commit d1a953e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
7 changes: 6 additions & 1 deletion examples/ml/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,18 @@
ui.panel_main(
ui.h3("Dynamic output, display_winner=True"),
ui.output_ui("label1"),
ui.h3("Static output, display_winner=True", style="margin-top: 3rem;"),
ui.h3(
"Static output, display_winner=True, max_items=2",
style="margin-top: 3rem;",
),
ui.ml.classification_label(
{
"Tigers": 32,
"Lions": 60,
"Bears": 15,
},
display_winner=True,
max_items=2,
),
ui.h3("Static output, sort=False"),
ui.ml.classification_label(
Expand All @@ -24,6 +28,7 @@
"Lions": 60,
"Bears": 15,
},
max_items=3,
sort=False,
),
),
Expand Down
34 changes: 32 additions & 2 deletions js/ml/classification-label.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,23 @@ export class ShinyClassificationLabel extends LitElement {
@property({ type: Number }) sort: number = 1;
@property({ type: Number, attribute: "display-winner" })
displayWinner: number = 0;
@property({ type: Number, attribute: "max-items" })
maxItems: number | null = null;

render() {
const entries = Object.entries(this.value);
let entries = Object.entries(this.value);

if (this.maxItems !== null) {
entries = truncateEntries(entries, this.maxItems);
}

if (this.sort) {
entries.sort((a, b) => b[1] - a[1]);
}

let winnerHTML = null;
if (this.displayWinner) {
// Entries might not be sorted
// Entries might not be sorted, so we need to loop through again.
const currentWinner = { name: "", value: -Infinity };
entries.forEach(([k, v]) => {
if (v > currentWinner.value) {
Expand All @@ -87,3 +93,27 @@ export class ShinyClassificationLabel extends LitElement {
return html`<div class="wrapper">${winnerHTML} ${valuesHtml}</div> `;
}
}

customElements.define("shiny-classification-label", ShinyClassificationLabel);

function truncateEntries(entries: [string, number][], maxItems: number | null) {
// Just the numeric values
const values = entries.map(([_, v]) => v);
values.sort().reverse();

const cutoffValue = values[maxItems - 1];

const newEntries = [];
for (const entry of entries) {
if (entry[1] >= cutoffValue) {
newEntries.push(entry);
// In case there are multiple items that match cutoffValue, we need to make sure
// we don't add more entries than were asked for.
if (newEntries.length === maxItems) {
break;
}
}
}

return newEntries;
}
2 changes: 2 additions & 0 deletions shiny/ui/ml.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def classification_label(
*,
sort: Optional[bool] = None,
display_winner: Optional[bool] = None,
max_items: Optional[int] = None,
_add_ws: bool = True,
**kwargs: TagAttrValue,
) -> Tag:
Expand All @@ -28,6 +29,7 @@ def classification_label(
value=attr_to_escaped_json(value),
sort=bool_to_num(sort),
display_winner=bool_to_num(display_winner),
max_items=max_items,
_add_ws=_add_ws,
**kwargs,
)
Expand Down

0 comments on commit d1a953e

Please sign in to comment.