semiotic 3.7.3 → 3.7.4
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/CLAUDE.md +6 -3
- package/README.md +7 -8
- package/ai/schema.json +1 -1
- package/dist/components/LinkedCharts.d.ts +2 -2
- package/dist/components/charts/custom/NetworkCustomChart.d.ts +1 -1
- package/dist/components/recipes/lineageDag.d.ts +129 -0
- package/dist/components/semiotic-recipes.d.ts +2 -0
- package/dist/components/semiotic.d.ts +2 -2
- package/dist/components/store/useSelection.d.ts +22 -0
- package/dist/components/stream/networkCustomLayout.d.ts +35 -0
- package/dist/components/stream/networkTypes.d.ts +9 -0
- package/dist/network.min.js +1 -1
- package/dist/network.module.min.js +1 -1
- package/dist/ordinal.min.js +1 -1
- package/dist/ordinal.module.min.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-recipes.d.ts +2 -0
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic.d.ts +2 -2
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -131,9 +131,9 @@ When the catalog doesn't fit, three HOCs take a layout function emitting scene p
|
|
|
131
131
|
|
|
132
132
|
Layout signature differs by family:
|
|
133
133
|
- **XY/Ordinal**: `layout: (ctx) => { nodes, overlays? }`. `ctx`: `data`, `scales` ({x,y} XY | {o,r,projection} ordinal), `dimensions` (plot rect — center-anchored for radial ordinal, top-left otherwise), `theme`, `resolveColor(key)`, `config`.
|
|
134
|
-
- **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config
|
|
134
|
+
- **Network**: `layout: (ctx) => { sceneNodes?, sceneEdges?, labels?, overlays? }`. `ctx`: `nodes`, `edges`, `dimensions`, `theme`, `resolveColor(key)`, `config`, `selection` (shared-selection predicate `{ isActive, predicate(datum) }` from `LinkedCharts`, `null` when unwired — dim/highlight by it). Run external positioners (`d3-flextree`, `dagre`) then emit network scene primitives (circle/rect/arc nodes; line/bezier/curved edges).
|
|
135
135
|
|
|
136
|
-
`semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `flextreeLayout`, `dagreLayout`). BYO heavy deps (`d3-flextree`, `dagre`) in user code.
|
|
136
|
+
`semiotic/recipes` ships pure layout functions (`waffleLayout`, `calendarLayout`, `marimekkoLayout`, `bulletLayout`, `parallelCoordinatesLayout`, `flextreeLayout`, `dagreLayout`, `lineageDagLayout`). BYO heavy deps (`d3-flextree`, `dagre`) in user code. `lineageDagLayout` renders a pre-positioned **layered lineage/DAG** (reads logical layer/row coords, no re-layout) with composite node glyphs (one hit-rect per node + icon/label/store-chip chrome in `overlays`), level-of-detail collapse (full→compact→icon→dot), distinct dashed back-edges, and host-driven reach-dimming (`layoutConfig.reachableIds`) + selection (`layoutConfig.selectedId` / shared `ctx.selection`).
|
|
137
137
|
|
|
138
138
|
**Chrome (labels/axes/legends): the recipe owns it.** Recipes emit own chrome via `overlays` return field (ReactNode painted on top). Built-in axes via `showAxes` on the HOC work for layouts respecting the standard scale. Recipe convention: `showXxx` boolean toggles, `xxxFormat` callbacks. Shipped recipes' toggles: marimekko `showCategoryLabels`, bullet `showLabels`+`showTicks`, parallelCoordinates `showAxes`, flextree/dagre `showLabels`, waffle/calendar none.
|
|
139
139
|
|
|
@@ -143,13 +143,16 @@ Layout signature differs by family:
|
|
|
143
143
|
- Coords are plot-relative (frame translates by `margin`). Read `ctx.dimensions.plot`. Radial ordinal: `plot.x = -width/2`, `plot.y = -height/2` (center-translated).
|
|
144
144
|
- Layouts needing axis domains: pass `xExtent`/`yExtent` (XY) or `oExtent`/`rExtent` (ordinal) — those flow through scale construction *before* the layout runs.
|
|
145
145
|
- Streaming layouts: ingest via ref (`push`/`pushMany`); layout re-runs on each ingest. Overlays update on data-change paths, NOT per-frame.
|
|
146
|
+
- **On `NetworkCustomChart`, a `layoutConfig` change re-runs the layout (`buildScene`) WITHOUT re-ingesting the node/edge topology** — so drive interaction state, styling, or animation progress through `layoutConfig` for cheap per-frame updates; swapping `nodes`/`edges` (or the chart `width`/`height`) is the heavier path that re-ingests. Custom overlays are read straight from the store at render time (the frame's repaint re-reads them), so a recipe returning fresh JSX every layout call needs no per-frame `setState`.
|
|
146
147
|
- Custom layouts own their colors — always prefer `ctx.resolveColor(key)` over hardcoded literals. `CategoryColorProvider` integration is XY-only; for cross-chart sync on network/ordinal customLayouts, pass matching `colorScheme` to each.
|
|
148
|
+
- `NetworkCustomChart` accepts `selection` / `linkedHover` / `chartId` like the built-in network HOCs: hover/click emit into the shared selection store, and the resolved predicate arrives as `ctx.selection` so the layout can dim/highlight by a cross-chart selection. Host-owned per-render dimming (e.g. a graph-reachability set) is orthogonal — pass it through `layoutConfig` and read `ctx.config`.
|
|
147
149
|
- Tooltips: emit datum keys matching user-visible accessor names. Avoid underscored synthetic keys (default tooltip filters those out).
|
|
148
150
|
|
|
149
151
|
## Coordinated Views
|
|
150
152
|
|
|
151
153
|
**LinkedCharts** — `selections`. **CategoryColorProvider** — `colors`|`categories` + `colorScheme`.
|
|
152
|
-
Chart props: `selection`, `linkedHover`, `linkedBrush`. Hooks: `useSelection`, `useLinkedHover`, `useBrushSelection`.
|
|
154
|
+
Chart props: `selection`, `linkedHover`, `linkedBrush`. Hooks: `useSelection`, `useLinkedHover`, `useBrushSelection`. Works for `NetworkCustomChart` too — the resolved selection predicate is threaded into the custom layout as `ctx.selection`.
|
|
155
|
+
**`useSelectionActions(name)`** — write-only access (`selectPoints`/`clear`) that does NOT subscribe to selection state, so a *container* can push a selection (e.g. from a hover handler) without re-rendering; only the leaf consumers reading the selection re-render. The provider-at-top / consumers-at-leaves pattern for interaction-heavy coordinated views.
|
|
153
156
|
**Shared categories inside LinkedCharts → wrap in `CategoryColorProvider`.** Gives identical per-category colors AND makes LinkedCharts render one unified legend (suppressing individual chart legends). Without it, mismatched colors and duplicate legends.
|
|
154
157
|
**Linked crosshair**: `linkedHover={{ name: "sync", mode: "x-position", xField: "time" }}`. Click locks crosshair (dashed white); click/Escape unlocks.
|
|
155
158
|
**Linked series highlight** (series↔bar cross-highlight): `linkedHover={{ name: "sync", mode: "series" }}` auto-resolves the chart's series-identity field (colorBy/lineBy/areaBy/stackBy/groupBy) and keys the linked selection off it — no hand-wired `fields`. Add `seriesField: "region"` to override (align charts whose series live under different prop names). Modes are exclusive: `mode` is `"field"` (default) | `"x-position"` (crosshair) | `"series"`.
|
package/README.md
CHANGED
|
@@ -12,16 +12,15 @@ Simple charts in 5 lines. Network graphs, streaming data, and coordinated
|
|
|
12
12
|
dashboards when you need them. Structured schemas and an MCP server so
|
|
13
13
|
AI coding assistants generate correct chart code on the first try.
|
|
14
14
|
|
|
15
|
-
## What's New in 3.7.
|
|
15
|
+
## What's New in 3.7.4
|
|
16
16
|
|
|
17
|
-
3.7.
|
|
17
|
+
3.7.4 is a network-chart and maintenance patch release:
|
|
18
18
|
|
|
19
|
-
- `semiotic
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
discovery 404 behavior.
|
|
19
|
+
- `semiotic/recipes` adds lineage DAG helpers for laying out data-flow and KStreams-style network
|
|
20
|
+
diagrams.
|
|
21
|
+
- Network custom layouts now preserve selection metadata through streaming layout and render paths.
|
|
22
|
+
- Docs add the KStreams DAG recipe and expand custom network chart guidance, alongside
|
|
23
|
+
dependency updates for Prettier, TypeScript ESLint, Rollup, and Sharp.
|
|
25
24
|
|
|
26
25
|
```jsx
|
|
27
26
|
import { LineChart } from "semiotic/xy"
|
package/ai/schema.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { ResolutionMode } from "./store/SelectionStore";
|
|
3
3
|
type LegendInteractionMode = "highlight" | "isolate" | "none";
|
|
4
|
-
export { useSelection, useLinkedHover, useBrushSelection, useFilteredData } from "./store/useSelection";
|
|
5
|
-
export type { UseSelectionOptions, UseSelectionResult, UseLinkedHoverOptions, UseLinkedHoverResult, UseBrushSelectionOptions, UseBrushSelectionResult } from "./store/useSelection";
|
|
4
|
+
export { useSelection, useSelectionActions, useLinkedHover, useBrushSelection, useFilteredData } from "./store/useSelection";
|
|
5
|
+
export type { UseSelectionOptions, UseSelectionResult, UseSelectionActionsResult, UseLinkedHoverOptions, UseLinkedHoverResult, UseBrushSelectionOptions, UseBrushSelectionResult } from "./store/useSelection";
|
|
6
6
|
export { useChartObserver } from "./store/useObservation";
|
|
7
7
|
export type { UseChartObserverOptions, UseChartObserverResult } from "./store/useObservation";
|
|
8
8
|
/** Hook: returns true when a parent LinkedCharts is handling the legend. */
|
|
@@ -29,7 +29,7 @@ export interface NetworkCustomChartProps<TNode extends Datum = Datum, TEdge exte
|
|
|
29
29
|
* `legendGroups` array yourself and pass it through `frameProps.legend`.
|
|
30
30
|
*/
|
|
31
31
|
/** Additional StreamNetworkFrame props for advanced customization. */
|
|
32
|
-
frameProps?: Partial<Omit<StreamNetworkFrameProps, "nodes" | "edges" | "chartType" | "size" | "customNetworkLayout" | "layoutConfig">>;
|
|
32
|
+
frameProps?: Partial<Omit<StreamNetworkFrameProps, "nodes" | "edges" | "chartType" | "size" | "customNetworkLayout" | "layoutConfig" | "layoutSelection">>;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* NetworkCustomChart — escape hatch for bespoke network geometry.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { NetworkCustomLayout } from "../stream/networkCustomLayout";
|
|
3
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
4
|
+
/**
|
|
5
|
+
* Level of detail for a node glyph.
|
|
6
|
+
* - `full` container + icon + type label + truncated name + store-slot chips
|
|
7
|
+
* - `compact` container + icon + truncated name
|
|
8
|
+
* - `icon` container + icon only
|
|
9
|
+
* - `dot` a single ~5px circle (minimap density)
|
|
10
|
+
*/
|
|
11
|
+
export type LineageLod = "full" | "compact" | "icon" | "dot";
|
|
12
|
+
export interface LineageStoreSlot {
|
|
13
|
+
storeName: string;
|
|
14
|
+
slotIndex: number;
|
|
15
|
+
}
|
|
16
|
+
export interface LineageDagConfig {
|
|
17
|
+
/** Number of layers (x domain). Computed from node `x` extents when omitted. */
|
|
18
|
+
layerCount?: number;
|
|
19
|
+
/** Largest layer's row count (y domain). Computed from the data when omitted. */
|
|
20
|
+
maxLayerSize?: number;
|
|
21
|
+
/** Target full-glyph width / height in px. Shrunk to fit the plot. @default 172 / 54 */
|
|
22
|
+
nodeWidth?: number;
|
|
23
|
+
nodeHeight?: number;
|
|
24
|
+
/** Minimum gap reserved between glyphs when fitting. @default 26 / 18 */
|
|
25
|
+
minGapX?: number;
|
|
26
|
+
minGapY?: number;
|
|
27
|
+
/** Force a level of detail; `"auto"` derives it from the fitted glyph size. @default "auto" */
|
|
28
|
+
lod?: LineageLod | "auto";
|
|
29
|
+
/**
|
|
30
|
+
* Caller-supplied "reachable" set. When present, nodes/edges **outside**
|
|
31
|
+
* it dim to `dimOpacity`. This is the controlled-dimming channel: the host
|
|
32
|
+
* computes the set (e.g. downstream BFS of the hovered node) and re-renders.
|
|
33
|
+
* Independent of, and composes with, `NetworkLayoutContext.selection`.
|
|
34
|
+
*/
|
|
35
|
+
reachableIds?: Iterable<string> | null;
|
|
36
|
+
/** Currently-selected node id — drawn with the selection ring. Host-owned. */
|
|
37
|
+
selectedId?: string | null;
|
|
38
|
+
/** Opacity for dimmed (out-of-reach / unselected) marks. @default 0.14 */
|
|
39
|
+
dimOpacity?: number;
|
|
40
|
+
/** Logical layer index (0 = leftmost). @default "x" */
|
|
41
|
+
layerAccessor?: string;
|
|
42
|
+
/** Logical row offset within the layer (centered on 0). @default "y" */
|
|
43
|
+
rowAccessor?: string;
|
|
44
|
+
/** Node partition → fill family. @default "partition" */
|
|
45
|
+
partitionAccessor?: string;
|
|
46
|
+
/** Node semantic → icon. @default "semantic" */
|
|
47
|
+
semanticAccessor?: string;
|
|
48
|
+
/** Human label. @default "label" */
|
|
49
|
+
labelAccessor?: string;
|
|
50
|
+
/** Store list — `string[]` or `{storeName,slotIndex}[]`. @default "stores" */
|
|
51
|
+
storesAccessor?: string;
|
|
52
|
+
/** Edge "closes a cycle" flag. @default "isBackEdge" */
|
|
53
|
+
backEdgeAccessor?: string;
|
|
54
|
+
/** Edge type, drives edge color. @default "edgeType" */
|
|
55
|
+
edgeTypeAccessor?: string;
|
|
56
|
+
/** Fill per partition. Overridable; recipe ships dark-theme-friendly defaults. */
|
|
57
|
+
partitionColors?: Partial<Record<string, string>>;
|
|
58
|
+
/** Edge stroke per edgeType, plus `back` for back-edges. */
|
|
59
|
+
edgeColors?: Partial<Record<string, string>>;
|
|
60
|
+
/** Selection-ring stroke. @default var(--semiotic-focus, #ffcc33) */
|
|
61
|
+
accentColor?: string;
|
|
62
|
+
/** Container border stroke. @default var(--semiotic-border, #555) */
|
|
63
|
+
borderColor?: string;
|
|
64
|
+
/** Draw the store-slot chips in `full` LOD. @default true */
|
|
65
|
+
showStoreChips?: boolean;
|
|
66
|
+
/** Chip fill. @default var(--semiotic-info, #6a8caf) */
|
|
67
|
+
storeChipColor?: string;
|
|
68
|
+
/** Base edge opacity (non-dimmed). @default 0.5 */
|
|
69
|
+
edgeOpacity?: number;
|
|
70
|
+
/** Forward-edge stroke width in px. @default 1.25 */
|
|
71
|
+
edgeWidth?: number;
|
|
72
|
+
/** Back-edge stroke width in px. @default `edgeWidth`, else 1.5 */
|
|
73
|
+
backEdgeWidth?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Render the per-node icon. Receives the resolved semantic/partition, the
|
|
76
|
+
* pixel size to draw within, and a color hint. Return any SVG node. When
|
|
77
|
+
* omitted a labelled fallback chip is drawn. The demo passes a KStreams
|
|
78
|
+
* icon set here — keeping the recipe domain-agnostic.
|
|
79
|
+
*/
|
|
80
|
+
renderIcon?: (info: {
|
|
81
|
+
semantic: string;
|
|
82
|
+
partition: string;
|
|
83
|
+
size: number;
|
|
84
|
+
color: string;
|
|
85
|
+
node: Datum;
|
|
86
|
+
}) => ReactNode;
|
|
87
|
+
/** Small type label shown above the name in `full` LOD. @default the semantic. */
|
|
88
|
+
typeLabel?: (info: {
|
|
89
|
+
semantic: string;
|
|
90
|
+
partition: string;
|
|
91
|
+
node: Datum;
|
|
92
|
+
}) => string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* `lineageDagLayout` — a reusable layout recipe for **pre-positioned layered
|
|
96
|
+
* lineage / DAG graphs** with rich, composite node glyphs. Used here for the
|
|
97
|
+
* Kafka Streams topology viewer, but domain-agnostic: it reads logical
|
|
98
|
+
* `x` (layer) / `y` (row) coordinates the caller already computed (e.g. from a
|
|
99
|
+
* `dagLayoutFromGraph` pipeline) and maps them into the plot — it never runs a
|
|
100
|
+
* force sim or re-lays-out, so output is deterministic.
|
|
101
|
+
*
|
|
102
|
+
* **Composite glyphs as one hit-testable unit.** Each node emits exactly one
|
|
103
|
+
* `rect` (or `circle` in `dot` LOD) scene node — that single mark owns the
|
|
104
|
+
* canvas hit area and carries the node datum/id. All glyph chrome (semantic
|
|
105
|
+
* icon, type label, truncated name, per-store chips, selection ring) is drawn
|
|
106
|
+
* in the returned `overlays` layer, which is `pointer-events: none`, so it
|
|
107
|
+
* decorates without ever intercepting a hover. Hover/click therefore always
|
|
108
|
+
* resolve to the underlying node as a unit — see §5.2(a) of the spec.
|
|
109
|
+
*
|
|
110
|
+
* **Controlled dimming + selection, from outside.** `config.reachableIds`
|
|
111
|
+
* (host-computed set) dims everything outside it; `config.selectedId` draws
|
|
112
|
+
* the selection ring; both are owned by the host, never by the frame. The
|
|
113
|
+
* shared `NetworkLayoutContext.selection` predicate (from `LinkedCharts`)
|
|
114
|
+
* composes on top — a node dims if excluded by *either* cue.
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* import { NetworkCustomChart } from "semiotic/network"
|
|
119
|
+
* import { lineageDagLayout } from "semiotic/recipes"
|
|
120
|
+
*
|
|
121
|
+
* <NetworkCustomChart
|
|
122
|
+
* nodes={dagNodes} // each: { id, x: layer, y: row, partition, semantic, stores, label }
|
|
123
|
+
* edges={dagEdges} // each: { source, target, edgeType, isBackEdge }
|
|
124
|
+
* layout={lineageDagLayout}
|
|
125
|
+
* layoutConfig={{ layerCount, maxLayerSize, reachableIds, selectedId }}
|
|
126
|
+
* />
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export declare const lineageDagLayout: NetworkCustomLayout<LineageDagConfig>;
|
|
@@ -13,6 +13,8 @@ export { flextreeLayout } from "./recipes/flextree";
|
|
|
13
13
|
export type { FlextreeConfig } from "./recipes/flextree";
|
|
14
14
|
export { dagreLayout } from "./recipes/dagre";
|
|
15
15
|
export type { DagreConfig } from "./recipes/dagre";
|
|
16
|
+
export { lineageDagLayout } from "./recipes/lineageDag";
|
|
17
|
+
export type { LineageDagConfig, LineageLod, LineageStoreSlot } from "./recipes/lineageDag";
|
|
16
18
|
export { marimekkoLayout } from "./recipes/marimekko";
|
|
17
19
|
export type { MarimekkoConfig } from "./recipes/marimekko";
|
|
18
20
|
export { bulletLayout } from "./recipes/bullet";
|
|
@@ -32,8 +32,8 @@ export type { StreamOrdinalFrameProps, StreamOrdinalFrameHandle, OrdinalChartTyp
|
|
|
32
32
|
export type { StreamNetworkFrameProps, StreamNetworkFrameHandle, NetworkChartType, NetworkSceneNode, NetworkSceneEdge, NetworkLabel, ThresholdAlertConfig } from "./stream/networkTypes";
|
|
33
33
|
export type { SelectionConfig, LinkedHoverProp, LinkedBrushProp } from "./charts/shared/types";
|
|
34
34
|
export type { LinkedChartsProps } from "./LinkedCharts";
|
|
35
|
-
export { useSelection, useLinkedHover, useBrushSelection, useFilteredData } from "./LinkedCharts";
|
|
36
|
-
export type { UseSelectionOptions, UseSelectionResult, UseLinkedHoverOptions, UseLinkedHoverResult, UseBrushSelectionOptions, UseBrushSelectionResult } from "./LinkedCharts";
|
|
35
|
+
export { useSelection, useSelectionActions, useLinkedHover, useBrushSelection, useFilteredData } from "./LinkedCharts";
|
|
36
|
+
export type { UseSelectionOptions, UseSelectionResult, UseSelectionActionsResult, UseLinkedHoverOptions, UseLinkedHoverResult, UseBrushSelectionOptions, UseBrushSelectionResult } from "./LinkedCharts";
|
|
37
37
|
export { useChartObserver } from "./LinkedCharts";
|
|
38
38
|
export type { UseChartObserverOptions, UseChartObserverResult } from "./LinkedCharts";
|
|
39
39
|
export type { ChartObservation, OnObservationCallback } from "./store/ObservationStore";
|
|
@@ -23,6 +23,28 @@ export interface UseSelectionResult {
|
|
|
23
23
|
clientId: string;
|
|
24
24
|
}
|
|
25
25
|
export declare function useSelection(options: UseSelectionOptions): UseSelectionResult;
|
|
26
|
+
export interface UseSelectionActionsResult {
|
|
27
|
+
/** Set a point selection (categorical values) under this client's clause. */
|
|
28
|
+
selectPoints: (fieldValues: Record<string, unknown[]>) => void;
|
|
29
|
+
/** Clear this client's clause. */
|
|
30
|
+
clear: () => void;
|
|
31
|
+
/** This client's ID. */
|
|
32
|
+
clientId: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Write-only access to a named selection that **does not subscribe** to the
|
|
36
|
+
* selection state — selecting only the stable `setClause`/`clearClause`
|
|
37
|
+
* actions, so the calling component never re-renders when the selection
|
|
38
|
+
* changes.
|
|
39
|
+
*
|
|
40
|
+
* Use this when a *container* needs to push a selection (e.g. from a hover
|
|
41
|
+
* handler) but only the leaf consumers (the charts reading the selection)
|
|
42
|
+
* should re-render. Pairs with `LinkedCharts` for the
|
|
43
|
+
* provider-at-top / consumers-at-leaves pattern: the writer stays out of the
|
|
44
|
+
* re-render path, avoiding per-interaction reconciliation + allocation in the
|
|
45
|
+
* container subtree. For read + write, use `useSelection`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function useSelectionActions(name: string, clientId?: string): UseSelectionActionsResult;
|
|
26
48
|
export interface UseLinkedHoverOptions {
|
|
27
49
|
/** Selection name. Defaults to "hover" */
|
|
28
50
|
name?: string;
|
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
import type { NetworkSceneNode, NetworkSceneEdge, NetworkLabel, RealtimeNode, RealtimeEdge } from "./networkTypes";
|
|
3
3
|
import type { ThemeSemanticColors } from "./types";
|
|
4
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
5
|
+
/**
|
|
6
|
+
* The shared selection state, projected into the custom-layout context.
|
|
7
|
+
*
|
|
8
|
+
* When the chart participates in a `LinkedCharts` / selection store (via
|
|
9
|
+
* `NetworkCustomChart`'s `selection` / `linkedHover` props), the frame
|
|
10
|
+
* threads the resolved predicate here so a custom layout can dim or
|
|
11
|
+
* highlight marks by the *shared* selection — the same predicate the
|
|
12
|
+
* built-in HOCs apply to `nodeStyle`. Mirrors `SelectionHookResult`.
|
|
13
|
+
*
|
|
14
|
+
* `predicate` receives the **raw** datum (the user object you passed in
|
|
15
|
+
* `nodes`, i.e. `node.data ?? node`), matching the `d.data || d`
|
|
16
|
+
* convention the built-in network charts use. `isActive` is `false`
|
|
17
|
+
* when no selection clause is present — when `false`, treat every mark
|
|
18
|
+
* as selected (draw at full weight).
|
|
19
|
+
*
|
|
20
|
+
* This is orthogonal to `config` (your `layoutConfig` blob): use `config`
|
|
21
|
+
* for host-owned highlight sets you compute yourself (e.g. a graph
|
|
22
|
+
* reachability set), and `selection` for cross-chart coordination that
|
|
23
|
+
* rides the shared store.
|
|
24
|
+
*/
|
|
25
|
+
export interface NetworkLayoutSelection {
|
|
26
|
+
/** Whether a selection clause is currently active. */
|
|
27
|
+
isActive: boolean;
|
|
28
|
+
/** Returns `true` when the raw datum matches the active selection. */
|
|
29
|
+
predicate: (datum: Datum) => boolean;
|
|
30
|
+
}
|
|
4
31
|
/**
|
|
5
32
|
* customLayout escape hatch for `StreamNetworkFrame`.
|
|
6
33
|
*
|
|
@@ -54,6 +81,14 @@ export interface NetworkLayoutContext<C extends object = Record<string, unknown>
|
|
|
54
81
|
resolveColor: (key: string) => string;
|
|
55
82
|
/** User-supplied config blob threaded through `layoutConfig`. */
|
|
56
83
|
config: C;
|
|
84
|
+
/**
|
|
85
|
+
* Shared-selection projection. Present when the chart is wired to a
|
|
86
|
+
* `LinkedCharts` / selection store; `null` otherwise. Use
|
|
87
|
+
* `selection.isActive` + `selection.predicate(node.data ?? node)` to
|
|
88
|
+
* dim/highlight marks by the cross-chart selection. See
|
|
89
|
+
* {@link NetworkLayoutSelection}.
|
|
90
|
+
*/
|
|
91
|
+
selection?: NetworkLayoutSelection | null;
|
|
57
92
|
}
|
|
58
93
|
export interface NetworkLayoutResult {
|
|
59
94
|
/** Positioned scene primitives. Circles, rects, or arcs. */
|
|
@@ -453,6 +453,11 @@ export interface NetworkPipelineConfig {
|
|
|
453
453
|
customNetworkLayout?: import("./networkCustomLayout").NetworkCustomLayout;
|
|
454
454
|
/** User-supplied config blob threaded through to NetworkLayoutContext.config. */
|
|
455
455
|
layoutConfig?: object;
|
|
456
|
+
/** Resolved shared-selection predicate, surfaced to a custom layout as
|
|
457
|
+
* `NetworkLayoutContext.selection`. Render-only — deliberately kept out of
|
|
458
|
+
* the layout/ingest-affecting signature so a selection change re-runs
|
|
459
|
+
* `buildScene` (re-emitting dimmed marks) without a re-ingest or re-layout. */
|
|
460
|
+
layoutSelection?: import("./networkCustomLayout").NetworkLayoutSelection | null;
|
|
456
461
|
}
|
|
457
462
|
export interface StreamNetworkFrameProps<T = Datum> {
|
|
458
463
|
chartType: NetworkChartType;
|
|
@@ -566,6 +571,10 @@ export interface StreamNetworkFrameProps<T = Datum> {
|
|
|
566
571
|
customNetworkLayout?: import("./networkCustomLayout").NetworkCustomLayout;
|
|
567
572
|
/** User-supplied config blob threaded through to NetworkLayoutContext.config. */
|
|
568
573
|
layoutConfig?: object;
|
|
574
|
+
/** Resolved shared-selection predicate, surfaced to a custom layout as
|
|
575
|
+
* `NetworkLayoutContext.selection`. Set by `NetworkCustomChart` from its
|
|
576
|
+
* `selection` / `linkedHover` wiring; render-only (no re-ingest on change). */
|
|
577
|
+
layoutSelection?: import("./networkCustomLayout").NetworkLayoutSelection | null;
|
|
569
578
|
}
|
|
570
579
|
export interface StreamNetworkFrameHandle {
|
|
571
580
|
push(edge: EdgePush): void;
|