@galaxy-io/dls 2.0.0 → 2.0.1
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/charts/BarChart.js +29 -13
- package/dist/charts/ChartCategoryTargets.d.ts +2 -2
- package/dist/charts/ChartCategoryTargets.js +2 -1
- package/dist/charts/ChartFrame.d.ts +7 -5
- package/dist/charts/ChartFrame.js +151 -76
- package/dist/charts/ChartLegend.d.ts +14 -4
- package/dist/charts/ChartLegend.js +90 -53
- package/dist/charts/ChartMarkTargets.d.ts +2 -2
- package/dist/charts/ChartMarkTargets.js +2 -1
- package/dist/charts/Heatmap.js +19 -7
- package/dist/charts/LineChart.js +19 -8
- package/dist/charts/PieChart.js +16 -7
- package/dist/charts/chartSelection.d.ts +15 -0
- package/dist/charts/chartSelection.js +22 -0
- package/dist/charts/constants.d.ts +4 -0
- package/dist/charts/constants.js +6 -2
- package/dist/charts/types.d.ts +10 -1
- package/dist/charts/useChartInteraction.d.ts +25 -3
- package/dist/charts/useChartInteraction.js +56 -10
- package/dist/drawer/Drawer.d.ts +3 -1
- package/dist/drawer/Drawer.js +43 -14
- package/dist/feedback/Alert.d.ts +1 -1
- package/dist/inputs/CheckboxGroup.js +1 -1
- package/dist/inputs/CheckboxInput.js +1 -1
- package/dist/inputs/ColorInput.js +1 -1
- package/dist/inputs/CronInput.js +1 -1
- package/dist/inputs/DateInput.js +1 -1
- package/dist/inputs/KeyValueInput.js +1 -1
- package/dist/inputs/SelectInput.js +1 -1
- package/dist/inputs/SwitchInput.js +1 -1
- package/dist/inputs/TextAreaInput.js +6 -0
- package/dist/inputs/internal/ownField.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/table/TableCore.js +6 -1
- package/dist/timeline/Timeline.d.ts +22 -1
- package/dist/timeline/Timeline.js +75 -43
- package/package.json +5 -1
|
@@ -5,13 +5,15 @@ import Flex, { AlignItems } from "../layout/Flex.js";
|
|
|
5
5
|
import Tooltip from "../tooltip/Tooltip.js";
|
|
6
6
|
import { ChartLegendPlacement, ChartMarkState, ChartPalette } from "./types.js";
|
|
7
7
|
import { CHART_MARK_STATE_TO_CSS_MAP } from "./ChartPrimitives.js";
|
|
8
|
+
import "./constants.js";
|
|
9
|
+
import { isAdditiveEvent } from "./chartSelection.js";
|
|
8
10
|
import Circle, { CircleSize, CircleVariant } from "../shapes/Circle.js";
|
|
9
11
|
import Square, { SquareSize, SquareVariant } from "../shapes/Square.js";
|
|
10
12
|
import { CHART_PALETTE_TO_COLOR_MAP } from "./chartPalette.js";
|
|
11
13
|
/* empty css */
|
|
12
14
|
import { styled } from "@linaria/react";
|
|
13
15
|
import { useCallback, useRef, useState } from "react";
|
|
14
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
15
17
|
import { cx } from "@linaria/core";
|
|
16
18
|
//#region src/charts/ChartLegend.tsx
|
|
17
19
|
/**
|
|
@@ -20,8 +22,13 @@ import { cx } from "@linaria/core";
|
|
|
20
22
|
* them. The fit is measured, not guessed: a hidden copy of every entry is laid out unconstrained
|
|
21
23
|
* and the visible count is however many real sizes fit beside the trigger.
|
|
22
24
|
*
|
|
23
|
-
* Entries are list items
|
|
24
|
-
*
|
|
25
|
+
* Entries are list items. Hovering one previews its series (a pointer enhancement; keyboard users
|
|
26
|
+
* hear every series in the announcement). On a filterable chart each entry is also a toggle button
|
|
27
|
+
* (`aria-pressed`): a click pins its series, ⌘ / Ctrl / Shift-click adds or removes it. Entries
|
|
28
|
+
* collapsed behind "+N more" stay hover-only (a tooltip holds no controls). A filterable chart's
|
|
29
|
+
* legend ends in a slot for its filter chip, right after the last entry (under the column when
|
|
30
|
+
* RIGHT): the slot always keeps its height, and a bottom legend always keeps room for the chip's
|
|
31
|
+
* width, so pinning never moves an entry. Spacing is
|
|
25
32
|
* padding on each entry (trailing in a row, split above and below in a column so the column
|
|
26
33
|
* centers), not a flex gap, so sweeping across entries never drops the isolation. Isolation changes opacity only; it never rescales the axis.
|
|
27
34
|
*/
|
|
@@ -75,14 +82,27 @@ var MEASURE_PLACEMENT_TO_CSS_MAP = {
|
|
|
75
82
|
[ChartLegendPlacement.BOTTOM]: "gx-ChartLegend-ChartLegendPlacement_BOTTOM-cixvbm6",
|
|
76
83
|
[ChartLegendPlacement.RIGHT]: "gx-ChartLegend-ChartLegendPlacement_RIGHT-c1ehakcs"
|
|
77
84
|
};
|
|
85
|
+
/** The filter chips' slot: one or two chips, truncating at its cap, never taller than the row it sets. */
|
|
86
|
+
var FilterSlot = /*#__PURE__*/ styled("li")({
|
|
87
|
+
name: "FilterSlot",
|
|
88
|
+
class: "gx-ChartLegend-FilterSlot-fsomlsk",
|
|
89
|
+
propsAsIs: false
|
|
90
|
+
});
|
|
91
|
+
/** BOTTOM: a 20px row the chip fits; RIGHT: the chip under the column, 8px below the last entry. */
|
|
92
|
+
var FILTER_SLOT_PLACEMENT_TO_CSS_MAP = {
|
|
93
|
+
[ChartLegendPlacement.BOTTOM]: "gx-ChartLegend-ChartLegendPlacement_BOTTOM-cdc52xq",
|
|
94
|
+
[ChartLegendPlacement.RIGHT]: "gx-ChartLegend-ChartLegendPlacement_RIGHT-cme95dp"
|
|
95
|
+
};
|
|
78
96
|
/** An entry never shrinks below its content; the fit decides what shows. */
|
|
79
|
-
var ENTRY_CSS = "gx-ChartLegend-ENTRY_CSS-
|
|
97
|
+
var ENTRY_CSS = "gx-ChartLegend-ENTRY_CSS-e1lt2566";
|
|
98
|
+
/** A filterable entry's toggle: the swatch and label as one button, ring on keyboard focus. */
|
|
99
|
+
var ENTRY_BUTTON_CSS = "gx-ChartLegend-ENTRY_BUTTON_CSS-e1btzd6s";
|
|
80
100
|
/** The "+N more" trigger: a real button, Tab-reachable. */
|
|
81
|
-
var TRIGGER_CSS = "gx-ChartLegend-TRIGGER_CSS-
|
|
101
|
+
var TRIGGER_CSS = "gx-ChartLegend-TRIGGER_CSS-t1hkz6fn";
|
|
82
102
|
/** The hidden entries, listed in the trigger's tooltip. */
|
|
83
103
|
var OverflowList = /*#__PURE__*/ styled("ul")({
|
|
84
104
|
name: "OverflowList",
|
|
85
|
-
class: "gx-ChartLegend-OverflowList-
|
|
105
|
+
class: "gx-ChartLegend-OverflowList-o1wv3pdp",
|
|
86
106
|
propsAsIs: false
|
|
87
107
|
});
|
|
88
108
|
function Swatch({ item, swatch }) {
|
|
@@ -97,8 +117,17 @@ function Swatch({ item, swatch }) {
|
|
|
97
117
|
})
|
|
98
118
|
});
|
|
99
119
|
}
|
|
100
|
-
function Entry({ item, swatch, isVertical, state, as = "li", onEnter, onLeave }) {
|
|
101
|
-
|
|
120
|
+
function Entry({ item, swatch, isVertical, state, as = "li", isPinned = false, onEnter, onLeave, onClick }) {
|
|
121
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Swatch, {
|
|
122
|
+
item,
|
|
123
|
+
swatch
|
|
124
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
125
|
+
size: TextSize.BODY_SM,
|
|
126
|
+
variant: isPinned ? TextVariant.PRIMARY : TextVariant.SECONDARY,
|
|
127
|
+
lineClamp: 1,
|
|
128
|
+
children: item.label
|
|
129
|
+
})] });
|
|
130
|
+
return /* @__PURE__ */ jsx(Flex, {
|
|
102
131
|
as,
|
|
103
132
|
alignItems: AlignItems.CENTER,
|
|
104
133
|
gap: 8,
|
|
@@ -111,19 +140,17 @@ function Entry({ item, swatch, isVertical, state, as = "li", onEnter, onLeave })
|
|
|
111
140
|
className: cx(ENTRY_CSS, CHART_MARK_STATE_TO_CSS_MAP[state]),
|
|
112
141
|
...onEnter && { onMouseEnter: onEnter },
|
|
113
142
|
...onLeave && { onMouseLeave: onLeave },
|
|
114
|
-
children:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
children: item.label
|
|
122
|
-
})]
|
|
143
|
+
children: onClick ? /* @__PURE__ */ jsx("button", {
|
|
144
|
+
type: "button",
|
|
145
|
+
"aria-pressed": isPinned,
|
|
146
|
+
className: ENTRY_BUTTON_CSS,
|
|
147
|
+
onClick: (event) => onClick(isAdditiveEvent(event)),
|
|
148
|
+
children: content
|
|
149
|
+
}) : content
|
|
123
150
|
});
|
|
124
151
|
}
|
|
125
152
|
/** @internal The chart legend. */
|
|
126
|
-
function ChartLegend({ items, placement, swatch, inset, extent = 0,
|
|
153
|
+
function ChartLegend({ items, placement, swatch, inset, extent = 0, isFixedExtent = true, hasFilterSlot = false, filter = null, getEntryState, isEntryPinned, onItemClick, onItemEnter, onItemLeave }) {
|
|
127
154
|
const listRef = useRef(null);
|
|
128
155
|
const measureRef = useRef(null);
|
|
129
156
|
const [fitCount, setFitCount] = useState(null);
|
|
@@ -135,7 +162,7 @@ function ChartLegend({ items, placement, swatch, inset, extent = 0, hoveredKey,
|
|
|
135
162
|
const rendered = Array.from(measure.children);
|
|
136
163
|
const trigger = rendered.pop();
|
|
137
164
|
if (!trigger) return;
|
|
138
|
-
const available = isVertical ? extent || Number.POSITIVE_INFINITY : list.clientWidth - inset;
|
|
165
|
+
const available = isVertical ? extent || Number.POSITIVE_INFINITY : list.clientWidth - inset - (hasFilterSlot ? 240 : 0);
|
|
139
166
|
const sizeOf = (element) => {
|
|
140
167
|
const rect = element.getBoundingClientRect();
|
|
141
168
|
return Math.ceil(isVertical ? rect.height : rect.width);
|
|
@@ -157,7 +184,8 @@ function ChartLegend({ items, placement, swatch, inset, extent = 0, hoveredKey,
|
|
|
157
184
|
}, [
|
|
158
185
|
isVertical,
|
|
159
186
|
extent,
|
|
160
|
-
inset
|
|
187
|
+
inset,
|
|
188
|
+
hasFilterSlot
|
|
161
189
|
]);
|
|
162
190
|
useIsomorphicLayoutEffect(() => {
|
|
163
191
|
recompute();
|
|
@@ -170,14 +198,12 @@ function ChartLegend({ items, placement, swatch, inset, extent = 0, hoveredKey,
|
|
|
170
198
|
return () => observer.disconnect();
|
|
171
199
|
}, [recompute]);
|
|
172
200
|
if (items.length === 0) return null;
|
|
173
|
-
const stateOf = (key) => hoveredKey === null || key === hoveredKey ? ChartMarkState.ACTIVE : ChartMarkState.MUTED;
|
|
174
201
|
const inline = items.slice(0, fitCount ?? items.length);
|
|
175
202
|
const overflow = items.slice(inline.length);
|
|
176
|
-
const
|
|
177
|
-
const triggerState = hoveredKey === null || isOverflowEngaged ? ChartMarkState.ACTIVE : ChartMarkState.MUTED;
|
|
203
|
+
const triggerState = overflow.some((item) => getEntryState(item.key) === ChartMarkState.ACTIVE) ? ChartMarkState.ACTIVE : ChartMarkState.MUTED;
|
|
178
204
|
const variables = {
|
|
179
205
|
"--gx-chart-legend-inset": `${inset}px`,
|
|
180
|
-
...isVertical && extent > 0 && { "--gx-chart-legend-extent": `${extent}px` }
|
|
206
|
+
...isVertical && extent > 0 && isFixedExtent && { "--gx-chart-legend-extent": `${extent}px` }
|
|
181
207
|
};
|
|
182
208
|
return /* @__PURE__ */ jsxs(Root, { children: [/* @__PURE__ */ jsx(MeasureClip, {
|
|
183
209
|
"aria-hidden": "true",
|
|
@@ -209,38 +235,49 @@ function ChartLegend({ items, placement, swatch, inset, extent = 0, hoveredKey,
|
|
|
209
235
|
ref: listRef,
|
|
210
236
|
className: CHART_LEGEND_PLACEMENT_TO_LIST_CSS_MAP[placement],
|
|
211
237
|
style: variables,
|
|
212
|
-
children: [
|
|
213
|
-
item,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
isVertical:
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
children: [
|
|
239
|
+
inline.map((item) => /* @__PURE__ */ jsx(Entry, {
|
|
240
|
+
item,
|
|
241
|
+
swatch,
|
|
242
|
+
isVertical,
|
|
243
|
+
state: getEntryState(item.key),
|
|
244
|
+
isPinned: isEntryPinned?.(item.key) ?? false,
|
|
245
|
+
onEnter: () => onItemEnter(item.key),
|
|
246
|
+
onLeave: onItemLeave,
|
|
247
|
+
onClick: onItemClick && ((isAdditive) => onItemClick(item.key, isAdditive))
|
|
248
|
+
}, item.key)),
|
|
249
|
+
overflow.length > 0 && /* @__PURE__ */ jsx(Flex, {
|
|
250
|
+
as: "li",
|
|
251
|
+
alignItems: AlignItems.CENTER,
|
|
252
|
+
className: cx(ENTRY_CSS, CHART_MARK_STATE_TO_CSS_MAP[triggerState]),
|
|
253
|
+
children: /* @__PURE__ */ jsx(Tooltip, {
|
|
254
|
+
placement: isVertical ? Placement.RIGHT : Placement.TOP,
|
|
255
|
+
body: /* @__PURE__ */ jsx(OverflowList, { children: overflow.map((item) => /* @__PURE__ */ jsx(Entry, {
|
|
256
|
+
item,
|
|
257
|
+
swatch,
|
|
258
|
+
isVertical: true,
|
|
259
|
+
state: getEntryState(item.key),
|
|
260
|
+
isPinned: isEntryPinned?.(item.key) ?? false,
|
|
261
|
+
onEnter: () => onItemEnter(item.key),
|
|
262
|
+
onLeave: onItemLeave
|
|
263
|
+
}, item.key)) }),
|
|
264
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
265
|
+
type: "button",
|
|
266
|
+
className: TRIGGER_CSS,
|
|
267
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
268
|
+
size: TextSize.BODY_SM,
|
|
269
|
+
variant: TextVariant.SECONDARY,
|
|
270
|
+
children: `+${overflow.length} more`
|
|
271
|
+
})
|
|
240
272
|
})
|
|
241
273
|
})
|
|
274
|
+
}),
|
|
275
|
+
hasFilterSlot && /* @__PURE__ */ jsx(FilterSlot, {
|
|
276
|
+
className: FILTER_SLOT_PLACEMENT_TO_CSS_MAP[placement],
|
|
277
|
+
"aria-hidden": filter === null || void 0,
|
|
278
|
+
children: filter
|
|
242
279
|
})
|
|
243
|
-
|
|
280
|
+
]
|
|
244
281
|
})] });
|
|
245
282
|
}
|
|
246
283
|
//#endregion
|
|
@@ -7,8 +7,8 @@ export interface ChartMarkTargetsProps {
|
|
|
7
7
|
onEnter: (categoryIndex: number) => void;
|
|
8
8
|
/** Pointer left the target layers (moving between targets is not leaving). */
|
|
9
9
|
onLeave: () => void;
|
|
10
|
-
/** Click on a mark, by its index in `targets
|
|
11
|
-
onSelect: (markIndex: number) => void;
|
|
10
|
+
/** Click on a mark, by its index in `targets` (additive with ⌘ / Ctrl / Shift). */
|
|
11
|
+
onSelect: (markIndex: number, isAdditive: boolean) => void;
|
|
12
12
|
}
|
|
13
13
|
/** @internal The mark hit layer. */
|
|
14
14
|
export declare function ChartMarkTargets({ targets, onEnter, onLeave, onSelect }: ChartMarkTargetsProps): import("react").JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ChartTargetShape } from "./types.js";
|
|
2
2
|
import { CHART_HIT_TARGET_CLICKABLE_CSS, CHART_HIT_TARGET_CSS, leaveUnlessTarget } from "./ChartPrimitives.js";
|
|
3
|
+
import { isAdditiveEvent } from "./chartSelection.js";
|
|
3
4
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
4
5
|
import { cx } from "@linaria/core";
|
|
5
6
|
//#region src/charts/ChartMarkTargets.tsx
|
|
@@ -17,7 +18,7 @@ function ChartMarkTargets({ targets, onEnter, onLeave, onSelect }) {
|
|
|
17
18
|
const handlers = {
|
|
18
19
|
onMouseEnter: () => onEnter(target.categoryIndex),
|
|
19
20
|
onMouseLeave: (event) => leaveUnlessTarget(event, onLeave),
|
|
20
|
-
onClick: () => onSelect(index)
|
|
21
|
+
onClick: (event) => onSelect(index, isAdditiveEvent(event))
|
|
21
22
|
};
|
|
22
23
|
return target.shape === ChartTargetShape.RECT ? /* @__PURE__ */ jsx("rect", {
|
|
23
24
|
x: target.x,
|
package/dist/charts/Heatmap.js
CHANGED
|
@@ -99,7 +99,7 @@ function HeatmapLegend({ ramp, min, max, hasEmpty, inset }) {
|
|
|
99
99
|
}
|
|
100
100
|
/** A grid of cells colored by value along one hue's token ramp. */
|
|
101
101
|
var Heatmap = forwardRef(function Heatmap(props, ref) {
|
|
102
|
-
const { cells, columns: explicitColumns, rows: explicitRows, color = ChartPalette.PURPLE, labelFormatter, valueDomain, valueFormatter, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, ariaLabel, id, className, style, ...rest } = props;
|
|
102
|
+
const { cells, columns: explicitColumns, rows: explicitRows, color = ChartPalette.PURPLE, labelFormatter, valueDomain, valueFormatter, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, isFilterable = false, defaultSelection, onSelectionChange, ariaLabel, id, className, style, ...rest } = props;
|
|
103
103
|
const plotRef = useRef(null);
|
|
104
104
|
const { formatValue, formatLabel } = useChartFormatters(valueFormatter, labelFormatter);
|
|
105
105
|
const { columns, rows } = useMemo(() => getHeatmapLabels(cells, explicitColumns, explicitRows), [
|
|
@@ -151,8 +151,11 @@ var Heatmap = forwardRef(function Heatmap(props, ref) {
|
|
|
151
151
|
categoryKeys: cellColumnKeys,
|
|
152
152
|
enableGroupSync: false,
|
|
153
153
|
selection,
|
|
154
|
+
isFilterable,
|
|
155
|
+
defaultSelection,
|
|
156
|
+
onSelectionChange,
|
|
154
157
|
categoryMuteState: ChartMarkState.ACTIVE,
|
|
155
|
-
isDisabled: !(hasTooltip || onSelect) || isLoading || isEmpty,
|
|
158
|
+
isDisabled: !(hasTooltip || onSelect || isFilterable) || isLoading || isEmpty,
|
|
156
159
|
isLoading,
|
|
157
160
|
grid
|
|
158
161
|
});
|
|
@@ -206,16 +209,25 @@ var Heatmap = forwardRef(function Heatmap(props, ref) {
|
|
|
206
209
|
plotWidth,
|
|
207
210
|
plotHeight
|
|
208
211
|
]);
|
|
209
|
-
const
|
|
212
|
+
const { toggleSelection } = interaction;
|
|
213
|
+
const handleSelect = useCallback((index, isAdditive = false) => {
|
|
210
214
|
const cell = geometry.cells[index];
|
|
211
|
-
if (!cell
|
|
212
|
-
onSelect({
|
|
215
|
+
if (!cell) return;
|
|
216
|
+
onSelect?.({
|
|
213
217
|
categoryIndex: cell.columnIndex,
|
|
214
218
|
categoryKey: cell.column,
|
|
215
219
|
seriesKey: cell.row,
|
|
216
220
|
...cell.value !== null && { value: cell.value }
|
|
217
221
|
});
|
|
218
|
-
|
|
222
|
+
toggleSelection({
|
|
223
|
+
categoryKey: cell.column,
|
|
224
|
+
seriesKey: cell.row
|
|
225
|
+
}, isAdditive);
|
|
226
|
+
}, [
|
|
227
|
+
geometry.cells,
|
|
228
|
+
onSelect,
|
|
229
|
+
toggleSelection
|
|
230
|
+
]);
|
|
219
231
|
const passedAriaLabel = typeof rest["aria-label"] === "string" ? rest["aria-label"] : void 0;
|
|
220
232
|
const resolvedAriaLabel = ariaLabel ?? passedAriaLabel ?? `Heatmap, ${columns.length} columns by ${rows.length} rows`;
|
|
221
233
|
const aspectRatio = clamp(columns.length / Math.max(1, rows.length), 1, 4);
|
|
@@ -256,7 +268,7 @@ var Heatmap = forwardRef(function Heatmap(props, ref) {
|
|
|
256
268
|
buildCategoryTooltip,
|
|
257
269
|
renderTooltip,
|
|
258
270
|
categoryTargets,
|
|
259
|
-
onCategorySelect: onSelect
|
|
271
|
+
onCategorySelect: onSelect || isFilterable ? handleSelect : void 0,
|
|
260
272
|
anchorHalfWidth: (geometry.cells[0]?.width ?? 0) / 2,
|
|
261
273
|
isEmpty,
|
|
262
274
|
isLoading,
|
package/dist/charts/LineChart.js
CHANGED
|
@@ -20,7 +20,8 @@ import { cx } from "@linaria/core";
|
|
|
20
20
|
* from `ChartPalette`; a `null` reading breaks the line instead of dropping to zero. Hover or
|
|
21
21
|
* keyboard focus works per category column: a cursor rule marks the column, every line shows its
|
|
22
22
|
* dot there, and the tooltip lists every line's value. Clicks and Enter report the category
|
|
23
|
-
* through `onSelect
|
|
23
|
+
* through `onSelect`; with `isFilterable` they also pin it, and legend clicks pin a line. It joins
|
|
24
|
+
* `ChartGroupProvider` sync.
|
|
24
25
|
*
|
|
25
26
|
* Filled series are `AreaChart`; inline trends without axes are `Sparkline`. The chart fills its
|
|
26
27
|
* parent (2:1 when the parent has no definite height): size it with a `Box`, `Grid` track or
|
|
@@ -40,7 +41,7 @@ var DEFAULT_PLACEHOLDER = "No data available";
|
|
|
40
41
|
* components, no public mode prop (the `MenuRoot` precedent).
|
|
41
42
|
*/
|
|
42
43
|
function LineChartRootInner(props, ref) {
|
|
43
|
-
const { series, lines, categories, curve = ChartCurve.SMOOTH, fill, isStacked, kind, valueFormatter, labelFormatter, valueDomain, axisLabels, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, ariaLabel, id, className, style, ...rest } = props;
|
|
44
|
+
const { series, lines, categories, curve = ChartCurve.SMOOTH, fill, isStacked, kind, valueFormatter, labelFormatter, valueDomain, axisLabels, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, isFilterable = false, defaultSelection, onSelectionChange, ariaLabel, id, className, style, ...rest } = props;
|
|
44
45
|
const plotRef = useRef(null);
|
|
45
46
|
const colors = useSeriesColorResolver(series);
|
|
46
47
|
const { dimensions, domain, valueTicks, formatValue, formatLabel } = useCartesianChartLayout({
|
|
@@ -93,7 +94,10 @@ function LineChartRootInner(props, ref) {
|
|
|
93
94
|
seriesKeys,
|
|
94
95
|
categoryKeys: geometry.categories,
|
|
95
96
|
selection,
|
|
96
|
-
|
|
97
|
+
isFilterable,
|
|
98
|
+
defaultSelection,
|
|
99
|
+
onSelectionChange,
|
|
100
|
+
isDisabled: !(hasTooltip || onSelect || isFilterable) || isLoading || isEmpty,
|
|
97
101
|
isLoading
|
|
98
102
|
});
|
|
99
103
|
const activeColumn = interaction.activeIndex === null ? void 0 : geometry.columns[interaction.activeIndex];
|
|
@@ -148,14 +152,20 @@ function LineChartRootInner(props, ref) {
|
|
|
148
152
|
width: column.bandWidth,
|
|
149
153
|
height: plotHeight
|
|
150
154
|
})), [geometry.columns, plotHeight]);
|
|
151
|
-
const
|
|
155
|
+
const { toggleSelection } = interaction;
|
|
156
|
+
const handleCategorySelect = useCallback((index, isAdditive = false) => {
|
|
152
157
|
const categoryKey = geometry.categories[index];
|
|
153
|
-
if (categoryKey === void 0
|
|
154
|
-
onSelect({
|
|
158
|
+
if (categoryKey === void 0) return;
|
|
159
|
+
onSelect?.({
|
|
155
160
|
categoryIndex: index,
|
|
156
161
|
categoryKey
|
|
157
162
|
});
|
|
158
|
-
|
|
163
|
+
toggleSelection({ categoryKey }, isAdditive);
|
|
164
|
+
}, [
|
|
165
|
+
geometry.categories,
|
|
166
|
+
onSelect,
|
|
167
|
+
toggleSelection
|
|
168
|
+
]);
|
|
159
169
|
const selectedColumns = geometry.columns.filter((column) => interaction.selectedCategoryIndices.has(column.categoryIndex));
|
|
160
170
|
const point = (item, keyPrefix = "") => /* @__PURE__ */ jsx("circle", {
|
|
161
171
|
cx: item.x,
|
|
@@ -200,12 +210,13 @@ function LineChartRootInner(props, ref) {
|
|
|
200
210
|
buildCategoryTooltip,
|
|
201
211
|
renderTooltip,
|
|
202
212
|
categoryTargets,
|
|
203
|
-
onCategorySelect: onSelect
|
|
213
|
+
onCategorySelect: onSelect || isFilterable ? handleCategorySelect : void 0,
|
|
204
214
|
anchorHalfWidth: geometry.step / 2,
|
|
205
215
|
isEmpty,
|
|
206
216
|
isLoading,
|
|
207
217
|
placeholder,
|
|
208
218
|
hasLegend,
|
|
219
|
+
formatCategoryKey: formatLabel,
|
|
209
220
|
legendItems,
|
|
210
221
|
legendPlacement: ChartLegendPlacement.BOTTOM,
|
|
211
222
|
legendSwatch: kind === ChartKind.AREA ? ChartLegendSwatch.SQUARE : ChartLegendSwatch.CIRCLE,
|
package/dist/charts/PieChart.js
CHANGED
|
@@ -47,7 +47,7 @@ var CenterBox = /*#__PURE__*/ styled("div")({
|
|
|
47
47
|
propsAsIs: false
|
|
48
48
|
});
|
|
49
49
|
function PieChartInner(props, ref) {
|
|
50
|
-
const { series, slices, isSolid = false, minSliceShare = PIE_MIN_SLICE_SHARE, aggregatedLabel = DEFAULT_AGGREGATED_LABEL, children, valueFormatter, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, ariaLabel, id, className, style, ...rest } = props;
|
|
50
|
+
const { series, slices, isSolid = false, minSliceShare = PIE_MIN_SLICE_SHARE, aggregatedLabel = DEFAULT_AGGREGATED_LABEL, children, valueFormatter, hasLegend = true, hasTooltip = true, renderTooltip, isLoading = false, placeholder = DEFAULT_PLACEHOLDER, onSelect, selection, isFilterable = false, defaultSelection, onSelectionChange, ariaLabel, id, className, style, ...rest } = props;
|
|
51
51
|
const plotRef = useRef(null);
|
|
52
52
|
const colors = useSeriesColorResolver(series);
|
|
53
53
|
const dimensions = useChartDimensions(plotRef, PLOT_INSETS);
|
|
@@ -93,7 +93,10 @@ function PieChartInner(props, ref) {
|
|
|
93
93
|
categoryKeys: arcKeys,
|
|
94
94
|
enableGroupSync: false,
|
|
95
95
|
selection,
|
|
96
|
-
|
|
96
|
+
isFilterable,
|
|
97
|
+
defaultSelection,
|
|
98
|
+
onSelectionChange,
|
|
99
|
+
isDisabled: !(hasTooltip || onSelect || isFilterable) || isLoading || isEmpty,
|
|
97
100
|
isLoading
|
|
98
101
|
});
|
|
99
102
|
const buildCategoryTooltip = useCallback((index) => {
|
|
@@ -123,16 +126,22 @@ function PieChartInner(props, ref) {
|
|
|
123
126
|
shape: ChartTargetShape.PATH,
|
|
124
127
|
d: item.path
|
|
125
128
|
})), [geometry.arcs]);
|
|
126
|
-
const
|
|
129
|
+
const { toggleSelection } = interaction;
|
|
130
|
+
const handleSelect = useCallback((index, isAdditive = false) => {
|
|
127
131
|
const item = resolvedSlices[index];
|
|
128
|
-
if (!item
|
|
129
|
-
onSelect({
|
|
132
|
+
if (!item) return;
|
|
133
|
+
onSelect?.({
|
|
130
134
|
categoryIndex: index,
|
|
131
135
|
categoryKey: item.id,
|
|
132
136
|
seriesKey: item.id,
|
|
133
137
|
value: item.value
|
|
134
138
|
});
|
|
135
|
-
|
|
139
|
+
toggleSelection({ seriesKey: item.id }, isAdditive);
|
|
140
|
+
}, [
|
|
141
|
+
resolvedSlices,
|
|
142
|
+
onSelect,
|
|
143
|
+
toggleSelection
|
|
144
|
+
]);
|
|
136
145
|
const passedAriaLabel = typeof rest["aria-label"] === "string" ? rest["aria-label"] : void 0;
|
|
137
146
|
const resolvedAriaLabel = ariaLabel ?? passedAriaLabel ?? `${isSolid ? "Pie" : "Donut"} chart, ${resolvedSlices.length} slices`;
|
|
138
147
|
const hasCenter = !isSolid && children !== void 0 && children !== null && !isEmpty;
|
|
@@ -172,7 +181,7 @@ function PieChartInner(props, ref) {
|
|
|
172
181
|
renderTooltip,
|
|
173
182
|
categoryTargets,
|
|
174
183
|
targetsTransform: centerTransform,
|
|
175
|
-
onCategorySelect: onSelect
|
|
184
|
+
onCategorySelect: onSelect || isFilterable ? handleSelect : void 0,
|
|
176
185
|
placeAwayFromX: geometry.centerX,
|
|
177
186
|
verticalAlign: ChartTooltipVerticalAlign.CENTERED,
|
|
178
187
|
isEmpty,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @internal The filter model behind `isFilterable`: a selection is a list of descriptors
|
|
3
|
+
* (`ChartSelection`), and a click toggles one. A plain click pins the descriptor alone, or unpins it
|
|
4
|
+
* when it is already the whole filter; an additive click (⌘ / Ctrl / Shift) adds or removes it.
|
|
5
|
+
*/
|
|
6
|
+
import type { KeyboardEvent as ReactKeyboardEvent, MouseEvent as ReactMouseEvent } from "react";
|
|
7
|
+
import type { ChartSelection, ChartSelectionInput } from "./types.js";
|
|
8
|
+
/** @internal The selection as a list; `null` and `undefined` are empty. */
|
|
9
|
+
export declare function toSelectionList<TKey extends string>(input: ChartSelectionInput<TKey> | undefined): ChartSelection<TKey>[];
|
|
10
|
+
/** @internal Two descriptors name the same marks: the same fields, the same values. */
|
|
11
|
+
export declare function isSameSelection(a: ChartSelection, b: ChartSelection): boolean;
|
|
12
|
+
/** @internal The filter after one click on `descriptor`. */
|
|
13
|
+
export declare function toggleSelection<TKey extends string>(current: ChartSelection<TKey>[], descriptor: ChartSelection<TKey>, isAdditive: boolean): ChartSelection<TKey>[];
|
|
14
|
+
/** @internal ⌘, Ctrl or Shift held: the click adds to the filter instead of replacing it. */
|
|
15
|
+
export declare function isAdditiveEvent(event: Pick<ReactMouseEvent | ReactKeyboardEvent, "metaKey" | "ctrlKey" | "shiftKey">): boolean;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//#region src/charts/chartSelection.ts
|
|
2
|
+
/** @internal The selection as a list; `null` and `undefined` are empty. */
|
|
3
|
+
function toSelectionList(input) {
|
|
4
|
+
if (input === void 0 || input === null) return [];
|
|
5
|
+
return Array.isArray(input) ? input : [input];
|
|
6
|
+
}
|
|
7
|
+
/** @internal Two descriptors name the same marks: the same fields, the same values. */
|
|
8
|
+
function isSameSelection(a, b) {
|
|
9
|
+
return a.categoryKey === b.categoryKey && a.seriesKey === b.seriesKey;
|
|
10
|
+
}
|
|
11
|
+
/** @internal The filter after one click on `descriptor`. */
|
|
12
|
+
function toggleSelection(current, descriptor, isAdditive) {
|
|
13
|
+
const isPinned = current.some((item) => isSameSelection(item, descriptor));
|
|
14
|
+
if (isAdditive) return isPinned ? current.filter((item) => !isSameSelection(item, descriptor)) : [...current, descriptor];
|
|
15
|
+
return isPinned && current.length === 1 ? [] : [descriptor];
|
|
16
|
+
}
|
|
17
|
+
/** @internal ⌘, Ctrl or Shift held: the click adds to the filter instead of replacing it. */
|
|
18
|
+
function isAdditiveEvent(event) {
|
|
19
|
+
return event.metaKey || event.ctrlKey || event.shiftKey;
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { isAdditiveEvent, isSameSelection, toSelectionList, toggleSelection };
|
|
@@ -97,6 +97,10 @@ export declare const CHART_TOOLTIP_OFFSET: number;
|
|
|
97
97
|
export declare const CHART_TOOLTIP_MAX_ROWS = 8;
|
|
98
98
|
/** @internal Gap between the plot box and a side-placed legend. */
|
|
99
99
|
export declare const CHART_LEGEND_SIDE_GAP: number;
|
|
100
|
+
/** @internal Height a side legend gives up to its filter chips: the 8px top padding and a 20px `Chip SMALL`. */
|
|
101
|
+
export declare const CHART_LEGEND_FILTER_EXTENT: number;
|
|
102
|
+
/** @internal Widest the filter chips grow (one or two) before their labels truncate; a bottom legend always keeps this much room for them. */
|
|
103
|
+
export declare const CHART_LEGEND_FILTER_MAX_WIDTH = 240;
|
|
100
104
|
/** @internal Height cap of the "+N more" legend list (about eight entries) before it scrolls. */
|
|
101
105
|
export declare const CHART_LEGEND_OVERFLOW_MAX_HEIGHT = 208;
|
|
102
106
|
/** @internal 2:1, the aspect-ratio fallback of cartesian charts and PieChart. */
|
package/dist/charts/constants.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RADIUS, SPACE } from "../theme/tokens/scales.js";
|
|
1
|
+
import { CONTROL_SIZE, RADIUS, SPACE } from "../theme/tokens/scales.js";
|
|
2
2
|
//#region src/charts/constants.ts
|
|
3
3
|
/**
|
|
4
4
|
* @internal Geometry and interaction constants for the chart family.
|
|
@@ -107,9 +107,13 @@ var CHART_TOOLTIP_OFFSET = px(SPACE[8]);
|
|
|
107
107
|
var CHART_TOOLTIP_MAX_ROWS = 8;
|
|
108
108
|
/** @internal Gap between the plot box and a side-placed legend. */
|
|
109
109
|
var CHART_LEGEND_SIDE_GAP = px(SPACE[16]);
|
|
110
|
+
/** @internal Height a side legend gives up to its filter chips: the 8px top padding and a 20px `Chip SMALL`. */
|
|
111
|
+
var CHART_LEGEND_FILTER_EXTENT = px(SPACE[8]) + px(CONTROL_SIZE.xSmall);
|
|
112
|
+
/** @internal Widest the filter chips grow (one or two) before their labels truncate; a bottom legend always keeps this much room for them. */
|
|
113
|
+
var CHART_LEGEND_FILTER_MAX_WIDTH = 240;
|
|
110
114
|
/** @internal Height cap of the "+N more" legend list (about eight entries) before it scrolls. */
|
|
111
115
|
var CHART_LEGEND_OVERFLOW_MAX_HEIGHT = 208;
|
|
112
116
|
/** @internal 2:1, the aspect-ratio fallback of cartesian charts and PieChart. */
|
|
113
117
|
var CHART_DEFAULT_ASPECT_RATIO = 2;
|
|
114
118
|
//#endregion
|
|
115
|
-
export { AREA_FILL_OPACITY, AREA_STACKED_FILL_OPACITY, AUTO_INSET_LEFT_STEP, AXIS_LABEL_GAP, AXIS_TITLE_BAND, AXIS_TITLE_GAP, BAR_GAP_RATIO, BAR_RADIUS, BAR_RADIUS_NARROW, CAPTION_CHAR_WIDTH_PX, CAPTION_LINE, CATEGORY_AXIS_LABEL_GAP, CATEGORY_AXIS_LABEL_HEIGHT, CATEGORY_GAP_RATIO, CHART_DEFAULT_ASPECT_RATIO, CHART_LEGEND_OVERFLOW_MAX_HEIGHT, CHART_LEGEND_SIDE_GAP, CHART_MARK_OPACITY_ACTIVE, CHART_MARK_OPACITY_DIMMED, CHART_MARK_OPACITY_MUTED, CHART_TOOLTIP_MAX_ROWS, CHART_TOOLTIP_OFFSET, DEFAULT_VALUE_TICK_COUNT, GRID_LINE_BLEED, HEATMAP_CELL_GAP_RATIO, LINE_DASH, LINE_POINT_RADIUS, LINE_STROKE_WIDTH, MAX_AUTO_INSET_LEFT, MAX_BAR_GAP, MAX_CATEGORY_GAP, MAX_HEATMAP_CELL_GAP, MIN_AUTO_INSET_LEFT, MIN_BAR_GAP, MIN_BAR_LENGTH, MIN_CATEGORY_GAP, MIN_CATEGORY_LABEL_GAP, MIN_HEATMAP_CELL_GAP, MIN_VALUE_TICK_SPACING, NARROW_BAR_WIDTH, PIE_SLICE_GAP, PLOT_INSET_BOTTOM, PLOT_INSET_RIGHT, PLOT_INSET_TOP, RADIAL_PLOT_INSET, STACK_SEGMENT_GAP, VALUE_AXIS_LABEL_HEIGHT, VALUE_AXIS_TICK_GAP };
|
|
119
|
+
export { AREA_FILL_OPACITY, AREA_STACKED_FILL_OPACITY, AUTO_INSET_LEFT_STEP, AXIS_LABEL_GAP, AXIS_TITLE_BAND, AXIS_TITLE_GAP, BAR_GAP_RATIO, BAR_RADIUS, BAR_RADIUS_NARROW, CAPTION_CHAR_WIDTH_PX, CAPTION_LINE, CATEGORY_AXIS_LABEL_GAP, CATEGORY_AXIS_LABEL_HEIGHT, CATEGORY_GAP_RATIO, CHART_DEFAULT_ASPECT_RATIO, CHART_LEGEND_FILTER_EXTENT, CHART_LEGEND_FILTER_MAX_WIDTH, CHART_LEGEND_OVERFLOW_MAX_HEIGHT, CHART_LEGEND_SIDE_GAP, CHART_MARK_OPACITY_ACTIVE, CHART_MARK_OPACITY_DIMMED, CHART_MARK_OPACITY_MUTED, CHART_TOOLTIP_MAX_ROWS, CHART_TOOLTIP_OFFSET, DEFAULT_VALUE_TICK_COUNT, GRID_LINE_BLEED, HEATMAP_CELL_GAP_RATIO, LINE_DASH, LINE_POINT_RADIUS, LINE_STROKE_WIDTH, MAX_AUTO_INSET_LEFT, MAX_BAR_GAP, MAX_CATEGORY_GAP, MAX_HEATMAP_CELL_GAP, MIN_AUTO_INSET_LEFT, MIN_BAR_GAP, MIN_BAR_LENGTH, MIN_CATEGORY_GAP, MIN_CATEGORY_LABEL_GAP, MIN_HEATMAP_CELL_GAP, MIN_VALUE_TICK_SPACING, NARROW_BAR_WIDTH, PIE_SLICE_GAP, PLOT_INSET_BOTTOM, PLOT_INSET_RIGHT, PLOT_INSET_TOP, RADIAL_PLOT_INSET, STACK_SEGMENT_GAP, VALUE_AXIS_LABEL_HEIGHT, VALUE_AXIS_TICK_GAP };
|
package/dist/charts/types.d.ts
CHANGED
|
@@ -281,8 +281,17 @@ export interface BaseChartProps<TKey extends string> extends AriaAttributes {
|
|
|
281
281
|
placeholder?: string;
|
|
282
282
|
/** Called when a mark or category is clicked, or Enter / Space is pressed on the active category. Supplying it makes the plot selectable. */
|
|
283
283
|
onSelect?: (event: ChartSelectionEvent<TKey>) => void;
|
|
284
|
-
/**
|
|
284
|
+
/**
|
|
285
|
+
* Click to filter. Clicking a legend entry, a mark or a category pins it (matching marks hold full strength, the rest recede); clicking it again unpins it, clicking another switches to it, and ⌘ / Ctrl / Shift-click adds or removes. While something is pinned, filter chips after the legend name it, one per part; a chip's × drops its part, and Escape on the plot clears the filter.
|
|
286
|
+
* @default false
|
|
287
|
+
*/
|
|
288
|
+
isFilterable?: boolean;
|
|
289
|
+
/** Which marks read as selected: matching marks hold full strength, the rest recede. With `isFilterable`, the controlled filter (pass it with `onSelectionChange`); without, presentational and never written by the chart. */
|
|
285
290
|
selection?: ChartSelectionInput<TKey>;
|
|
291
|
+
/** Initial filter while uncontrolled, with `isFilterable`. */
|
|
292
|
+
defaultSelection?: ChartSelectionInput<TKey>;
|
|
293
|
+
/** With `isFilterable`: called with the new filter when a click, Enter, Escape or the chip's × changes it. An empty array means cleared. */
|
|
294
|
+
onSelectionChange?: (selection: ChartSelection<TKey>[]) => void;
|
|
286
295
|
/** Accessible name of the chart. @default derived, e.g. Line chart, 12 categories, 3 series */
|
|
287
296
|
ariaLabel?: string;
|
|
288
297
|
/** DOM id on the root `<div>`. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChartMarkState, type ChartSelectionInput } from "./types.js";
|
|
1
|
+
import { ChartMarkState, type ChartSelection, type ChartSelectionInput } from "./types.js";
|
|
2
2
|
/** @internal Inputs of `useChartInteraction`. */
|
|
3
3
|
export interface UseChartInteractionOptions {
|
|
4
4
|
/** Number of categories (slices, cells). A shrinking count clears stale indices. */
|
|
@@ -9,8 +9,14 @@ export interface UseChartInteractionOptions {
|
|
|
9
9
|
categoryKeys?: string[];
|
|
10
10
|
/** Follow and publish to a `ChartGroupProvider`. PieChart and Heatmap pass `false`. @default true */
|
|
11
11
|
enableGroupSync?: boolean;
|
|
12
|
-
/** The caller's selection
|
|
12
|
+
/** The caller's selection: presentational, or the controlled filter with `isFilterable`. */
|
|
13
13
|
selection?: ChartSelectionInput | undefined;
|
|
14
|
+
/** Clicks toggle the filter; the filter chips' × and Escape clear it. @default false */
|
|
15
|
+
isFilterable?: boolean;
|
|
16
|
+
/** Initial filter while uncontrolled, with `isFilterable`. */
|
|
17
|
+
defaultSelection?: ChartSelectionInput | undefined;
|
|
18
|
+
/** Called with the new filter, with `isFilterable`. */
|
|
19
|
+
onSelectionChange?: ((selection: ChartSelection[]) => void) | undefined;
|
|
14
20
|
/** How off-category marks recede. @default ChartMarkState.MUTED */
|
|
15
21
|
categoryMuteState?: ChartMarkState;
|
|
16
22
|
/** No category interaction (static plot, loading, empty). The legend stays live. */
|
|
@@ -39,6 +45,22 @@ export interface ChartInteraction {
|
|
|
39
45
|
hoveredSeriesKey: string | null;
|
|
40
46
|
/** Categories the selection names outright (persistent cursors). */
|
|
41
47
|
selectedCategoryIndices: ReadonlySet<number>;
|
|
48
|
+
/** Clicks filter (`isFilterable`). */
|
|
49
|
+
isFilterable: boolean;
|
|
50
|
+
/** Something is pinned (or the caller's selection is not empty). */
|
|
51
|
+
hasSelection: boolean;
|
|
52
|
+
/** The selection as a list (the pinned filter with `isFilterable`). */
|
|
53
|
+
selection: readonly ChartSelection[];
|
|
54
|
+
/** One click on a descriptor: pin, unpin, switch, or (additive) add / remove. No-op unless filterable. */
|
|
55
|
+
toggleSelection: (descriptor: ChartSelection, isAdditive: boolean) => void;
|
|
56
|
+
/** Replace the filter (a chip's × dropping one part of a pin). No-op unless filterable. */
|
|
57
|
+
setSelection: (selection: ChartSelection[]) => void;
|
|
58
|
+
/** Clear the filter (the chip's ×, Escape). No-op unless filterable. */
|
|
59
|
+
clearSelection: () => void;
|
|
60
|
+
/** A legend entry's emphasis: the hovered entry, else whether the selection covers its series. */
|
|
61
|
+
getSeriesState: (seriesKey: string) => ChartMarkState;
|
|
62
|
+
/** The series is pinned on its own (`{ seriesKey }` is in the filter): its legend entry reads pressed. */
|
|
63
|
+
isSeriesPinned: (seriesKey: string) => boolean;
|
|
42
64
|
/** Emphasis of one mark, composed from selection, series and category. */
|
|
43
65
|
getMarkState: (args: ChartMarkStateArgs) => ChartMarkState;
|
|
44
66
|
/** Pointer entered a category's target. */
|
|
@@ -63,4 +85,4 @@ export declare function getNextCategoryIndex(current: number, key: string, count
|
|
|
63
85
|
columns: number;
|
|
64
86
|
}): number | null;
|
|
65
87
|
/** @internal Shared interaction model; see the module comment. */
|
|
66
|
-
export declare function useChartInteraction({ categoryCount, seriesKeys, categoryKeys, enableGroupSync, selection, categoryMuteState, isDisabled, isLoading, grid, }: UseChartInteractionOptions): ChartInteraction;
|
|
88
|
+
export declare function useChartInteraction({ categoryCount, seriesKeys, categoryKeys, enableGroupSync, selection, isFilterable, defaultSelection, onSelectionChange, categoryMuteState, isDisabled, isLoading, grid, }: UseChartInteractionOptions): ChartInteraction;
|