semiotic 3.6.0 → 3.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/CLAUDE.md +190 -227
- package/README.md +44 -14
- package/ai/cli.js +41 -0
- package/ai/componentMetadata.cjs +11 -2
- package/ai/dist/mcp-server.js +209 -6
- package/ai/examples.md +98 -0
- package/ai/schema.json +581 -1
- package/ai/system-prompt.md +5 -2
- package/dist/components/AccessibleNavTree.d.ts +25 -0
- package/dist/components/Annotation.d.ts +40 -14
- package/dist/components/ChartContainer.d.ts +32 -2
- package/dist/components/ai/annotationProvenance.d.ts +349 -0
- package/dist/components/ai/audienceProfile.d.ts +60 -3
- package/dist/components/ai/chartCapabilityTypes.d.ts +60 -2
- package/dist/components/ai/chartRoles.d.ts +27 -0
- package/dist/components/ai/conversationArc.d.ts +379 -0
- package/dist/components/ai/dataScaleProfile.d.ts +320 -0
- package/dist/components/ai/describeChart.d.ts +114 -0
- package/dist/components/ai/navigationTree.d.ts +45 -0
- package/dist/components/ai/readerGrounding.d.ts +70 -0
- package/dist/components/ai/suggestCharts.d.ts +34 -1
- package/dist/components/ai/useConversationArc.d.ts +89 -0
- package/dist/components/ai/useNavigationSync.d.ts +61 -0
- package/dist/components/ai/variantDiscovery.d.ts +168 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeLineChart.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +3 -0
- package/dist/components/charts/shared/annotationHierarchy.d.ts +42 -0
- package/dist/components/charts/shared/annotationResolvers.d.ts +3 -2
- package/dist/components/charts/shared/annotationRules.d.ts +16 -0
- package/dist/components/charts/shared/annotationTypes.d.ts +14 -0
- package/dist/components/charts/shared/auditAccessibility.d.ts +90 -0
- package/dist/components/charts/shared/chartSpecs.d.ts +2 -3
- package/dist/components/charts/shared/diagnoseConfig.d.ts +4 -6
- package/dist/components/charts/shared/selectionUtils.d.ts +5 -2
- package/dist/components/charts/shared/streamPropsHelpers.d.ts +2 -0
- package/dist/components/charts/shared/types.d.ts +5 -1
- package/dist/components/charts/value/BigNumber.capability.d.ts +13 -0
- package/dist/components/charts/value/BigNumber.d.ts +14 -0
- package/dist/components/charts/value/formatting.d.ts +40 -0
- package/dist/components/charts/value/thresholdSparkline.d.ts +40 -0
- package/dist/components/charts/value/types.d.ts +292 -0
- package/dist/components/realtime/lifecycleBands.d.ts +44 -0
- package/dist/components/realtime/types.d.ts +23 -8
- package/dist/components/recipes/annotationDensity.d.ts +69 -0
- package/dist/components/recipes/annotationLayout.d.ts +93 -0
- package/dist/components/semiotic-ai.d.ts +38 -15
- package/dist/components/semiotic-realtime.d.ts +2 -0
- package/dist/components/semiotic-recipes.d.ts +4 -0
- package/dist/components/semiotic-utils.d.ts +8 -0
- package/dist/components/semiotic-value.d.ts +55 -0
- package/dist/components/semiotic.d.ts +7 -0
- package/dist/components/server/staticAnnotations.d.ts +2 -0
- package/dist/components/stream/AccessibleDataTable.d.ts +10 -1
- package/dist/components/stream/NetworkSVGOverlay.d.ts +11 -5
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +2 -0
- package/dist/components/stream/SVGOverlay.d.ts +2 -0
- package/dist/components/stream/geoTypes.d.ts +3 -0
- package/dist/components/stream/networkTypes.d.ts +2 -0
- package/dist/components/stream/ordinalTypes.d.ts +2 -0
- package/dist/components/stream/types.d.ts +2 -0
- package/dist/geo.min.js +1 -1
- package/dist/geo.module.min.js +1 -1
- 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.d.ts +38 -15
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-realtime.d.ts +2 -0
- package/dist/semiotic-recipes.d.ts +4 -0
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-themes.min.js +1 -1
- package/dist/semiotic-themes.module.min.js +1 -1
- package/dist/semiotic-utils.d.ts +8 -0
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- package/dist/semiotic-value.d.ts +55 -0
- package/dist/semiotic-value.min.js +2 -0
- package/dist/semiotic-value.module.min.js +2 -0
- package/dist/semiotic.d.ts +7 -0
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/dist/server.min.js +1 -1
- package/dist/server.module.min.js +1 -1
- package/dist/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +18 -4
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { type ConversationArcEvent, type ConversationArcEventInput, type ConversationArcEventType, type EnableConversationArcOptions } from "./conversationArc";
|
|
2
|
+
/**
|
|
3
|
+
* Talk-friendly summary of an arc. Computed from the current buffer
|
|
4
|
+
* each time it's read. `summarizeArc` is exported separately for
|
|
5
|
+
* server-side or batch use.
|
|
6
|
+
*/
|
|
7
|
+
export interface ConversationArcSummary {
|
|
8
|
+
/** Total events buffered. */
|
|
9
|
+
total: number;
|
|
10
|
+
/** Per-type counts. Missing types implicitly zero. */
|
|
11
|
+
byType: Partial<Record<ConversationArcEventType, number>>;
|
|
12
|
+
/** Component names referenced across the buffer (deduplicated). */
|
|
13
|
+
componentsSeen: string[];
|
|
14
|
+
/** Audience labels referenced across the buffer (most recent last). */
|
|
15
|
+
audiencesSeen: string[];
|
|
16
|
+
/** Latest event's `arcId`, if any. */
|
|
17
|
+
latestArcId?: string;
|
|
18
|
+
/** Timestamp of the first event (epoch ms), or `null` if empty. */
|
|
19
|
+
startedAt: number | null;
|
|
20
|
+
/** Timestamp of the most recent event (epoch ms), or `null` if empty. */
|
|
21
|
+
lastAt: number | null;
|
|
22
|
+
/** Wall-clock duration covered by the buffer in ms, or `0` if empty. */
|
|
23
|
+
durationMs: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Reduce an event array to the talk-friendly `ConversationArcSummary`.
|
|
27
|
+
*
|
|
28
|
+
* Pure function — no `Date.now()` calls, no I/O. Safe to use on
|
|
29
|
+
* the server, in batch jobs, or against a replayed arc fixture.
|
|
30
|
+
*
|
|
31
|
+
* Walks the events once, so cost scales with buffer size; the default
|
|
32
|
+
* 1000-event capacity makes this trivially fast in practice.
|
|
33
|
+
*/
|
|
34
|
+
export declare function summarizeArc(events: ReadonlyArray<ConversationArcEvent>): ConversationArcSummary;
|
|
35
|
+
/**
|
|
36
|
+
* Options for {@link useConversationArc}. Mirrors the underlying
|
|
37
|
+
* `enableConversationArc` options, plus a `disableOnUnmount` escape
|
|
38
|
+
* hatch for consumers that own the entire arc lifecycle.
|
|
39
|
+
*/
|
|
40
|
+
export interface UseConversationArcOptions extends EnableConversationArcOptions {
|
|
41
|
+
/**
|
|
42
|
+
* Auto-enable the arc store on mount. Defaults to `true` — the
|
|
43
|
+
* common case is "I'm rendering the arc inspector / live dashboard,
|
|
44
|
+
* I want recording on while I'm mounted." Set to `false` if you
|
|
45
|
+
* want the hook to read but not flip the enable flag.
|
|
46
|
+
*/
|
|
47
|
+
enableOnMount?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Auto-disable on unmount. Defaults to `false` — disabling on
|
|
50
|
+
* unmount would cut off any other consumer that depends on
|
|
51
|
+
* recording staying live (the audience picker, an inspector panel
|
|
52
|
+
* in a sibling tree). Set to `true` if you own the whole session.
|
|
53
|
+
*/
|
|
54
|
+
disableOnUnmount?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Result returned from {@link useConversationArc}.
|
|
58
|
+
*/
|
|
59
|
+
export interface UseConversationArcResult {
|
|
60
|
+
/** Live event buffer, refreshed on every recorded event. */
|
|
61
|
+
/** Frozen snapshot of the live event buffer. Read-only; `.slice()` for a mutable copy. */
|
|
62
|
+
history: ReadonlyArray<ConversationArcEvent>;
|
|
63
|
+
/** Reduced summary of the current buffer. Recomputed on each event. */
|
|
64
|
+
summary: ConversationArcSummary;
|
|
65
|
+
/** `true` while the store is actively recording. */
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
/** Current session ID, or `null` before any `enable*` call. */
|
|
68
|
+
sessionId: string | null;
|
|
69
|
+
/** Record an event — stable across renders. Returns the stamped event, or `null` if disabled. */
|
|
70
|
+
record: (input: ConversationArcEventInput) => ConversationArcEvent | null;
|
|
71
|
+
/** Clear the buffered events without disabling the store. */
|
|
72
|
+
clear: () => void;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* React hook that participates in the conversation-arc session.
|
|
76
|
+
*
|
|
77
|
+
* Subscribes via `useSyncExternalStore` so re-renders are coordinated
|
|
78
|
+
* with React's concurrent rendering (no tearing between the buffer
|
|
79
|
+
* snapshot and the rendered tree). Auto-enables the store on mount
|
|
80
|
+
* by default; the underlying store is module-scoped, so all hook
|
|
81
|
+
* instances share the same buffer.
|
|
82
|
+
*
|
|
83
|
+
* ```tsx
|
|
84
|
+
* const { history, summary, record } = useConversationArc()
|
|
85
|
+
* // Later, in a click handler:
|
|
86
|
+
* record({ type: "chart-exported", component: "LineChart", format: "jsx" })
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function useConversationArc(options?: UseConversationArcOptions): UseConversationArcResult;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { NavTreeNode } from "./navigationTree";
|
|
2
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
3
|
+
/**
|
|
4
|
+
* useNavigationSync — keep an `AccessibleNavTree` and a chart in sync, both ways:
|
|
5
|
+
*
|
|
6
|
+
* tree → canvas : landing on a datum node highlights the matching mark (via
|
|
7
|
+
* the selection store — pass `selection` to the chart).
|
|
8
|
+
* canvas → tree : hovering/clicking a mark moves the tree's active node (via
|
|
9
|
+
* the observation store — give the chart a `chartId`).
|
|
10
|
+
*
|
|
11
|
+
* Both directions ride the existing module-global stores, so **no provider is
|
|
12
|
+
* required** — the chart just needs `chartId` and `selection={sync.selection}`,
|
|
13
|
+
* and the tree needs `activeId`/`onActiveChange`. Headless: BYO layout.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* const sync = useNavigationSync({ tree, chartId: "sales", matchFields: ["month"] })
|
|
17
|
+
* <LineChart chartId="sales" selection={sync.selection} {...props} />
|
|
18
|
+
* <AccessibleNavTree tree={tree} activeId={sync.activeId} onActiveChange={sync.onActiveChange} />
|
|
19
|
+
*/
|
|
20
|
+
export interface UseNavigationSyncOptions {
|
|
21
|
+
/** The navigation tree (from `buildNavigationTree`). */
|
|
22
|
+
tree: NavTreeNode;
|
|
23
|
+
/** `chartId` set on the chart, so its hover/click can be matched back to a leaf. */
|
|
24
|
+
chartId?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Fields that identify a datum for highlighting + matching. Defaults to the
|
|
27
|
+
* primitive-valued keys of the first leaf's datum.
|
|
28
|
+
*/
|
|
29
|
+
matchFields?: string[];
|
|
30
|
+
/** Selection name shared with the chart's `selection={{ name }}`. Default "__semiotic-nav-sync". */
|
|
31
|
+
selectionName?: string;
|
|
32
|
+
/** Which canvas observations move the tree. Default ["hover", "click"]. */
|
|
33
|
+
observe?: Array<"hover" | "click">;
|
|
34
|
+
/**
|
|
35
|
+
* The chart's annotations. An annotation anchored to a datum carries that
|
|
36
|
+
* datum's identifying fields (the same `matchFields` used for hover sync), so
|
|
37
|
+
* each one resolves to a nav-tree leaf. Lets a non-visual reader *reach* an
|
|
38
|
+
* anchored point — e.g. an AI's "anchored conversation" note — via
|
|
39
|
+
* `focusAnnotation`, and lets the tree mark annotated nodes via `annotatedIds`.
|
|
40
|
+
*/
|
|
41
|
+
annotations?: ReadonlyArray<Datum>;
|
|
42
|
+
}
|
|
43
|
+
export interface UseNavigationSyncResult {
|
|
44
|
+
/** Controlled active node id — pass to `AccessibleNavTree`. */
|
|
45
|
+
activeId: string;
|
|
46
|
+
/** Change handler — pass to `AccessibleNavTree` (drives the canvas highlight). */
|
|
47
|
+
onActiveChange: (node: NavTreeNode) => void;
|
|
48
|
+
/** Pass to the chart as `selection={sync.selection}`. */
|
|
49
|
+
selection: {
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
/** Nav-tree leaf ids that an annotation anchors to — mark these as "has a note". */
|
|
53
|
+
annotatedIds: Set<string>;
|
|
54
|
+
/**
|
|
55
|
+
* Move the tree (and canvas highlight) to an annotation's anchored node.
|
|
56
|
+
* Accepts an annotation object or its index in `annotations`. Returns `true`
|
|
57
|
+
* if the anchor resolved to a leaf. The reader lands on the anchored datum.
|
|
58
|
+
*/
|
|
59
|
+
focusAnnotation: (annotation: Datum | number) => boolean;
|
|
60
|
+
}
|
|
61
|
+
export declare function useNavigationSync(options: UseNavigationSyncOptions): UseNavigationSyncResult;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { ChartCapability, ChartDataProfile, ChartRubric, ChartVariant } from "./chartCapabilityTypes";
|
|
2
|
+
import type { IntentId } from "./intents";
|
|
3
|
+
import { type AudienceProfile } from "./audienceProfile";
|
|
4
|
+
/**
|
|
5
|
+
* Where a proposal came from. Used by scoring + ranking to weight
|
|
6
|
+
* trusted sources (manual hand-curated variants) above heuristic
|
|
7
|
+
* suggestions and model-generated proposals that need verification.
|
|
8
|
+
*/
|
|
9
|
+
export type VariantProposalSource = "manual" | "heuristic" | "model";
|
|
10
|
+
/**
|
|
11
|
+
* A "what if we tried this configuration?" candidate. Closely
|
|
12
|
+
* related to `ChartVariant`, but with explicit provenance and an
|
|
13
|
+
* optional `buildProps` so model-generated proposals can carry
|
|
14
|
+
* their own prop-construction logic without registering a full
|
|
15
|
+
* capability.
|
|
16
|
+
*
|
|
17
|
+
* The `id` is the durable identifier — the scoring side keys
|
|
18
|
+
* results by it so consumers can correlate proposals across
|
|
19
|
+
* propose/evaluate rounds.
|
|
20
|
+
*/
|
|
21
|
+
export interface VariantProposal {
|
|
22
|
+
/** Stable identifier — `<component>:<key>` is the conventional shape. */
|
|
23
|
+
id: string;
|
|
24
|
+
/** Component this proposal would render. */
|
|
25
|
+
baseComponent: string;
|
|
26
|
+
/** Human-facing label, usually a registered variant label or generated heuristic label. */
|
|
27
|
+
label?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Per-intent score deltas applied on top of the base capability's
|
|
30
|
+
* `intentScores`. Use sparingly — over-large deltas are a sign the
|
|
31
|
+
* proposal should be a separate chart, not a variant.
|
|
32
|
+
*/
|
|
33
|
+
intentDeltas?: Partial<Record<IntentId, number>>;
|
|
34
|
+
/** Rubric deltas applied on top of the base capability's rubric. */
|
|
35
|
+
rubricDeltas?: Partial<ChartRubric>;
|
|
36
|
+
/**
|
|
37
|
+
* Build the props this proposal would pass to the component. When
|
|
38
|
+
* omitted, the engine falls back to the capability's own
|
|
39
|
+
* `buildProps(profile, variant)`. Model-generated proposals
|
|
40
|
+
* typically provide their own.
|
|
41
|
+
*/
|
|
42
|
+
buildProps?: (profile: ChartDataProfile, audience?: AudienceProfile) => Record<string, unknown>;
|
|
43
|
+
/** Free-form natural-language rationale for the proposal. */
|
|
44
|
+
rationale?: string;
|
|
45
|
+
/** Where the proposal originated. */
|
|
46
|
+
source: VariantProposalSource;
|
|
47
|
+
/** Optional reference to a registered variant key when the proposal mirrors one. */
|
|
48
|
+
variantKey?: string;
|
|
49
|
+
/** Optional tags consumers can filter on (mirrors `ChartVariant.tags`). */
|
|
50
|
+
tags?: ReadonlyArray<string>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Why we'd reject a proposal: missing required field, conflicts with
|
|
54
|
+
* data type, audience mismatch above threshold, etc. Surfaced through
|
|
55
|
+
* `VariantScore.reasons`.
|
|
56
|
+
*/
|
|
57
|
+
export type VariantRejectionReason = string;
|
|
58
|
+
/**
|
|
59
|
+
* Result of evaluating a single proposal against a data profile and
|
|
60
|
+
* (optionally) an audience. Composes with the existing
|
|
61
|
+
* `suggestCharts` scoring vocabulary.
|
|
62
|
+
*/
|
|
63
|
+
export interface VariantScore {
|
|
64
|
+
/** Echoes `VariantProposal.id`. */
|
|
65
|
+
proposalId: string;
|
|
66
|
+
/**
|
|
67
|
+
* How well this proposal matches the profile + audience, 0..5.
|
|
68
|
+
* Drawn from the same 0..5 scale `suggestCharts` uses so consumers
|
|
69
|
+
* can mix variant proposals into a unified ranked list.
|
|
70
|
+
*/
|
|
71
|
+
fit: number;
|
|
72
|
+
/**
|
|
73
|
+
* How surprising the proposal is relative to the obvious
|
|
74
|
+
* recommendation, 0..1. Higher = more novel. The talk-track use
|
|
75
|
+
* is "a discovery model proposed a Ridgeline where the audience
|
|
76
|
+
* expected a BoxPlot."
|
|
77
|
+
*/
|
|
78
|
+
novelty: number;
|
|
79
|
+
/**
|
|
80
|
+
* Risk of misleading the audience, 0..1. Higher = more risky.
|
|
81
|
+
* Drives the visual treatment (warning chip, expanded caveats).
|
|
82
|
+
*/
|
|
83
|
+
risk: number;
|
|
84
|
+
/**
|
|
85
|
+
* Narrative reasons assembled from the capability `fits()` gate,
|
|
86
|
+
* rubric deltas, audience bias, and the discovery source. Suitable
|
|
87
|
+
* for tooltips and LLM context.
|
|
88
|
+
*/
|
|
89
|
+
reasons: ReadonlyArray<string>;
|
|
90
|
+
}
|
|
91
|
+
export interface EvaluateVariantProposalOptions {
|
|
92
|
+
/** Ranking intent(s). When omitted, fit uses the mean non-zero intent score. */
|
|
93
|
+
intent?: IntentId | ReadonlyArray<IntentId>;
|
|
94
|
+
/** Component the user started from — used to estimate cross-family novelty. */
|
|
95
|
+
baselineComponent?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Context handed to a discovery function. Carries everything a
|
|
99
|
+
* proposer needs to inspect the existing recommendation surface:
|
|
100
|
+
* the dataset profile, the audience, the already-considered
|
|
101
|
+
* variants, and the intent driving the recommendation.
|
|
102
|
+
*/
|
|
103
|
+
export interface VariantDiscoveryContext {
|
|
104
|
+
profile: ChartDataProfile;
|
|
105
|
+
audience?: AudienceProfile;
|
|
106
|
+
intent?: IntentId | ReadonlyArray<IntentId>;
|
|
107
|
+
/**
|
|
108
|
+
* Variants already attached to the base capability — proposers
|
|
109
|
+
* should avoid re-emitting these unless they have meaningful
|
|
110
|
+
* deltas a registered variant doesn't.
|
|
111
|
+
*/
|
|
112
|
+
existingVariants?: ReadonlyArray<ChartVariant>;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Signature for a proposal generator. Implementations may be
|
|
116
|
+
* heuristic, LLM-driven, or hand-coded. The engine collects
|
|
117
|
+
* proposals from every registered discovery function and ranks
|
|
118
|
+
* the union through `evaluateVariantProposal`.
|
|
119
|
+
*/
|
|
120
|
+
export type ProposeVariantFn = (component: string, capability: ChartCapability, context: VariantDiscoveryContext) => ReadonlyArray<VariantProposal>;
|
|
121
|
+
/**
|
|
122
|
+
* Signature for a scoring function. The default scorer composes the
|
|
123
|
+
* capability's `fits()` gate, rubric deltas, and audience bias. External
|
|
124
|
+
* scorers may add their own novelty/risk computations.
|
|
125
|
+
*/
|
|
126
|
+
export type EvaluateVariantProposalFn = (proposal: VariantProposal, profile: ChartDataProfile, audience?: AudienceProfile, options?: EvaluateVariantProposalOptions) => VariantScore;
|
|
127
|
+
/**
|
|
128
|
+
* Aggregates proposals from every registered discovery function.
|
|
129
|
+
*
|
|
130
|
+
* Each registered function is invoked with the same `(component,
|
|
131
|
+
* capability, context)` tuple; their results are concatenated and
|
|
132
|
+
* deduplicated by `VariantProposal.id` (first proposer wins). A
|
|
133
|
+
* proposer that throws is isolated — the error surfaces through
|
|
134
|
+
* `console.warn` and the remaining proposers still run.
|
|
135
|
+
*
|
|
136
|
+
* The built-in proposer first emits registered `capability.variants` as
|
|
137
|
+
* manual proposals, then adds conservative heuristic transforms and
|
|
138
|
+
* same-intent cross-family alternatives. Registered discovery functions
|
|
139
|
+
* run after that and are deduplicated by `VariantProposal.id`.
|
|
140
|
+
*/
|
|
141
|
+
export declare const proposeVariant: ProposeVariantFn;
|
|
142
|
+
/**
|
|
143
|
+
* Evaluate a proposal against the same ingredients the capability
|
|
144
|
+
* recommender uses: fits gate, intent scores, rubric deltas, and audience
|
|
145
|
+
* profile. `novelty` and `risk` are discovery-specific side channels.
|
|
146
|
+
*/
|
|
147
|
+
export declare const evaluateVariantProposal: EvaluateVariantProposalFn;
|
|
148
|
+
/**
|
|
149
|
+
* Register a discovery function. Returns an unregister callback.
|
|
150
|
+
*
|
|
151
|
+
* `proposeVariant` invokes every registered function and deduplicates
|
|
152
|
+
* by `VariantProposal.id`. External ML-driven proposers plug in here
|
|
153
|
+
* without API change.
|
|
154
|
+
*
|
|
155
|
+
* Built-in heuristic discovery lives in `proposeVariant` directly. This
|
|
156
|
+
* registry is the extension surface for consumers and model integrations.
|
|
157
|
+
*/
|
|
158
|
+
export declare function registerVariantDiscovery(fn: ProposeVariantFn): () => void;
|
|
159
|
+
/**
|
|
160
|
+
* Snapshot the registered discovery functions. Primarily for testing
|
|
161
|
+
* and for the engine implementation to iterate registered proposers.
|
|
162
|
+
*/
|
|
163
|
+
export declare function getRegisteredVariantDiscovery(): ReadonlyArray<ProposeVariantFn>;
|
|
164
|
+
/**
|
|
165
|
+
* Drop every registered discovery function. Exposed for tests and
|
|
166
|
+
* for consumers who need to swap discovery models between sessions.
|
|
167
|
+
*/
|
|
168
|
+
export declare function clearVariantDiscovery(): void;
|
|
@@ -6,6 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
|
6
6
|
import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
|
|
7
7
|
import type { OnObservationCallback } from "../../store/ObservationStore";
|
|
8
8
|
import type { Datum } from "../shared/datumTypes";
|
|
9
|
+
import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
|
|
9
10
|
export interface RealtimeHeatmapProps<TDatum extends Datum = Datum> {
|
|
10
11
|
/** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
|
|
11
12
|
mode?: ChartMode;
|
|
@@ -64,6 +65,8 @@ export interface RealtimeHeatmapProps<TDatum extends Datum = Datum> {
|
|
|
64
65
|
onHover?: (d: HoverData | null) => void;
|
|
65
66
|
/** Annotation objects */
|
|
66
67
|
annotations?: Datum[];
|
|
68
|
+
/** Opt into automatic placement for note-like annotations without manual offsets. */
|
|
69
|
+
autoPlaceAnnotations?: AutoPlaceAnnotations;
|
|
67
70
|
/** SVG annotation render function */
|
|
68
71
|
svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
|
|
69
72
|
/** Custom formatter for time axis ticks */
|
|
@@ -6,6 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
|
6
6
|
import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
|
|
7
7
|
import type { OnObservationCallback } from "../../store/ObservationStore";
|
|
8
8
|
import type { Datum } from "../shared/datumTypes";
|
|
9
|
+
import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
|
|
9
10
|
export type RealtimeHistogramDirection = "up" | "down";
|
|
10
11
|
export interface RealtimeHistogramProps<TDatum extends Datum = Datum> {
|
|
11
12
|
/** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
|
|
@@ -87,6 +88,8 @@ export interface RealtimeHistogramProps<TDatum extends Datum = Datum> {
|
|
|
87
88
|
onHover?: (d: HoverData | null) => void;
|
|
88
89
|
/** Annotation objects */
|
|
89
90
|
annotations?: Datum[];
|
|
91
|
+
/** Opt into automatic placement for note-like annotations without manual offsets. */
|
|
92
|
+
autoPlaceAnnotations?: AutoPlaceAnnotations;
|
|
90
93
|
/** SVG annotation render function */
|
|
91
94
|
svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
|
|
92
95
|
/** Custom formatter for time axis ticks */
|
|
@@ -6,6 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
|
6
6
|
import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
|
|
7
7
|
import type { OnObservationCallback } from "../../store/ObservationStore";
|
|
8
8
|
import type { Datum } from "../shared/datumTypes";
|
|
9
|
+
import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
|
|
9
10
|
export interface RealtimeLineChartProps<TDatum extends Datum = Datum> {
|
|
10
11
|
/** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
|
|
11
12
|
mode?: ChartMode;
|
|
@@ -64,6 +65,8 @@ export interface RealtimeLineChartProps<TDatum extends Datum = Datum> {
|
|
|
64
65
|
onHover?: (d: HoverData | null) => void;
|
|
65
66
|
/** Annotation objects */
|
|
66
67
|
annotations?: Datum[];
|
|
68
|
+
/** Opt into automatic placement for note-like annotations without manual offsets. */
|
|
69
|
+
autoPlaceAnnotations?: AutoPlaceAnnotations;
|
|
67
70
|
/** SVG annotation render function */
|
|
68
71
|
svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
|
|
69
72
|
/** Custom formatter for time axis ticks */
|
|
@@ -6,6 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
|
6
6
|
import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
|
|
7
7
|
import type { OnObservationCallback } from "../../store/ObservationStore";
|
|
8
8
|
import type { Datum } from "../shared/datumTypes";
|
|
9
|
+
import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
|
|
9
10
|
export interface RealtimeSwarmChartProps<TDatum extends Datum = Datum> {
|
|
10
11
|
/** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
|
|
11
12
|
mode?: ChartMode;
|
|
@@ -70,6 +71,8 @@ export interface RealtimeSwarmChartProps<TDatum extends Datum = Datum> {
|
|
|
70
71
|
onHover?: (d: HoverData | null) => void;
|
|
71
72
|
/** Annotation objects (including threshold coloring) */
|
|
72
73
|
annotations?: Datum[];
|
|
74
|
+
/** Opt into automatic placement for note-like annotations without manual offsets. */
|
|
75
|
+
autoPlaceAnnotations?: AutoPlaceAnnotations;
|
|
73
76
|
/** SVG annotation render function */
|
|
74
77
|
svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
|
|
75
78
|
/** Custom formatter for time axis ticks */
|
|
@@ -6,6 +6,7 @@ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
|
|
|
6
6
|
import type { ChartMode, ChartAccessor, SelectionConfig } from "../shared/types";
|
|
7
7
|
import type { OnObservationCallback } from "../../store/ObservationStore";
|
|
8
8
|
import type { Datum } from "../shared/datumTypes";
|
|
9
|
+
import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
|
|
9
10
|
export interface RealtimeWaterfallChartProps<TDatum extends Datum = Datum> {
|
|
10
11
|
/** Display mode: "primary" (full chrome), "context" (compact), "sparkline" (inline) */
|
|
11
12
|
mode?: ChartMode;
|
|
@@ -72,6 +73,8 @@ export interface RealtimeWaterfallChartProps<TDatum extends Datum = Datum> {
|
|
|
72
73
|
onHover?: (d: HoverData | null) => void;
|
|
73
74
|
/** Annotation objects */
|
|
74
75
|
annotations?: Datum[];
|
|
76
|
+
/** Opt into automatic placement for note-like annotations without manual offsets. */
|
|
77
|
+
autoPlaceAnnotations?: AutoPlaceAnnotations;
|
|
75
78
|
/** SVG annotation render function */
|
|
76
79
|
svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
|
|
77
80
|
/** Custom formatter for time axis ticks */
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Datum } from "./datumTypes";
|
|
3
|
+
export type AnnotationEmphasis = "primary" | "secondary";
|
|
4
|
+
/** A rendered annotation node paired with the source annotation it came
|
|
5
|
+
* from, so hierarchy treatment can read metadata after the per-type rule has
|
|
6
|
+
* produced the node. */
|
|
7
|
+
export interface AnnotationRenderPair {
|
|
8
|
+
node: React.ReactNode;
|
|
9
|
+
annotation: Datum;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Reveal CSS for M3 progressive disclosure. Density-deferred notes are hidden
|
|
13
|
+
* (opacity 0) until the chart they belong to is hovered or focused. The
|
|
14
|
+
* selectors are scoped to each frame's stable wrapper class so a chart only
|
|
15
|
+
* reveals its *own* deferred notes; `:focus-within` covers keyboard users who
|
|
16
|
+
* focus the canvas (the canvas lives inside the wrapper). Style rules are
|
|
17
|
+
* document-global regardless of where the `<style>` tag lands, so injecting it
|
|
18
|
+
* inside the (pointer-events:none) overlay svg is fine. Identical across charts
|
|
19
|
+
* — duplicate injections are harmless.
|
|
20
|
+
*/
|
|
21
|
+
export declare const ANNOTATION_DISCLOSURE_REVEAL_CSS: string;
|
|
22
|
+
/**
|
|
23
|
+
* Apply annotation hierarchy — Rahman et al.'s "Hierarchy" consideration,
|
|
24
|
+
* reusing the same `emphasis` token charts already accept (`"primary"` /
|
|
25
|
+
* `"secondary"`). A `secondary` annotation dims, shrinks note text through
|
|
26
|
+
* inherited SVG font-size, and yields z-order; a `primary` one paints at full
|
|
27
|
+
* weight and on top.
|
|
28
|
+
*
|
|
29
|
+
* If no explicit emphasis is declared, annotations with
|
|
30
|
+
* `provenance.confidence` get an inferred reading order: confidence
|
|
31
|
+
* descending, then authored array order. The visual output uses that order as
|
|
32
|
+
* a subtle opacity gradient, with higher-confidence notes painted later.
|
|
33
|
+
*
|
|
34
|
+
* Type-agnostic: it wraps whatever the per-type rule produced, so all
|
|
35
|
+
* annotation types get hierarchy without each rule knowing about it.
|
|
36
|
+
*
|
|
37
|
+
* Zero-overhead and structure-preserving when no annotation declares an
|
|
38
|
+
* explicit emphasis or provenance confidence: the original nodes are returned
|
|
39
|
+
* untouched (same keys, same order), so existing charts render identically.
|
|
40
|
+
* Opacity composes multiplicatively with lifecycle freshness opacity.
|
|
41
|
+
*/
|
|
42
|
+
export declare function applyAnnotationEmphasis(pairs: ReadonlyArray<AnnotationRenderPair>): React.ReactNode[];
|
|
@@ -3,8 +3,8 @@ import type { Datum } from "./datumTypes";
|
|
|
3
3
|
* Coordinate resolution helpers for annotations.
|
|
4
4
|
*
|
|
5
5
|
* Resolves data coordinates to pixel positions, respecting anchor modes
|
|
6
|
-
* (fixed, latest, sticky), pointId matching, and
|
|
7
|
-
* streaming charts where data scrolls off-screen.
|
|
6
|
+
* (fixed, latest, sticky, semantic), pointId / stableId matching, and
|
|
7
|
+
* bounds checking for streaming charts where data scrolls off-screen.
|
|
8
8
|
*
|
|
9
9
|
* Dependencies: types (AnnotationContext)
|
|
10
10
|
* Consumed by: annotationRules.tsx (all annotation type renderers)
|
|
@@ -17,6 +17,7 @@ export declare function resolveY(ann: Datum, context: AnnotationContext): number
|
|
|
17
17
|
* - "fixed" (default): resolve from annotation's own fields
|
|
18
18
|
* - "latest": resolve from the most recent datum in the buffer
|
|
19
19
|
* - "sticky": resolve from annotation fields; if not found, use cached position
|
|
20
|
+
* - "semantic": resolve from provenance.stableId; if not found, use recorded fields
|
|
20
21
|
*/
|
|
21
22
|
export declare function resolveAnchoredPosition(ann: Datum, index: number, context: AnnotationContext): {
|
|
22
23
|
x: number;
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { AnnotationContext } from "../../realtime/types";
|
|
3
3
|
import type { Datum } from "./datumTypes";
|
|
4
|
+
export { applyAnnotationEmphasis, type AnnotationRenderPair } from "./annotationHierarchy";
|
|
5
|
+
type AnnotationRule = (annotation: Datum, index: number, context: AnnotationContext) => React.ReactNode | null;
|
|
6
|
+
/**
|
|
7
|
+
* Run the SVG-overlay annotation pass: dispatch each annotation through the
|
|
8
|
+
* user's `svgAnnotationRules` (falling back to the default rules), drop the
|
|
9
|
+
* ones that render nothing, then apply emphasis hierarchy. Shared verbatim by
|
|
10
|
+
* the XY and ordinal overlays so the dispatch/filter/hierarchy logic lives in
|
|
11
|
+
* one place.
|
|
12
|
+
*
|
|
13
|
+
* Falsy-node semantics match the pre-emphasis `.filter(Boolean)` exactly: a
|
|
14
|
+
* rule returning `null`/`undefined` ("skip", e.g. the default rules' out-of-
|
|
15
|
+
* bounds path) — or any other falsy node (`0`/`""`/`false`) — produces no
|
|
16
|
+
* annotation and is dropped. A user rule that returns `null`/`undefined` falls
|
|
17
|
+
* through to the default rule, preserving the existing override contract.
|
|
18
|
+
*/
|
|
19
|
+
export declare function renderAnnotationPass(annotations: ReadonlyArray<Datum>, defaultRule: AnnotationRule, userRule: AnnotationRule | undefined, context: AnnotationContext): React.ReactNode[];
|
|
4
20
|
export declare function createDefaultAnnotationRules(_frameType: "xy" | "ordinal" | "network"): (annotation: Datum, index: number, context: AnnotationContext) => React.ReactNode | null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Datum } from "./datumTypes";
|
|
2
|
+
/**
|
|
3
|
+
* Note-like annotations compete for placement and density budgets. Keep this
|
|
4
|
+
* taxonomy centralized because layout, diagnostics, and accessibility checks
|
|
5
|
+
* all need to agree on what counts as a note.
|
|
6
|
+
*/
|
|
7
|
+
export declare const NOTE_ANNOTATION_TYPES: readonly ["label", "callout", "callout-circle", "callout-rect", "text", "widget"];
|
|
8
|
+
export type NoteAnnotationType = (typeof NOTE_ANNOTATION_TYPES)[number];
|
|
9
|
+
/** Note types whose default renderer draws a connector unless disabled. */
|
|
10
|
+
export declare const CONNECTOR_ANNOTATION_TYPES: readonly ["label", "callout", "callout-circle", "callout-rect"];
|
|
11
|
+
export declare function annotationType(annotation: Datum): string;
|
|
12
|
+
export declare function isNoteAnnotation(annotation: Datum): boolean;
|
|
13
|
+
export declare function annotationDisablesConnector(annotation: Datum): boolean;
|
|
14
|
+
export declare function annotationDrawsConnector(annotation: Datum): boolean;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Datum } from "./datumTypes";
|
|
2
|
+
export type A11yPrinciple = "perceivable" | "operable" | "understandable" | "robust" | "compromising" | "assistive" | "flexible";
|
|
3
|
+
/**
|
|
4
|
+
* - `pass` — satisfied (by config or by Semiotic's built-ins)
|
|
5
|
+
* - `fail` — a problem we can prove from the config
|
|
6
|
+
* - `warn` — a likely problem or a default worth revisiting
|
|
7
|
+
* - `manual`— can't be settled statically; run the named Chartability test
|
|
8
|
+
* - `not-applicable` — heuristic doesn't apply to this chart
|
|
9
|
+
*/
|
|
10
|
+
export type A11yStatus = "pass" | "fail" | "warn" | "manual" | "not-applicable";
|
|
11
|
+
export interface A11yFinding {
|
|
12
|
+
/** Stable id, `principle.heuristic-slug` (e.g. "perceivable.low-contrast"). */
|
|
13
|
+
id: string;
|
|
14
|
+
principle: A11yPrinciple;
|
|
15
|
+
/** The Chartability heuristic name, verbatim. */
|
|
16
|
+
heuristic: string;
|
|
17
|
+
/** Chartability flags 14 of 50 heuristics as critical. */
|
|
18
|
+
critical: boolean;
|
|
19
|
+
status: A11yStatus;
|
|
20
|
+
message: string;
|
|
21
|
+
/** How to fix or, for `manual`, the test to run. */
|
|
22
|
+
fix?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface AccessibilityAuditResult {
|
|
25
|
+
component: string;
|
|
26
|
+
/** No critical heuristic is in a `fail` state. (warn/manual don't break this.) */
|
|
27
|
+
ok: boolean;
|
|
28
|
+
summary: {
|
|
29
|
+
criticalsPassed: number;
|
|
30
|
+
/** Critical heuristics actually evaluated (excludes not-applicable). */
|
|
31
|
+
criticalsEvaluated: number;
|
|
32
|
+
fails: number;
|
|
33
|
+
warnings: number;
|
|
34
|
+
manual: number;
|
|
35
|
+
passes: number;
|
|
36
|
+
};
|
|
37
|
+
findings: A11yFinding[];
|
|
38
|
+
/** Always points back to the source framework. */
|
|
39
|
+
reference: string;
|
|
40
|
+
}
|
|
41
|
+
export interface AuditAccessibilityOptions {
|
|
42
|
+
/**
|
|
43
|
+
* Whether the chart is wrapped in a ChartContainer (or otherwise exposes a
|
|
44
|
+
* data-download / copy-config affordance). Lets the audit credit the
|
|
45
|
+
* "downloadable table" and "shareable state" heuristics. ChartContainer is
|
|
46
|
+
* the opt-in layer for full-accessibility chrome (title, caption,
|
|
47
|
+
* description), so several heuristics soften their remediation toward it.
|
|
48
|
+
* Default false.
|
|
49
|
+
*/
|
|
50
|
+
inChartContainer?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Whether ChartContainer's `describe` option (auto-generated L1–L3 description
|
|
53
|
+
* via describeChart) is enabled. Lets the "features described" heuristic pass.
|
|
54
|
+
* Default false.
|
|
55
|
+
*/
|
|
56
|
+
describe?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Whether ChartContainer's `navigable` option (a structured, screen-reader-
|
|
59
|
+
* navigable tree via buildNavigationTree/AccessibleNavTree) is enabled. Lets
|
|
60
|
+
* the "navigable structure" heuristic pass — including for hierarchy charts.
|
|
61
|
+
* Default false.
|
|
62
|
+
*/
|
|
63
|
+
navigable?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Audit a Semiotic chart configuration against the Chartability heuristics.
|
|
67
|
+
* Pure, SSR-safe, no DOM. See module docstring for what static analysis can
|
|
68
|
+
* and cannot determine.
|
|
69
|
+
*/
|
|
70
|
+
export declare function auditAccessibility(component: string, props: Datum, options?: AuditAccessibilityOptions): AccessibilityAuditResult;
|
|
71
|
+
/**
|
|
72
|
+
* Distil an audit result into terse caveat strings — the author-actionable
|
|
73
|
+
* `fail` and `warn` findings, one line each. Lets the recommender (and an AI
|
|
74
|
+
* agent) read *receivability* caveats ("8 slices is too many," "color-only
|
|
75
|
+
* encoding") from the same channel as the perceptual caveats a capability
|
|
76
|
+
* descriptor already declares, instead of two disconnected surfaces.
|
|
77
|
+
*
|
|
78
|
+
* Pure. Pair with {@link auditAccessibility}:
|
|
79
|
+
* ```ts
|
|
80
|
+
* const caveats = accessibilityCaveats(auditAccessibility("PieChart", props))
|
|
81
|
+
* ```
|
|
82
|
+
*
|
|
83
|
+
* @param onlyCritical When true, restrict to critical heuristics (the 14 that
|
|
84
|
+
* Chartability flags). Default false — include all fail/warn findings.
|
|
85
|
+
*/
|
|
86
|
+
export declare function accessibilityCaveats(result: AccessibilityAuditResult, { onlyCritical }?: {
|
|
87
|
+
onlyCritical?: boolean;
|
|
88
|
+
}): string[];
|
|
89
|
+
/** Render an audit result as a human-readable report (used by --audit-a11y + MCP). */
|
|
90
|
+
export declare function formatAccessibilityAudit(result: AccessibilityAuditResult): string;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
export type PropType = "string" | "number" | "boolean" | "array" | "object" | "function";
|
|
2
2
|
export type DataShape = "array" | "object" | "network" | "realtime" | "none";
|
|
3
|
-
export type ChartCategory = "xy" | "ordinal" | "network" | "geo" | "realtime";
|
|
3
|
+
export type ChartCategory = "xy" | "ordinal" | "network" | "geo" | "realtime" | "value";
|
|
4
4
|
/**
|
|
5
|
-
* Capability tags for runtime behavior.
|
|
6
|
-
* `hoc-frame-architecture-audit` Phase 1: each chart declares which
|
|
5
|
+
* Capability tags for runtime behavior. Each chart declares which
|
|
7
6
|
* features it actually supports so docs, AI/MCP tools, and CI gates
|
|
8
7
|
* can read structured truth instead of inferring it from the source.
|
|
9
8
|
*
|
|
@@ -9,10 +9,8 @@ export interface DiagnosisResult {
|
|
|
9
9
|
ok: boolean;
|
|
10
10
|
diagnoses: Diagnosis[];
|
|
11
11
|
}
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
|
|
16
|
-
* Runs validateProps internally — validation errors are included as diagnoses.
|
|
17
|
-
*/
|
|
12
|
+
/** WCAG contrast ratio between two hex colors. Exported for reuse by the
|
|
13
|
+
* accessibility audit (auditAccessibility.ts) — single source of truth for the
|
|
14
|
+
* contrast math. Returns null if either color isn't a parseable hex. */
|
|
15
|
+
export declare function contrastRatio(hex1: string, hex2: string): number | null;
|
|
18
16
|
export declare function diagnoseConfig(componentName: string, props: Datum): DiagnosisResult;
|
|
@@ -8,8 +8,10 @@ import type { Datum } from "./datumTypes";
|
|
|
8
8
|
export interface NormalizedLinkedHover {
|
|
9
9
|
name: string;
|
|
10
10
|
fields: string[];
|
|
11
|
-
mode?: "field" | "x-position";
|
|
11
|
+
mode?: "field" | "x-position" | "series";
|
|
12
12
|
xField?: string;
|
|
13
|
+
/** Explicit series-identity field for `mode: "series"`; overrides the auto-resolved one. */
|
|
14
|
+
seriesField?: string;
|
|
13
15
|
}
|
|
14
16
|
export interface NormalizedLinkedBrush {
|
|
15
17
|
name: string;
|
|
@@ -26,8 +28,9 @@ export interface NormalizedLinkedBrush {
|
|
|
26
28
|
export declare function normalizeLinkedHover(prop: boolean | string | {
|
|
27
29
|
name?: string;
|
|
28
30
|
fields?: string[];
|
|
29
|
-
mode?: "field" | "x-position";
|
|
31
|
+
mode?: "field" | "x-position" | "series";
|
|
30
32
|
xField?: string;
|
|
33
|
+
seriesField?: string;
|
|
31
34
|
} | undefined, fallbackFields?: string[]): NormalizedLinkedHover | null;
|
|
32
35
|
/**
|
|
33
36
|
* Normalize the linkedBrush prop into a consistent config object.
|