@carto/ps-react-ui 4.6.3 → 4.7.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/{download-config-C3I0jWIL.js → download-config-DNLkypdN.js} +8 -7
- package/dist/{download-config-C3I0jWIL.js.map → download-config-DNLkypdN.js.map} +1 -1
- package/dist/shared-resize-observer-98b1SK1e.js +17 -0
- package/dist/shared-resize-observer-98b1SK1e.js.map +1 -0
- package/dist/types/widgets/actions/brush-toggle/brush-overlay.d.ts +24 -0
- package/dist/types/widgets/actions/brush-toggle/brush-toggle.d.ts +15 -10
- package/dist/types/widgets/actions/brush-toggle/hit-test.d.ts +19 -0
- package/dist/types/widgets/actions/brush-toggle/hit-test.test.d.ts +1 -0
- package/dist/types/widgets/actions/brush-toggle/style.d.ts +8 -0
- package/dist/types/widgets/actions/brush-toggle/types.d.ts +35 -1
- package/dist/widgets/actions.js +985 -772
- package/dist/widgets/actions.js.map +1 -1
- package/dist/widgets/bar.js +1 -1
- package/dist/widgets/category.js +9 -8
- package/dist/widgets/category.js.map +1 -1
- package/dist/widgets/echart.js +79 -91
- package/dist/widgets/echart.js.map +1 -1
- package/dist/widgets/formula.js +43 -42
- package/dist/widgets/formula.js.map +1 -1
- package/dist/widgets/histogram.js +7 -6
- package/dist/widgets/histogram.js.map +1 -1
- package/dist/widgets/markdown.js +15 -14
- package/dist/widgets/markdown.js.map +1 -1
- package/dist/widgets/pie.js +1 -1
- package/dist/widgets/scatterplot.js +1 -1
- package/dist/widgets/spread.js +47 -46
- package/dist/widgets/spread.js.map +1 -1
- package/dist/widgets/table.js +17 -16
- package/dist/widgets/table.js.map +1 -1
- package/dist/widgets/timeseries.js +1 -1
- package/dist/widgets/utils.js +1 -1
- package/package.json +3 -1
- package/src/widgets/actions/brush-toggle/brush-overlay.tsx +386 -0
- package/src/widgets/actions/brush-toggle/brush-toggle.tsx +88 -152
- package/src/widgets/actions/brush-toggle/hit-test.test.ts +65 -0
- package/src/widgets/actions/brush-toggle/hit-test.ts +45 -0
- package/src/widgets/actions/brush-toggle/style.ts +32 -0
- package/src/widgets/actions/brush-toggle/types.ts +36 -1
|
@@ -11,7 +11,8 @@ import "./cjs-D4KH3azB.js";
|
|
|
11
11
|
import "@dnd-kit/core";
|
|
12
12
|
import "@dnd-kit/sortable";
|
|
13
13
|
import "@dnd-kit/utilities";
|
|
14
|
-
|
|
14
|
+
import "react-dom";
|
|
15
|
+
function T(r) {
|
|
15
16
|
const o = [];
|
|
16
17
|
if (r.length > 0 && (r[0]?.length ?? 0) > 0) {
|
|
17
18
|
const i = r?.[0]?.[0] ?? {}, t = Object.keys(i);
|
|
@@ -24,7 +25,7 @@ function E(r) {
|
|
|
24
25
|
});
|
|
25
26
|
}), o;
|
|
26
27
|
}
|
|
27
|
-
function
|
|
28
|
+
function b(r) {
|
|
28
29
|
const o = [];
|
|
29
30
|
return o.push(["x", "y"]), r.forEach((i) => {
|
|
30
31
|
i.forEach((t) => {
|
|
@@ -32,7 +33,7 @@ function T(r) {
|
|
|
32
33
|
});
|
|
33
34
|
}), o;
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
+
function j(r) {
|
|
36
37
|
return function({
|
|
37
38
|
refUI: o
|
|
38
39
|
}) {
|
|
@@ -49,8 +50,8 @@ function b(r) {
|
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
export {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
j as c,
|
|
54
|
+
T as f,
|
|
55
|
+
b as s
|
|
55
56
|
};
|
|
56
|
-
//# sourceMappingURL=download-config-
|
|
57
|
+
//# sourceMappingURL=download-config-DNLkypdN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download-config-
|
|
1
|
+
{"version":3,"file":"download-config-DNLkypdN.js","sources":["../src/widgets/utils/chart-config/csv-modifiers.ts","../src/widgets/utils/chart-config/download-config.ts"],"sourcesContent":["/**\n * Shared CSV export modifiers for chart widgets\n */\n\n/**\n * Flattens object array data into CSV-ready rows.\n * Used by bar, pie, histogram, and timeseries widgets.\n *\n * @param data - Array of series, where each series is an array of data objects\n * @returns CSV rows with headers and values\n */\nexport function flattenObjectArrayToCSV<T extends Record<string, unknown>>(\n data: T[][],\n): string[][] {\n const rows: string[][] = []\n\n // Add headers from first data point if available\n if (data.length > 0 && (data[0]?.length ?? 0) > 0) {\n const firstDataPoint = data?.[0]?.[0] ?? {}\n const headers = Object.keys(firstDataPoint)\n rows.push(headers)\n }\n\n // Add data rows from all series\n data.forEach((series) => {\n series.forEach((dataPoint) => {\n const values = Object.values(dataPoint).map((v) => String(v))\n rows.push(values)\n })\n })\n\n return rows\n}\n\n/**\n * Creates CSV rows for scatterplot data.\n * Scatterplot uses array format [x, y] instead of objects.\n *\n * @param data - Array of series, where each series is an array of [x, y] tuples\n * @returns CSV rows with ['x', 'y'] headers\n */\nexport function scatterplotDataToCSV(data: number[][][]): string[][] {\n const rows: string[][] = []\n\n // Add headers\n rows.push(['x', 'y'])\n\n // Add data rows from all series\n data.forEach((series) => {\n series.forEach((dataPoint) => {\n rows.push([String(dataPoint[0]), String(dataPoint[1])])\n })\n })\n\n return rows\n}\n","import { downloadToCSV, downloadToPNG, type DownloadItem } from '../../actions'\nimport type { ConfigProps } from '../../loader/types'\n\nexport function createChartDownloadConfig<TData>(\n csvModifier: (data: TData) => string[][],\n) {\n return function ({ refUI }: ConfigProps): DownloadItem<TData>[] {\n return [\n {\n ...downloadToPNG,\n modifier: () => downloadToPNG.modifier(refUI),\n },\n {\n ...downloadToCSV,\n modifier: async (data) => {\n const rows = csvModifier(data)\n return downloadToCSV.modifier(rows)\n },\n },\n ]\n }\n}\n"],"names":["flattenObjectArrayToCSV","data","rows","length","firstDataPoint","headers","Object","keys","push","forEach","series","dataPoint","values","map","v","String","scatterplotDataToCSV","createChartDownloadConfig","csvModifier","refUI","downloadToPNG","modifier","downloadToCSV"],"mappings":";;;;;;;;;;;;;;AAWO,SAASA,EACdC,GACY;AACZ,QAAMC,IAAmB,CAAA;AAGzB,MAAID,EAAKE,SAAS,MAAMF,EAAK,CAAC,GAAGE,UAAU,KAAK,GAAG;AACjD,UAAMC,IAAiBH,IAAO,CAAC,IAAI,CAAC,KAAK,CAAA,GACnCI,IAAUC,OAAOC,KAAKH,CAAc;AAC1CF,IAAAA,EAAKM,KAAKH,CAAO;AAAA,EACnB;AAGAJ,SAAAA,EAAKQ,QAASC,CAAAA,MAAW;AACvBA,IAAAA,EAAOD,QAASE,CAAAA,MAAc;AAC5B,YAAMC,IAASN,OAAOM,OAAOD,CAAS,EAAEE,IAAKC,CAAAA,MAAMC,OAAOD,CAAC,CAAC;AAC5DZ,MAAAA,EAAKM,KAAKI,CAAM;AAAA,IAClB,CAAC;AAAA,EACH,CAAC,GAEMV;AACT;AASO,SAASc,EAAqBf,GAAgC;AACnE,QAAMC,IAAmB,CAAA;AAGzBA,SAAAA,EAAKM,KAAK,CAAC,KAAK,GAAG,CAAC,GAGpBP,EAAKQ,QAASC,CAAAA,MAAW;AACvBA,IAAAA,EAAOD,QAASE,CAAAA,MAAc;AAC5BT,MAAAA,EAAKM,KAAK,CAACO,OAAOJ,EAAU,CAAC,CAAC,GAAGI,OAAOJ,EAAU,CAAC,CAAC,CAAC,CAAC;AAAA,IACxD,CAAC;AAAA,EACH,CAAC,GAEMT;AACT;ACpDO,SAASe,EACdC,GACA;AACA,SAAO,SAAU;AAAA,IAAEC,OAAAA;AAAAA,EAAAA,GAA6C;AAC9D,WAAO,CACL;AAAA,MACE,GAAGC;AAAAA,MACHC,UAAUA,MAAMD,EAAcC,SAASF,CAAK;AAAA,IAAA,GAE9C;AAAA,MACE,GAAGG;AAAAA,MACHD,UAAU,OAAOpB,MAAS;AACxB,cAAMC,IAAOgB,EAAYjB,CAAI;AAC7B,eAAOqB,EAAcD,SAASnB,CAAI;AAAA,MACpC;AAAA,IAAA,CACD;AAAA,EAEL;AACF;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const s = /* @__PURE__ */ new Map();
|
|
2
|
+
let o = null;
|
|
3
|
+
function t() {
|
|
4
|
+
return o ??= new ResizeObserver((e) => {
|
|
5
|
+
for (const r of e)
|
|
6
|
+
s.get(r.target)?.();
|
|
7
|
+
}), o;
|
|
8
|
+
}
|
|
9
|
+
function n(e, r) {
|
|
10
|
+
return s.set(e, r), t().observe(e), () => {
|
|
11
|
+
s.delete(e), t().unobserve(e);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
n as o
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=shared-resize-observer-98b1SK1e.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-resize-observer-98b1SK1e.js","sources":["../src/widgets/echart/shared-resize-observer.ts"],"sourcesContent":["/**\n * Shared ResizeObserver singleton for all ECharts instances.\n *\n * Instead of creating 100+ individual ResizeObserver instances (one per chart),\n * this module provides a single shared observer that efficiently handles resize\n * callbacks for all registered elements.\n */\n\ntype ResizeCallback = () => void\n\nconst callbacks = new Map<Element, ResizeCallback>()\n\nlet observer: ResizeObserver | null = null\n\nfunction getObserver(): ResizeObserver {\n observer ??= new ResizeObserver((entries) => {\n for (const entry of entries) {\n const callback = callbacks.get(entry.target)\n callback?.()\n }\n })\n return observer\n}\n\nexport function observeResize(\n element: Element,\n callback: ResizeCallback,\n): () => void {\n callbacks.set(element, callback)\n getObserver().observe(element)\n\n return () => {\n callbacks.delete(element)\n getObserver().unobserve(element)\n }\n}\n\n/** Reset the shared observer (for testing only). */\nexport function resetSharedResizeObserver(): void {\n if (observer) {\n observer.disconnect()\n observer = null\n }\n callbacks.clear()\n}\n"],"names":["callbacks","Map","observer","getObserver","ResizeObserver","entries","entry","callback","get","target","observeResize","element","set","observe","delete","unobserve"],"mappings":"AAUA,MAAMA,wBAAgBC,IAAAA;AAEtB,IAAIC,IAAkC;AAEtC,SAASC,IAA8B;AACrCD,SAAAA,MAAa,IAAIE,eAAgBC,CAAAA,MAAY;AAC3C,eAAWC,KAASD;AAElBE,MADiBP,EAAUQ,IAAIF,EAAMG,MAAM,IAC3CF;AAAAA,EAEJ,CAAC,GACML;AACT;AAEO,SAASQ,EACdC,GACAJ,GACY;AACZP,SAAAA,EAAUY,IAAID,GAASJ,CAAQ,GAC/BJ,EAAAA,EAAcU,QAAQF,CAAO,GAEtB,MAAM;AACXX,IAAAA,EAAUc,OAAOH,CAAO,GACxBR,EAAAA,EAAcY,UAAUJ,CAAO;AAAA,EACjC;AACF;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface BrushOverlayProps {
|
|
2
|
+
id: string;
|
|
3
|
+
multiBrush?: boolean;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Portaled overlay rendered inside the ECharts chart `<div>`. Handles brush
|
|
7
|
+
* drawing entirely in DOM, independent of ECharts' built-in brush.
|
|
8
|
+
*
|
|
9
|
+
* Rectangles are stored in x-axis data coords (category indices) in the
|
|
10
|
+
* widget store. The overlay re-projects them to pixel coords on every chart
|
|
11
|
+
* `finished` event and container resize, so `setOption({ notMerge: true })`
|
|
12
|
+
* by the config pipeline is a non-event.
|
|
13
|
+
*
|
|
14
|
+
* Pointer capture and rectangle rendering are both clamped to the ECharts
|
|
15
|
+
* grid (plot area), so the legend, axis labels, and other chart chrome
|
|
16
|
+
* receive their usual events and aren't visually covered.
|
|
17
|
+
*
|
|
18
|
+
* Hit-testing happens on `pointerup` using `hitTestRects` against the widget's
|
|
19
|
+
* data length (derived from `widget.data`). The result is written to
|
|
20
|
+
* `brushSelection` in the store; `BrushToggle` subscribes to that and invokes
|
|
21
|
+
* the consumer's `onBrushSelected` callback.
|
|
22
|
+
*/
|
|
23
|
+
export declare function BrushOverlay({ id, multiBrush }: BrushOverlayProps): import('react').ReactPortal | null;
|
|
24
|
+
export {};
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import { BrushToggleProps } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Kept for backwards compatibility. The tool is no longer registered with the
|
|
4
|
+
* widget store — brush state is now owned directly by this component and the
|
|
5
|
+
* associated DOM overlay instead of being driven through the config pipeline.
|
|
6
|
+
* Existing code that looks this constant up in `registeredTools` will simply
|
|
7
|
+
* find no match.
|
|
8
|
+
*/
|
|
2
9
|
export declare const BRUSH_TOGGLE_TOOL_ID = "brush-toggle";
|
|
3
10
|
/**
|
|
4
|
-
* Widget action to toggle
|
|
5
|
-
*
|
|
6
|
-
* Registers as a config pipeline tool so that brush configuration is automatically
|
|
7
|
-
* re-applied when the base config is updated (e.g., by WidgetLoader).
|
|
11
|
+
* Widget action to toggle brush-style selection on bar and histogram widgets.
|
|
8
12
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
13
|
+
* Renders a toggle button and a portaled overlay rendered inside the chart's
|
|
14
|
+
* `<div>`. The overlay handles all pointer interactions, draws selection
|
|
15
|
+
* rectangles in DOM, and hit-tests against the widget data. All state lives
|
|
16
|
+
* in the widget store — rectangles survive config-pipeline re-renders
|
|
17
|
+
* (`setOption({ notMerge: true })`) automatically.
|
|
11
18
|
*
|
|
12
|
-
*
|
|
13
|
-
* Selection clearing is handled via the chart's brush interactions/toolbox configuration.
|
|
14
|
-
* Only intended for use in fullscreen ToolbarActions for bar and histogram widgets.
|
|
19
|
+
* Only intended for bar and histogram widgets (both use `xAxis.type === 'category'`).
|
|
15
20
|
*
|
|
16
21
|
* @example
|
|
17
22
|
* ```tsx
|
|
@@ -21,4 +26,4 @@ export declare const BRUSH_TOGGLE_TOOL_ID = "brush-toggle";
|
|
|
21
26
|
* />
|
|
22
27
|
* ```
|
|
23
28
|
*/
|
|
24
|
-
export declare function BrushToggle({ id, onBrushSelected, labels, Icon, IconButtonProps, }: BrushToggleProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare function BrushToggle({ id, onBrushSelected, multiBrush, selections, defaultEnabled, labels, Icon, IconButtonProps, }: BrushToggleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BrushRect } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Returns integer dataIndices covered by a brush rectangle on a category axis.
|
|
4
|
+
*
|
|
5
|
+
* `xStart` / `xEnd` come from `instance.convertFromPixel({ xAxisIndex: 0 }, …)`
|
|
6
|
+
* which, for a category axis, returns fractional positions around integer
|
|
7
|
+
* category indices (e.g. `1.3` lands between categories 1 and 2). We snap the
|
|
8
|
+
* range outward (`floor` / `ceil`) so a drag that visually covers any part of
|
|
9
|
+
* a category's bar includes that index.
|
|
10
|
+
*
|
|
11
|
+
* Results are clamped to `[0, dataLength - 1]` and returned in ascending order.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hitTestCategoryRange(xStart: number, xEnd: number, dataLength: number): number[];
|
|
14
|
+
/**
|
|
15
|
+
* Union of `hitTestCategoryRange` across multiple rectangles. Used for
|
|
16
|
+
* multi-brush selections where each drawn rectangle contributes to the
|
|
17
|
+
* combined selection.
|
|
18
|
+
*/
|
|
19
|
+
export declare function hitTestRects(rects: BrushRect[], dataLength: number): number[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Theme } from '@mui/material';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
2
3
|
export declare const styles: {
|
|
3
4
|
container: {
|
|
4
5
|
display: "flex";
|
|
@@ -11,3 +12,10 @@ export declare const styles: {
|
|
|
11
12
|
};
|
|
12
13
|
};
|
|
13
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Plain CSS objects for the brush overlay — we're outside MUI's sx pipeline
|
|
17
|
+
* here because the rectangles are rendered via a React portal into the chart
|
|
18
|
+
* div (not part of the MUI tree). Colors borrow from the base palette; if
|
|
19
|
+
* theme-aware styling is needed later, move to styled components.
|
|
20
|
+
*/
|
|
21
|
+
export declare const overlayStyles: Record<string, CSSProperties>;
|
|
@@ -12,10 +12,29 @@ export interface BrushSelectedItems {
|
|
|
12
12
|
seriesIndex: number;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* A selection rectangle in x-axis data coords. Stored in the widget store so
|
|
16
|
+
* it survives config-pipeline re-renders (which call `setOption` with
|
|
17
|
+
* `notMerge: true` and wipe any ECharts-side state). The overlay re-projects
|
|
18
|
+
* these to pixel positions on every chart render / resize.
|
|
19
|
+
*
|
|
20
|
+
* Both bar and histogram widgets use `xAxis.type === 'category'`, so the
|
|
21
|
+
* coords are category indices (possibly fractional — `convertFromPixel`
|
|
22
|
+
* returns floats like `1.3` between categories 1 and 2).
|
|
23
|
+
*/
|
|
24
|
+
export interface BrushRect {
|
|
25
|
+
xStart: number;
|
|
26
|
+
xEnd: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* State stored in widget store for brush functionality.
|
|
16
30
|
*/
|
|
17
31
|
export interface BrushConfig {
|
|
32
|
+
/** Whether brush mode is enabled. */
|
|
18
33
|
brush?: boolean;
|
|
34
|
+
/** Persisted selection rectangles in data-axis coords. */
|
|
35
|
+
brushRects?: BrushRect[];
|
|
36
|
+
/** Last selection emitted to the `onBrushSelected` callback. */
|
|
37
|
+
brushSelection?: BrushSelectedItems;
|
|
19
38
|
}
|
|
20
39
|
export type BrushState<T = unknown> = BaseWidgetState<T & BrushConfig>;
|
|
21
40
|
export interface BrushToggleProps {
|
|
@@ -23,6 +42,21 @@ export interface BrushToggleProps {
|
|
|
23
42
|
id: string;
|
|
24
43
|
/** Callback fired when items are selected via brush */
|
|
25
44
|
onBrushSelected?: (items: BrushSelectedItems) => void;
|
|
45
|
+
/** When true, allows multiple brush selection areas. Brush stays active after each selection. */
|
|
46
|
+
multiBrush?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Initial brush-enabled state. Only applied on first mount if the widget
|
|
49
|
+
* store has no `brush` value yet — subsequent remounts preserve whatever
|
|
50
|
+
* state the user has toggled to.
|
|
51
|
+
*/
|
|
52
|
+
defaultEnabled?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Current selection count from the consumer (e.g. `selectedItems.length`).
|
|
55
|
+
* When this transitions to `0` (typically when the user presses the clear
|
|
56
|
+
* button in `WidgetSelectionSummary`), BrushToggle clears its persisted
|
|
57
|
+
* brush rectangles and the on-chart selection.
|
|
58
|
+
*/
|
|
59
|
+
selections?: number;
|
|
26
60
|
/** Custom labels for the action */
|
|
27
61
|
labels?: {
|
|
28
62
|
/** Tooltip when brush is disabled (button will enable brush) */
|