v1.6.0

<bmx-pivot-slicer>

A slicer for a bmx-pivot-grid: the members of one field as buttons the reader clicks to filter the pivot - any field, whether or not it is placed on the pivot. Beside each member is how many records it has under the pivot's other filters, and members that would leave nothing are dimmed (or hidden), so several slicers side by side narrow the data together.

9 properties · 1 events · 4 methods · 8 parts

Example

Click members to filter. Each slicer shows how many records its members have under the other slicers' choices; the channel slicer hides the ones that would leave nothing. The channel is not placed on the pivot at all - a slicer can filter any field.
Show markup
<div class="row" role="group" aria-label="Slicers">
  <bmx-pivot-slicer for="ex-ps-pivot" field="region"></bmx-pivot-slicer>
  <bmx-pivot-slicer for="ex-ps-pivot" field="product" layout="grid" columns="2"></bmx-pivot-slicer>
  <bmx-pivot-slicer for="ex-ps-pivot" field="ordered:year" label="Year" layout="list" multiple="false"></bmx-pivot-slicer>
  <bmx-pivot-slicer for="ex-ps-pivot" field="channel" hide-empty></bmx-pivot-slicer>
</div>

<bmx-pivot-grid id="ex-ps-pivot" label="Sales" field-list="none" style="--bmx-pivot-grid-height: 22rem; margin-block-start: 1rem"></bmx-pivot-grid>

<div class="row" style="margin-block-start: 1rem">
  <span class="note" id="ex-ps-out">
    <strong>Click members to filter.</strong> Each slicer shows how many records its members have under the other
    slicers' choices; the channel slicer hides the ones that would leave nothing. The channel is not placed on the
    pivot at all - a slicer can filter any field.
  </span>
</div>

<script type="module">
  await customElements.whenDefined('bmx-pivot-grid');

  const pivot = document.getElementById('ex-ps-pivot');
  const out = document.getElementById('ex-ps-out');

  const regions = ['North', 'South', 'East', 'West'];
  const products = ['Laptops', 'Monitors', 'Docks', 'Keyboards'];
  let seed = 11;
  const random = () => ((seed = (seed * 1103515245 + 12345) % 2147483648) / 2147483648);
  const records = Array.from({ length: 12000 }, () => {
    const region = regions[Math.floor(random() * 4)];
    return {
      region,
      product: products[Math.floor(random() * 4)],
      // The West sells online only, so choosing it leaves one channel.
      channel: region === 'West' || random() > 0.5 ? 'Online' : 'Retail',
      ordered: `202${5 + Math.floor(random() * 2)}-${String(1 + Math.floor(random() * 12)).padStart(2, '0')}-10`,
      revenue: Math.round(random() * 250000) / 100,
    };
  });

  pivot.fields = [
    { field: 'revenue', title: 'Revenue', format: { style: 'currency', currency: 'GBP' } },
    { field: 'ordered', title: 'Order date' },
  ];
  pivot.layout = { rows: ['region'], columns: ['product'], values: [{ field: 'revenue', title: 'Revenue' }] };
  pivot.data = records;

  document.addEventListener('bmxSlicerChange', event => {
    const { field, selected } = event.detail;
    out.textContent = selected ? `${field}: ${selected.join(', ')}` : `${field}: everything`;
  });
</script>

Point it at the pivot with for (an id or a selector) and name the field - or one part of a date field, such as orderDate:year:

A listbox of options for assistive technology: the arrow keys move, Space or Enter chooses, Ctrl+A or Escape shows everything again.

Properties

PropertyAttributeTypeDefaultDescription
columns columns number 2 Columns, for the grid layout.
field field string '' The level it filters: a field (region) or a part of a date field (orderDate:year).
for for string | HTMLElement — The pivot grid it filters: its id, a CSS selector, or the element.
hideEmpty hide-empty boolean false Hide members with no records under the pivot's other filters, rather than dimming them.
label label string — Its heading. Default: the field's name from the pivot.
layout layout 'buttons' | 'grid' | 'list' 'buttons' buttons (default, wrapping), grid (in columns columns) or list (one per line).
multiple multiple boolean true Choose several members (default), or one at a time.
search search 'auto' | 'always' | 'never' 'auto' A search box: from 12 members (auto), always or never.
showCounts show-counts boolean true Show how many records each member has.

Events

EventDetailDescription
bmxSlicerChange BmxPivotSlicerChangeDetail The choice changed.

Methods

MethodSignatureDescription
clear clear() => Promise<void> Shows every member again.
getSelected getSelected() => Promise<string[] | null> The member keys kept, or null when all are.
refreshMembers refreshMembers() => Promise<void> Reads the members again from the pivot.
select select(keys: string[] | null) => Promise<void> Keeps only these members (their keys); an empty list or null keeps them all.

CSS shadow parts

PartDescription
clear the button that shows every member again.
count how many records a member has.
head its heading row.
option one member. Also option-selected when it is chosen.
options the members.
search the search field.
slicer the whole slicer.
title its heading.

CSS custom properties

PropertyDescription
--bmx-pivot-slicer-background Behind the slicer.
--bmx-pivot-slicer-max-height How tall the list may grow before it scrolls. Default 16rem.
--bmx-pivot-slicer-option-background A member.
--bmx-pivot-slicer-radius The slicer's corners.
--bmx-pivot-slicer-selected-background A chosen member.
--bmx-pivot-slicer-selected-text A chosen member's text.
--bmx-pivot-slicer-width How wide the slicer is. Default 14rem.