Conditional filtering with Inputs.select

I am trying to learn a good way to provide a custom value for Inputs.select (in this case “All”) and then subset the number of rows to plot based on that. Using the penguins dataset that it straightforward if I am using levels of a variable that are in the data already. But for something like “All”, I really only know how to do a conditional like this:

pplot = {
  let pplot;
  if (pen_types == "All") {
    return pplot = penguins;
  } else {
    return pplot = penguins.filter(aq.escape(d => op.includes(d.species, pen_types)));
  }
}

So this is saying "if pen_types is “All” I want the whole dataset, otherwise subset the rows based on the value of pen_types. This seems verbose to me. For example is there any way within filter that I can just say “if ‘All’ give me all the rows” or something like this? Notebook here:

Oh maybe the ternary operator is what I need:

 foo = {
  return (pen_types === "All")
  ? penguins // If pen_types is "All", no filtering is applied
  : penguins.filter(aq.escape(d => op.includes(d.species, pen_types)));
 }

You can also filter directly in Plot which will preserve the original domains:

    Plot.dot(penguins, {
      y: "body_mass_g",
      x: "bill_length_mm",
      fill: "species",
      filter: pen_types === "All" ? true : d => d.species === pen_types
    })
1 Like

Ah yes I always forget about that. In my case I have multiple dropdowns and multiple filtering steps so I think it is easier to separate out (i think?).

Difficult to tell without a concrete example. You can combine filters by using a pattern like

filters = [
  // changing the filter callback on the fly
  pen_types === "All"
    ? () => true
    : d => d.species === pen_types,
  // creating a Set in a closure to avoid Array.includes()
  (set => d => set.has(d.island))(new Set([selected_islands])),
  // a basic filter callback
  d => d.bill_length_mm >= min_length
]
    Plot.dot(penguins, {
      y: "body_mass_g",
      x: "bill_length_mm",
      fill: "species",
      filter: d => filters.every(func => func(d))
    })