@sentropic/dataviz-react 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -28,4 +28,12 @@ export { DrillBarChart } from './lib/DrillBarChart.js';
28
28
  export type { DrillBarChartProps } from './lib/DrillBarChart.js';
29
29
  export { DrillBreadcrumb } from './lib/DrillBreadcrumb.js';
30
30
  export type { DrillBreadcrumbProps } from './lib/DrillBreadcrumb.js';
31
+ export { TopNFilter } from './lib/TopNFilter.js';
32
+ export type { TopNFilterProps } from './lib/TopNFilter.js';
33
+ export { ValueSlicer } from './lib/ValueSlicer.js';
34
+ export type { ValueSlicerProps } from './lib/ValueSlicer.js';
35
+ export { ExportMenu, rowsToCsv } from './lib/ExportMenu.js';
36
+ export type { ExportMenuProps } from './lib/ExportMenu.js';
37
+ export { DateRangeFilter, dateRangeToSpec } from './lib/DateRangeFilter.js';
38
+ export type { DateRangeFilterProps } from './lib/DateRangeFilter.js';
31
39
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,cAAc,cAAc,CAAC;AAG7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,YAAY,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,YAAY,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC5E,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -20,4 +20,8 @@ export { KpiCardGroup } from './lib/KpiCardGroup.js';
20
20
  export { RecordsTable } from './lib/RecordsTable.js';
21
21
  export { DrillBarChart } from './lib/DrillBarChart.js';
22
22
  export { DrillBreadcrumb } from './lib/DrillBreadcrumb.js';
23
+ export { TopNFilter } from './lib/TopNFilter.js';
24
+ export { ValueSlicer } from './lib/ValueSlicer.js';
25
+ export { ExportMenu, rowsToCsv } from './lib/ExportMenu.js';
26
+ export { DateRangeFilter, dateRangeToSpec } from './lib/DateRangeFilter.js';
23
27
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iFAAiF;AACjF,cAAc,cAAc,CAAC;AAE7B,qEAAqE;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iFAAiF;AACjF,cAAc,cAAc,CAAC;AAE7B,qEAAqE;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEjE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAEnD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type DashboardStore, type FilterSpec } from '@sentropic/dataviz-core';
2
+ export type DateRangeFilterProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Date dimension to filter (its cells must be epoch-millisecond numbers). */
6
+ dimension: string;
7
+ label?: string;
8
+ className?: string;
9
+ };
10
+ /**
11
+ * Pure: a DatePicker `{ start, end }` range → a core `range` FilterSpec in epoch
12
+ * milliseconds (bounds optional), or `null` when the range is empty.
13
+ */
14
+ export declare function dateRangeToSpec(range: {
15
+ start: Date | null;
16
+ end: Date | null;
17
+ }): FilterSpec | null;
18
+ /**
19
+ * A date-range filter: a design-system DatePicker (range mode) bound to a core
20
+ * `range` filter on a date dimension (epoch-millisecond cells).
21
+ */
22
+ export declare function DateRangeFilter({ store, dimension, label, className }: DateRangeFilterProps): import("react").JSX.Element;
23
+ //# sourceMappingURL=DateRangeFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateRangeFilter.d.ts","sourceRoot":"","sources":["../../src/lib/DateRangeFilter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE/E,MAAM,MAAM,oBAAoB,GAAG;IACjC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,IAAI,GAAG,IAAI,CAAC;IAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAA;CAAE,GAAG,UAAU,GAAG,IAAI,CAKlG;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAiB,EAAE,SAAS,EAAE,EAAE,oBAAoB,+BAgBvG"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { DatePicker } from '@sentropic/design-system-react';
4
+ import {} from '@sentropic/dataviz-core';
5
+ /**
6
+ * Pure: a DatePicker `{ start, end }` range → a core `range` FilterSpec in epoch
7
+ * milliseconds (bounds optional), or `null` when the range is empty.
8
+ */
9
+ export function dateRangeToSpec(range) {
10
+ const min = range.start ? range.start.getTime() : undefined;
11
+ const max = range.end ? range.end.getTime() : undefined;
12
+ if (min === undefined && max === undefined)
13
+ return null;
14
+ return { kind: 'range', min, max };
15
+ }
16
+ const asRange = (value) => value && typeof value === 'object' && 'start' in value ? value : { start: null, end: null };
17
+ /**
18
+ * A date-range filter: a design-system DatePicker (range mode) bound to a core
19
+ * `range` filter on a date dimension (epoch-millisecond cells).
20
+ */
21
+ export function DateRangeFilter({ store, dimension, label = 'Période', className }) {
22
+ const [range, setRange] = useState({ start: null, end: null });
23
+ useEffect(() => {
24
+ const spec = dateRangeToSpec(range);
25
+ if (spec)
26
+ store.setFilter(dimension, spec);
27
+ else
28
+ store.clearFilter(dimension);
29
+ }, [store, dimension, range]);
30
+ return (_jsx(DatePicker, { mode: "range", label: label, value: range, onChange: (v) => setRange(asRange(v)), className: className }));
31
+ }
32
+ //# sourceMappingURL=DateRangeFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DateRangeFilter.js","sourceRoot":"","sources":["../../src/lib/DateRangeFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,UAAU,EAA8C,MAAM,gCAAgC,CAAC;AACxG,OAAO,EAAwC,MAAM,yBAAyB,CAAC;AAW/E;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAA+C;IAC7E,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACxD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACxD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,KAAsB,EAAmB,EAAE,CAC1D,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AAE9F;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,GAAG,SAAS,EAAE,SAAS,EAAwB;IACtG,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,IAAI;YAAE,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;;YACtC,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC9B,OAAO,CACL,KAAC,UAAU,IACT,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EACrC,SAAS,EAAE,SAAS,GACpB,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { type DashboardStore, type Row } from '@sentropic/dataviz-core';
2
+ export type ExportMenuProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** View whose cross-filtered rows are exported (omit for global filters). */
6
+ viewId?: string;
7
+ /** Field ids (and order) to export; defaults to all model fields. */
8
+ fields?: string[];
9
+ /** Downloaded file name. */
10
+ filename?: string;
11
+ /** Button label. */
12
+ label?: string;
13
+ className?: string;
14
+ };
15
+ /** Pure: rows + columns → a CSV string (RFC-4180-ish escaping). */
16
+ export declare function rowsToCsv(rows: readonly Row[], columns: {
17
+ key: string;
18
+ label: string;
19
+ }[]): string;
20
+ /**
21
+ * Exports the current cross-filtered rows of a view as a downloaded CSV, via a
22
+ * design-system Button. The CSV serialisation is pure and exported for testing.
23
+ */
24
+ export declare function ExportMenu({ store, viewId, fields, filename, label, className, }: ExportMenuProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=ExportMenu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportMenu.d.ts","sourceRoot":"","sources":["../../src/lib/ExportMenu.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAE,KAAK,GAAG,EAAE,MAAM,yBAAyB,CAAC;AAErF,MAAM,MAAM,eAAe,GAAG;IAC5B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAOF,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,EAAE,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,MAAM,CAIjG;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,MAAM,EACN,QAAuB,EACvB,KAAwB,EACxB,SAAS,GACV,EAAE,eAAe,+BA4BjB"}
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Button } from '@sentropic/design-system-react';
3
+ import { findMeasure } from '@sentropic/dataviz-core';
4
+ function escapeCsv(value) {
5
+ const s = value == null ? '' : String(value);
6
+ return /[",\n\r]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
7
+ }
8
+ /** Pure: rows + columns → a CSV string (RFC-4180-ish escaping). */
9
+ export function rowsToCsv(rows, columns) {
10
+ const header = columns.map((c) => escapeCsv(c.label)).join(',');
11
+ const body = rows.map((r) => columns.map((c) => escapeCsv(r[c.key] ?? '')).join(',')).join('\n');
12
+ return body ? `${header}\n${body}` : header;
13
+ }
14
+ /**
15
+ * Exports the current cross-filtered rows of a view as a downloaded CSV, via a
16
+ * design-system Button. The CSV serialisation is pure and exported for testing.
17
+ */
18
+ export function ExportMenu({ store, viewId, fields, filename = 'export.csv', label = 'Exporter (CSV)', className, }) {
19
+ const columns = () => {
20
+ const ids = fields ?? [
21
+ ...store.model.dimensions.map((d) => d.id),
22
+ ...store.model.measures.map((m) => m.id),
23
+ ];
24
+ return ids.map((id) => {
25
+ const dim = store.model.dimensions.find((d) => d.id === id);
26
+ const meas = findMeasure(store.model, id);
27
+ return { key: id, label: dim?.label ?? meas?.label ?? id };
28
+ });
29
+ };
30
+ const exportCsv = () => {
31
+ const csv = rowsToCsv(store.applyCrossfilter(viewId), columns());
32
+ if (typeof URL === 'undefined' || typeof URL.createObjectURL !== 'function')
33
+ return;
34
+ const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
35
+ const url = URL.createObjectURL(blob);
36
+ const a = document.createElement('a');
37
+ a.href = url;
38
+ a.download = filename;
39
+ a.click();
40
+ URL.revokeObjectURL(url);
41
+ };
42
+ return (_jsx(Button, { variant: "secondary", className: className, onClick: exportCsv, children: label }));
43
+ }
44
+ //# sourceMappingURL=ExportMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportMenu.js","sourceRoot":"","sources":["../../src/lib/ExportMenu.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SmallMultiples.d.ts","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,mBAAmB,GAAG;IAChC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,KAAK,EACL,OAAW,EACX,IAAI,EACJ,SAAS,GACV,EAAE,mBAAmB,+BAoCrB"}
1
+ {"version":3,"file":"SmallMultiples.d.ts","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIL,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,MAAM,mBAAmB,GAAG;IAChC,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,OAAO,EACP,SAAS,EACT,OAAO,EACP,KAAK,EACL,OAAW,EACX,IAAI,EACJ,SAAS,GACV,EAAE,mBAAmB,+BAuCrB"}
@@ -26,17 +26,21 @@ export function SmallMultiples({ store, viewId, facetBy, dimension, measure, lab
26
26
  keys.push(k);
27
27
  }
28
28
  }
29
+ let min = 0;
29
30
  let max = 0;
30
31
  panels = keys.map((k) => {
31
32
  const facetRows = rows.filter((row) => keyOf(row[facetBy]) === k);
32
33
  const data = groupAggregate(facetRows, dimension, m).map(({ key: barKey, value }) => {
34
+ if (value < min)
35
+ min = value;
33
36
  if (value > max)
34
37
  max = value;
35
38
  return tone ? { label: barKey, value, tone } : { label: barKey, value };
36
39
  });
37
40
  return { key: k, data };
38
41
  });
39
- domain = panels.length ? [0, max] : undefined;
42
+ // Shared domain anchored at 0 (keeps negatives in view for mixed facets).
43
+ domain = panels.length ? [min, max] : undefined;
40
44
  }
41
45
  return (_jsx(Grid, { columns: columns, gap: 4, className: className, role: "group", "aria-label": label, children: panels.map((panel) => (_jsx(BarChart, { data: panel.data, label: `${label} — ${panel.key}`, domain: domain }, panel.key))) }));
42
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SmallMultiples.js","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SmallMultiples.js","sourceRoot":"","sources":["../../src/lib/SmallMultiples.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type TopNFilterProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Dimension to restrict to its top-N values. */
6
+ dimension: string;
7
+ /** Measure used to rank the dimension's values (descending). */
8
+ measure: string;
9
+ /** Initial N. Defaults to 5. */
10
+ defaultN?: number;
11
+ /** Field label of the number input. */
12
+ label?: string;
13
+ className?: string;
14
+ };
15
+ /**
16
+ * Restricts a dimension to its top-N values by a measure (ranked over the full
17
+ * dataset), via a design-system NumberInput. Applies on mount and on change.
18
+ */
19
+ export declare function TopNFilter({ store, dimension, measure, defaultN, label, className, }: TopNFilterProps): import("react").JSX.Element;
20
+ //# sourceMappingURL=TopNFilter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopNFilter.d.ts","sourceRoot":"","sources":["../../src/lib/TopNFilter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,cAAc,EAAY,MAAM,yBAAyB,CAAC;AAErG,MAAM,MAAM,eAAe,GAAG;IAC5B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAY,EACZ,KAAe,EACf,SAAS,GACV,EAAE,eAAe,+BAyBjB"}
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useState } from 'react';
3
+ import { NumberInput } from '@sentropic/design-system-react';
4
+ import { findMeasure, groupAggregate } from '@sentropic/dataviz-core';
5
+ /**
6
+ * Restricts a dimension to its top-N values by a measure (ranked over the full
7
+ * dataset), via a design-system NumberInput. Applies on mount and on change.
8
+ */
9
+ export function TopNFilter({ store, dimension, measure, defaultN = 5, label = 'Top N', className, }) {
10
+ const [n, setN] = useState(defaultN);
11
+ useEffect(() => {
12
+ const m = findMeasure(store.model, measure);
13
+ if (!m || !Number.isFinite(n) || n < 1)
14
+ return;
15
+ const ranked = groupAggregate([...store.data], dimension, m)
16
+ .slice()
17
+ .sort((a, b) => b.value - a.value)
18
+ .slice(0, n)
19
+ .map((r) => r.key);
20
+ store.setFilter(dimension, { kind: 'include', values: ranked });
21
+ }, [store, dimension, measure, n]);
22
+ return (_jsx(NumberInput, { label: label, value: n, min: 1, step: 1, className: className, onChange: (e) => {
23
+ const v = Number(e.target.value);
24
+ if (Number.isFinite(v))
25
+ setN(v);
26
+ } }));
27
+ }
28
+ //# sourceMappingURL=TopNFilter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopNFilter.js","sourceRoot":"","sources":["../../src/lib/TopNFilter.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAiC,MAAM,yBAAyB,CAAC;AAgBrG;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,SAAS,EACT,OAAO,EACP,QAAQ,GAAG,CAAC,EACZ,KAAK,GAAG,OAAO,EACf,SAAS,GACO;IAChB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACrC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO;QAC/C,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,GAAI,KAAK,CAAC,IAAuB,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;aAC7E,KAAK,EAAE;aACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACrB,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CACL,KAAC,WAAW,IACV,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,EACR,GAAG,EAAE,CAAC,EACN,IAAI,EAAE,CAAC,EACP,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE;YACd,MAAM,CAAC,GAAG,MAAM,CAAE,CAAC,CAAC,MAA2B,CAAC,KAAK,CAAC,CAAC;YACvD,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAClC,CAAC,GACD,CACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type DashboardStore } from '@sentropic/dataviz-core';
2
+ export type ValueSlicerProps = {
3
+ /** The dashboard store to bind to. */
4
+ store: DashboardStore;
5
+ /** Dimension whose distinct values become the slicer's checkboxes. */
6
+ dimension: string;
7
+ /** Legend; defaults to the dimension label. */
8
+ legend?: string;
9
+ orientation?: 'vertical' | 'horizontal';
10
+ className?: string;
11
+ };
12
+ /**
13
+ * A checkbox slicer over a dimension's distinct values: checked values become an
14
+ * `include` filter (an OR within the dimension). Design-system CheckboxGroup.
15
+ */
16
+ export declare function ValueSlicer({ store, dimension, legend, orientation, className, }: ValueSlicerProps): import("react").JSX.Element;
17
+ //# sourceMappingURL=ValueSlicer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueSlicer.d.ts","sourceRoot":"","sources":["../../src/lib/ValueSlicer.tsx"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAG7E,MAAM,MAAM,gBAAgB,GAAG;IAC7B,sCAAsC;IACtC,KAAK,EAAE,cAAc,CAAC;IACtB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,UAAU,GAAG,YAAY,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAIF;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,MAAM,EACN,WAAwB,EACxB,SAAS,GACV,EAAE,gBAAgB,+BA4BlB"}
@@ -0,0 +1,32 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { CheckboxGroup } from '@sentropic/design-system-react';
3
+ import { findDimension } from '@sentropic/dataviz-core';
4
+ import { useDashboard } from '../adapter.js';
5
+ const keyOf = (v) => (v == null ? 'null' : String(v));
6
+ /**
7
+ * A checkbox slicer over a dimension's distinct values: checked values become an
8
+ * `include` filter (an OR within the dimension). Design-system CheckboxGroup.
9
+ */
10
+ export function ValueSlicer({ store, dimension, legend, orientation = 'vertical', className, }) {
11
+ const state = useDashboard(store);
12
+ const resolvedLegend = legend ?? findDimension(store.model, dimension)?.label ?? dimension;
13
+ const seen = new Set();
14
+ const options = [];
15
+ for (const row of store.data) {
16
+ const k = keyOf(row[dimension]);
17
+ if (!seen.has(k)) {
18
+ seen.add(k);
19
+ options.push({ label: k, value: k });
20
+ }
21
+ }
22
+ const f = state.filters[dimension];
23
+ const value = f && f.kind === 'include' ? [...f.values] : [];
24
+ const onChange = (values) => {
25
+ if (values.length)
26
+ store.setFilter(dimension, { kind: 'include', values });
27
+ else
28
+ store.clearFilter(dimension);
29
+ };
30
+ return (_jsx(CheckboxGroup, { legend: resolvedLegend, options: options, value: value, orientation: orientation, className: className, onChange: onChange }));
31
+ }
32
+ //# sourceMappingURL=ValueSlicer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ValueSlicer.js","sourceRoot":"","sources":["../../src/lib/ValueSlicer.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAA4B,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,aAAa,EAAuB,MAAM,yBAAyB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAa7C,MAAM,KAAK,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAE/D;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,SAAS,EACT,MAAM,EACN,WAAW,GAAG,UAAU,EACxB,SAAS,GACQ;IACjB,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,cAAc,GAAG,MAAM,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,CAAC,EAAE,KAAK,IAAI,SAAS,CAAC;IAC3F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,QAAQ,GAAG,CAAC,MAAgB,EAAE,EAAE;QACpC,IAAI,MAAM,CAAC,MAAM;YAAE,KAAK,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;;YACtE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC;IACF,OAAO,CACL,KAAC,aAAa,IACZ,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAClB,CACH,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentropic/dataviz-react",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "React adapter for @sentropic/dataviz-core, built on @sentropic/design-system-react.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,8 +27,8 @@
27
27
  "test": "vitest run"
28
28
  },
29
29
  "dependencies": {
30
- "@sentropic/dataviz-core": "0.2.0",
31
- "@sentropic/design-system-react": "0.18.0",
30
+ "@sentropic/dataviz-core": "0.3.0",
31
+ "@sentropic/design-system-react": "0.21.0",
32
32
  "@sentropic/design-system-themes": "0.11.0"
33
33
  },
34
34
  "peerDependencies": {