semiotic 3.5.4 → 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 +196 -175
- package/README.md +52 -15
- package/ai/cli.js +41 -0
- package/ai/componentMetadata.cjs +11 -2
- package/ai/dist/mcp-server.js +454 -4
- package/ai/examples.md +98 -0
- package/ai/schema.json +614 -9
- 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 +147 -0
- package/dist/components/ai/audiences.d.ts +31 -0
- package/dist/components/ai/chartCapabilities.d.ts +55 -0
- package/dist/components/ai/chartCapabilityTypes.d.ts +254 -0
- 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/diffProfile.d.ts +51 -0
- package/dist/components/ai/inferIntent.d.ts +24 -0
- package/dist/components/ai/intents.d.ts +34 -0
- package/dist/components/ai/navigationTree.d.ts +45 -0
- package/dist/components/ai/profileData.d.ts +16 -0
- package/dist/components/ai/qualityFixtures.d.ts +2 -0
- package/dist/components/ai/qualityScorecard.d.ts +82 -0
- package/dist/components/ai/readerGrounding.d.ts +70 -0
- package/dist/components/ai/repairChartConfig.d.ts +73 -0
- package/dist/components/ai/streamingTypes.d.ts +64 -0
- package/dist/components/ai/suggestCharts.d.ts +109 -0
- package/dist/components/ai/suggestDashboard.d.ts +92 -0
- package/dist/components/ai/suggestStreamCharts.d.ts +34 -0
- package/dist/components/ai/suggestStretchCharts.d.ts +60 -0
- package/dist/components/ai/useChartSuggestions.d.ts +22 -0
- 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/geo/ChoroplethMap.capability.d.ts +2 -0
- package/dist/components/charts/geo/DistanceCartogram.capability.d.ts +2 -0
- package/dist/components/charts/geo/FlowMap.capability.d.ts +2 -0
- package/dist/components/charts/geo/ProportionalSymbolMap.capability.d.ts +2 -0
- package/dist/components/charts/index.d.ts +1 -1
- package/dist/components/charts/network/ChordDiagram.capability.d.ts +2 -0
- package/dist/components/charts/network/CirclePack.capability.d.ts +2 -0
- package/dist/components/charts/network/ForceDirectedGraph.capability.d.ts +2 -0
- package/dist/components/charts/network/OrbitDiagram.capability.d.ts +2 -0
- package/dist/components/charts/network/ProcessSankey.capability.d.ts +2 -0
- package/dist/components/charts/network/SankeyDiagram.capability.d.ts +2 -0
- package/dist/components/charts/network/TreeDiagram.capability.d.ts +2 -0
- package/dist/components/charts/network/Treemap.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/BarChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/BoxPlot.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/DonutChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/DotPlot.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/FunnelChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/GaugeChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/GroupedBarChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/Histogram.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/Histogram.d.ts +4 -2
- package/dist/components/charts/ordinal/LikertChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/LikertChart.d.ts +1 -1
- package/dist/components/charts/ordinal/LikertChart.defaults.d.ts +1 -0
- package/dist/components/charts/ordinal/PieChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/RidgelinePlot.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/StackedBarChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/SwarmPlot.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/SwimlaneChart.capability.d.ts +2 -0
- package/dist/components/charts/ordinal/ViolinPlot.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeHistogram.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeLineChart.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeLineChart.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +3 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.capability.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +3 -0
- package/dist/components/charts/realtime/TemporalHistogram.capability.d.ts +7 -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 -37
- 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/charts/xy/AreaChart.capability.d.ts +10 -0
- package/dist/components/charts/xy/BubbleChart.capability.d.ts +2 -0
- package/dist/components/charts/xy/CandlestickChart.capability.d.ts +2 -0
- package/dist/components/charts/xy/ConnectedScatterplot.capability.d.ts +2 -0
- package/dist/components/charts/xy/DifferenceChart.capability.d.ts +8 -0
- package/dist/components/charts/xy/Heatmap.capability.d.ts +9 -0
- package/dist/components/charts/xy/LineChart.capability.d.ts +9 -0
- package/dist/components/charts/xy/MinimapChart.capability.d.ts +2 -0
- package/dist/components/charts/xy/MultiAxisLineChart.capability.d.ts +2 -0
- package/dist/components/charts/xy/QuadrantChart.capability.d.ts +2 -0
- package/dist/components/charts/xy/QuadrantChart.d.ts +5 -2
- package/dist/components/charts/xy/QuadrantChart.defaults.d.ts +2 -0
- package/dist/components/charts/xy/Scatterplot.capability.d.ts +2 -0
- package/dist/components/charts/xy/StackedAreaChart.capability.d.ts +2 -0
- package/dist/components/data/DataSummarizer.d.ts +45 -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 +58 -0
- 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-xy.d.ts +1 -1
- package/dist/components/semiotic.d.ts +8 -1
- package/dist/components/server/staticAnnotations.d.ts +2 -0
- package/dist/components/store/useChartFocus.d.ts +43 -0
- package/dist/components/store/useChartInterrogation.d.ts +141 -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 +58 -0
- 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-xy.d.ts +1 -1
- package/dist/semiotic.d.ts +8 -1
- 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 +28 -5
package/ai/system-prompt.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- semiotic-bundle-sizes:start -->
|
|
4
4
|
<!-- Auto-generated by scripts/sync-bundle-sizes.mjs — do not edit by hand. -->
|
|
5
|
-
**Use sub-path imports** — `semiotic/xy` (
|
|
5
|
+
**Use sub-path imports** — `semiotic/xy` (90KB gz), `semiotic/ordinal` (74KB gz), `semiotic/network` (68KB gz), `semiotic/geo` (55KB gz), `semiotic/realtime` (95KB gz), `semiotic/server` (127KB gz), `semiotic/utils` (37KB gz), `semiotic/recipes` (9KB gz), `semiotic/themes` (4KB gz), `semiotic/data` (3KB gz), `semiotic/value` (6KB gz), `semiotic/ai` (246KB gz). Full `semiotic` is 203KB gz.
|
|
6
6
|
<!-- semiotic-bundle-sizes:end -->
|
|
7
7
|
|
|
8
8
|
## Flat Array Data (`data: object[]`)
|
|
@@ -84,12 +84,15 @@ Callback receiving `ChartObservation`: `{ type: "hover"|"click"|"brush"|"selecti
|
|
|
84
84
|
### emphasis
|
|
85
85
|
`emphasis="primary"` makes a chart span two columns inside a `ChartGrid`.
|
|
86
86
|
|
|
87
|
-
## Annotations (
|
|
87
|
+
## Annotations (all chart families)
|
|
88
88
|
- `annotations={[{ type: "y-threshold", value: 200, label: "SLA limit", color: "#e45050", labelPosition: "right" }]}` — horizontal reference line (works on XY and vertical ordinal charts). `labelPosition`: "left"|"center"|"right"
|
|
89
89
|
- `annotations={[{ type: "x-threshold", value: 50, label: "Cutoff", labelPosition: "top" }]}` — vertical reference line. `labelPosition`: "top"|"center"|"bottom"
|
|
90
|
+
- `annotations={[{ type: "callout-circle", x: 5, y: 20, label: "Peak", radius: 12 }]}` — data-bound callout; use `callout-rect` with `width`/`height` for a rectangular subject
|
|
90
91
|
- `annotations={[{ type: "category-highlight", category: "Q3 2024", color: "#4589ff", opacity: 0.15 }]}` — highlight a category column/row in ordinal charts
|
|
91
92
|
- `annotations={[{ type: "widget", time: 42, latency: 850, dy: -10, content: <span>Alert</span> }]}` — place React element at data coordinates
|
|
92
93
|
- `annotations={[{ type: "enclose", coordinates: [datum1, datum2], label: "Cluster" }]}` — circle enclosing data points
|
|
94
|
+
- `autoPlaceAnnotations={{ density: true, progressiveDisclosure: true, redundantCues: true }}` — opt-in placement, clutter management, and non-color association support
|
|
95
|
+
- Annotation metadata: `emphasis`, `defensive`, `provenance`, and `lifecycle`; use `applyAnnotationLifecycle`, `applyAnnotationStatus`, and `filterAnnotationsByStatus` from `semiotic/ai`
|
|
93
96
|
|
|
94
97
|
## Theming & Brand Styling
|
|
95
98
|
All charts respond to CSS custom properties on any ancestor:
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type NavTreeNode } from "./ai/navigationTree";
|
|
2
|
+
export interface AccessibleNavTreeProps {
|
|
3
|
+
tree: NavTreeNode;
|
|
4
|
+
/** Accessible name for the tree. */
|
|
5
|
+
label?: string;
|
|
6
|
+
/** Show the tree visibly (default: screen-reader-only). */
|
|
7
|
+
visible?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
/** Fired when the active node changes (e.g. to highlight the matching mark). */
|
|
10
|
+
onActiveChange?: (node: NavTreeNode) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Controlled active node id. When provided, the parent owns the active node
|
|
13
|
+
* (e.g. `useNavigationSync` driving it from the chart's hover). The tree
|
|
14
|
+
* auto-expands the path to a controlled active node so it stays visible.
|
|
15
|
+
*/
|
|
16
|
+
activeId?: string;
|
|
17
|
+
/**
|
|
18
|
+
* `chartId` of the chart this tree describes. Correlates the reception
|
|
19
|
+
* telemetry the tree emits (`nav-node-focused` / `nav-branch-expanded`
|
|
20
|
+
* conversation-arc events) back to the chart. Events are only recorded while
|
|
21
|
+
* the conversation-arc store is enabled — zero-overhead otherwise.
|
|
22
|
+
*/
|
|
23
|
+
chartId?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function AccessibleNavTree({ tree, label, visible, className, onActiveChange, activeId: controlledActiveId, chartId }: AccessibleNavTreeProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,11 +1,41 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
type AnnotationEventHandlers = Record<string, (e: React.SyntheticEvent) => void>;
|
|
3
|
+
type AnnotationNote = {
|
|
4
|
+
label?: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
wrap?: number;
|
|
7
|
+
orientation?: string;
|
|
8
|
+
align?: string;
|
|
9
|
+
noWrap?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type AnnotationConnector = {
|
|
12
|
+
end?: "arrow";
|
|
13
|
+
type?: "line" | "curve";
|
|
14
|
+
curve?: number;
|
|
15
|
+
};
|
|
16
|
+
type AnnotationSubject = {
|
|
17
|
+
radius?: number;
|
|
18
|
+
radiusPadding?: number;
|
|
19
|
+
width?: number;
|
|
20
|
+
height?: number;
|
|
21
|
+
custom?: React.ReactElement | React.ReactElement[];
|
|
22
|
+
x?: number;
|
|
23
|
+
y?: number;
|
|
24
|
+
x1?: number;
|
|
25
|
+
x2?: number;
|
|
26
|
+
y1?: number;
|
|
27
|
+
y2?: number;
|
|
28
|
+
type?: string;
|
|
29
|
+
depth?: number;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
};
|
|
2
32
|
/** Props for the single-annotation renderer. Consumed only by `SemioticAnnotation`
|
|
3
33
|
* below; the broader annotation API flows through the frame-level `annotations`
|
|
4
34
|
* array and its `svgAnnotationRules` hook. */
|
|
5
35
|
export interface AnnotationProps {
|
|
6
36
|
noteData: {
|
|
7
|
-
eventListeners?:
|
|
8
|
-
events?:
|
|
37
|
+
eventListeners?: AnnotationEventHandlers;
|
|
38
|
+
events?: AnnotationEventHandlers;
|
|
9
39
|
type: string;
|
|
10
40
|
screenCoordinates?: number[][];
|
|
11
41
|
/** When truthy, `screenCoordinates` is read as a sequence of anchor points
|
|
@@ -19,25 +49,21 @@ export interface AnnotationProps {
|
|
|
19
49
|
ny?: number;
|
|
20
50
|
dx?: number;
|
|
21
51
|
dy?: number;
|
|
22
|
-
note:
|
|
23
|
-
label?: string;
|
|
24
|
-
title?: string;
|
|
25
|
-
wrap?: number;
|
|
26
|
-
orientation?: string;
|
|
27
|
-
align?: string;
|
|
28
|
-
noWrap?: boolean;
|
|
29
|
-
};
|
|
52
|
+
note: AnnotationNote;
|
|
30
53
|
i?: number;
|
|
31
54
|
fixedPosition?: boolean;
|
|
32
55
|
label?: string;
|
|
33
|
-
connector?:
|
|
34
|
-
|
|
35
|
-
};
|
|
36
|
-
subject?: Record<string, unknown>;
|
|
56
|
+
connector?: AnnotationConnector;
|
|
57
|
+
subject?: AnnotationSubject;
|
|
37
58
|
color?: string;
|
|
38
59
|
className?: string;
|
|
39
60
|
disable?: string[];
|
|
61
|
+
/** SVG opacity cascaded to every stroked/filled child of the annotation. */
|
|
62
|
+
opacity?: number;
|
|
63
|
+
/** SVG stroke-dasharray cascaded to every stroked child of the annotation. */
|
|
64
|
+
strokeDasharray?: string;
|
|
40
65
|
[key: string]: unknown;
|
|
41
66
|
};
|
|
42
67
|
}
|
|
43
68
|
export default function SemioticAnnotation(props: AnnotationProps): import("react/jsx-runtime").JSX.Element;
|
|
69
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { ChartConfig, CopyFormat } from "./export/chartConfig";
|
|
3
|
+
import { type DescribeLevel } from "./ai/describeChart";
|
|
3
4
|
export interface ChartContainerProps {
|
|
4
5
|
/** Chart title */
|
|
5
6
|
title?: string;
|
|
@@ -26,8 +27,37 @@ export interface ChartContainerProps {
|
|
|
26
27
|
/** Enable "Data Summary" action button — shows statistical summary + sample rows */
|
|
27
28
|
dataSummary?: boolean;
|
|
28
29
|
};
|
|
29
|
-
/**
|
|
30
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Chart configuration. Enables the "Copy Config" toolbar action and the
|
|
32
|
+
* `describe`/`navigable` a11y affordances. Only `component` and `props` are
|
|
33
|
+
* required — the `version`/`createdAt` serialization metadata is optional
|
|
34
|
+
* here and synthesized when copying.
|
|
35
|
+
*/
|
|
36
|
+
chartConfig?: Omit<ChartConfig, "version" | "createdAt"> & Partial<Pick<ChartConfig, "version" | "createdAt">>;
|
|
37
|
+
/**
|
|
38
|
+
* Auto-generate a layered (L1–L3) natural-language description from
|
|
39
|
+
* `chartConfig` and expose it at the container level — the opt-in path to a
|
|
40
|
+
* fuller accessible reading than the bare chart's terse aria-label. Requires
|
|
41
|
+
* `chartConfig`. `true` renders a screen-reader-only note; pass
|
|
42
|
+
* `{ visible: true }` to also show it as a visible caption, or `{ levels }`
|
|
43
|
+
* to choose verbosity. Backed by `describeChart()`.
|
|
44
|
+
*/
|
|
45
|
+
describe?: boolean | {
|
|
46
|
+
levels?: DescribeLevel[];
|
|
47
|
+
visible?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Mount a structured, screen-reader-navigable tree of the chart (chart →
|
|
51
|
+
* axes/series → data points), built from `chartConfig` — the Olli /
|
|
52
|
+
* Data Navigator model, as an opt-in at the container layer. Requires
|
|
53
|
+
* `chartConfig`. `true` renders it screen-reader-only; `{ visible: true }`
|
|
54
|
+
* shows it; `{ maxLeaves }` caps leaves per branch. Backed by
|
|
55
|
+
* `buildNavigationTree()` + `AccessibleNavTree`.
|
|
56
|
+
*/
|
|
57
|
+
navigable?: boolean | {
|
|
58
|
+
visible?: boolean;
|
|
59
|
+
maxLeaves?: number;
|
|
60
|
+
};
|
|
31
61
|
/** Additional controls rendered in the toolbar after built-in actions */
|
|
32
62
|
controls?: React.ReactNode;
|
|
33
63
|
/** Loading state — shows skeleton placeholder */
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where an annotation came from and how confident we should be in it.
|
|
3
|
+
* Lives on `annotation.provenance`.
|
|
4
|
+
*/
|
|
5
|
+
export interface AnnotationProvenance {
|
|
6
|
+
/**
|
|
7
|
+
* Display name (or stable id) for who created the annotation — a
|
|
8
|
+
* person, agent, or watcher. Together with `authorKind` this expresses
|
|
9
|
+
* IDID §8's structured `author: { kind, id }`: `authorKind` is the
|
|
10
|
+
* actor category, `author` is the name/id.
|
|
11
|
+
*/
|
|
12
|
+
author?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Actor category — *who* created the annotation. IDID §8's
|
|
15
|
+
* `author.kind`. Distinct from `basis` (*how* it was derived) and from
|
|
16
|
+
* the coarser `source`. Open union; consumers may extend.
|
|
17
|
+
*/
|
|
18
|
+
authorKind?: AnnotationActorKind;
|
|
19
|
+
/**
|
|
20
|
+
* Origin category. Recognized values are not exhaustive; consumers
|
|
21
|
+
* may extend with their own source labels. Coarser than the
|
|
22
|
+
* `authorKind` / `basis` pair — kept for back-compat and as a single
|
|
23
|
+
* convenience label when the finer split isn't needed.
|
|
24
|
+
*/
|
|
25
|
+
source?: AnnotationSource;
|
|
26
|
+
/**
|
|
27
|
+
* Evidence type — *how* the annotation's claim was derived
|
|
28
|
+
* (a hand note, a statistical test, a rule, an LLM inference, an
|
|
29
|
+
* external source). IDID §8's `basis`. Distinct from `authorKind`
|
|
30
|
+
* (the actor) and `source` (the coarse origin): a `"human"` author can
|
|
31
|
+
* relay a `"statistical-test"` basis. Lets a reader weight a note by
|
|
32
|
+
* the strength of its evidence, not just who left it.
|
|
33
|
+
*/
|
|
34
|
+
basis?: AnnotationBasis;
|
|
35
|
+
/**
|
|
36
|
+
* Confidence in the assertion, 0–1. `1` is a hand-placed user
|
|
37
|
+
* annotation; LLM-suggested annotations typically land below 0.8.
|
|
38
|
+
*/
|
|
39
|
+
confidence?: number;
|
|
40
|
+
/** ISO 8601 timestamp marking when the annotation was created. */
|
|
41
|
+
createdAt?: string;
|
|
42
|
+
/**
|
|
43
|
+
* Identifier of the data snapshot the annotation was made against
|
|
44
|
+
* (IDID §8's `dataVersion`). Lets a consumer tell "this note was
|
|
45
|
+
* written about last week's data" from "this note still tracks the
|
|
46
|
+
* current data," independent of wall-clock freshness.
|
|
47
|
+
*/
|
|
48
|
+
dataVersion?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Stable, opaque identifier that survives data refresh and chart
|
|
51
|
+
* recreation. Used by the `"semantic"` anchor-resolution work to
|
|
52
|
+
* re-locate "the Q3 spike" after new data arrives, and as the target
|
|
53
|
+
* of another annotation's `lifecycle.supersedes`.
|
|
54
|
+
*/
|
|
55
|
+
stableId?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Actor category for an annotation — *who* created it. IDID §8 models
|
|
59
|
+
* this as `author.kind`. Open string union: `"system"` covers
|
|
60
|
+
* non-watcher automated placement, and consumers may pass any other
|
|
61
|
+
* label (it is preserved).
|
|
62
|
+
*/
|
|
63
|
+
export type AnnotationActorKind = "human" | "agent" | "watcher" | "system" | (string & {});
|
|
64
|
+
/**
|
|
65
|
+
* Evidence type for an annotation — *how* its claim was derived. IDID
|
|
66
|
+
* §8's `basis`. Open string union so consumers can add evidence kinds
|
|
67
|
+
* (e.g. `"forecast"`, `"manual-review"`) without a type change.
|
|
68
|
+
*/
|
|
69
|
+
export type AnnotationBasis = "human-note" | "statistical-test" | "rule" | "llm-inference" | "external-source" | "computed" | (string & {});
|
|
70
|
+
/**
|
|
71
|
+
* Recognized provenance sources. Open string union — consumers may
|
|
72
|
+
* pass any other label and it will be preserved.
|
|
73
|
+
*/
|
|
74
|
+
export type AnnotationSource = "user" | "ai" | "agent" | "import" | "computed" | "system" | (string & {});
|
|
75
|
+
/**
|
|
76
|
+
* How an annotation ages relative to the chart's current data extent.
|
|
77
|
+
* Default visual treatment (defined in M2): `aging` dims, `stale`
|
|
78
|
+
* draws a dashed border, `expired` is hidden unless
|
|
79
|
+
* `showExpiredAnnotations` is on.
|
|
80
|
+
*/
|
|
81
|
+
export type AnnotationFreshness = LifecycleBand;
|
|
82
|
+
import type { AnnotationAnchor } from "../realtime/types";
|
|
83
|
+
export type { AnnotationAnchor } from "../realtime/types";
|
|
84
|
+
import type { LifecycleBand, LifecycleBandThresholds } from "../realtime/lifecycleBands";
|
|
85
|
+
export { bandFromAge, DEFAULT_LIFECYCLE_THRESHOLDS } from "../realtime/lifecycleBands";
|
|
86
|
+
export type { LifecycleBand, LifecycleBandThresholds } from "../realtime/lifecycleBands";
|
|
87
|
+
/**
|
|
88
|
+
* Editorial standing of an annotation in a multiplayer conversation —
|
|
89
|
+
* is the note still believed? IDID §8's `status`. Orthogonal to the
|
|
90
|
+
* temporal `freshness` band: a note can be fresh-but-`disputed` or
|
|
91
|
+
* stale-but-`accepted`. Closed union — these four are the editorial
|
|
92
|
+
* state machine the editorial-lifecycle work drives:
|
|
93
|
+
*
|
|
94
|
+
* - `"proposed"` — placed but unreviewed (e.g. a watcher's auto-note).
|
|
95
|
+
* - `"accepted"` — confirmed by a human or agent.
|
|
96
|
+
* - `"disputed"` — contested; under review.
|
|
97
|
+
* - `"retracted"` — withdrawn; treat like an expired note.
|
|
98
|
+
*/
|
|
99
|
+
export type AnnotationStatus = "proposed" | "accepted" | "disputed" | "retracted";
|
|
100
|
+
/**
|
|
101
|
+
* Lifecycle state for an annotation. Lives on `annotation.lifecycle`.
|
|
102
|
+
*
|
|
103
|
+
* Two orthogonal axes: the **temporal** band (`freshness`, derived from
|
|
104
|
+
* `createdAt` + `ttlHint`) and the **editorial** state (`status`,
|
|
105
|
+
* driven by the multiplayer accept/dispute/retract flow). `supersedes`
|
|
106
|
+
* links a revision to the note it replaces.
|
|
107
|
+
*/
|
|
108
|
+
export interface AnnotationLifecycle {
|
|
109
|
+
/**
|
|
110
|
+
* Current freshness band. When omitted, `computeAnnotationFreshness`
|
|
111
|
+
* derives it from `ttlHint` and the data's current temporal extent.
|
|
112
|
+
*/
|
|
113
|
+
freshness?: AnnotationFreshness;
|
|
114
|
+
/**
|
|
115
|
+
* Editorial standing (IDID §8's `status`). Set by the multiplayer
|
|
116
|
+
* accept/dispute/retract flow; orthogonal to `freshness`. When
|
|
117
|
+
* omitted, the annotation is treated as unconditionally shown (the
|
|
118
|
+
* pre-editorial-lifecycle behavior). Status-driven visual treatment
|
|
119
|
+
* is owed alongside the editorial-lifecycle work — the field ships
|
|
120
|
+
* first so it can be stamped now.
|
|
121
|
+
*/
|
|
122
|
+
status?: AnnotationStatus;
|
|
123
|
+
/**
|
|
124
|
+
* `provenance.stableId` of the annotation this one replaces (IDID
|
|
125
|
+
* §8's `supersedes`). Forms a revision chain so a reader can trace how
|
|
126
|
+
* an interpretation changed; the superseded note is typically hidden
|
|
127
|
+
* once its replacement is `accepted`.
|
|
128
|
+
*/
|
|
129
|
+
supersedes?: string;
|
|
130
|
+
/**
|
|
131
|
+
* How long this annotation should be considered fresh. Either an
|
|
132
|
+
* ISO 8601 duration string (`"PT24H"`, `"P7D"`) or a number of
|
|
133
|
+
* milliseconds. The freshness computation walks `fresh → aging
|
|
134
|
+
* → stale → expired` as the chart's "now" advances past
|
|
135
|
+
* `createdAt + ttlHint`.
|
|
136
|
+
*/
|
|
137
|
+
ttlHint?: string | number;
|
|
138
|
+
/** Anchor resolution strategy. Defaults to `"fixed"` when omitted. */
|
|
139
|
+
anchor?: AnnotationAnchor;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Carries the new optional blocks onto whatever annotation type the
|
|
143
|
+
* chart accepts. Use as `Annotated<typeof myAnnotation>` for explicit
|
|
144
|
+
* typing, or call `withProvenance()` for inline authoring.
|
|
145
|
+
*/
|
|
146
|
+
export type Annotated<T> = T & {
|
|
147
|
+
provenance?: AnnotationProvenance;
|
|
148
|
+
lifecycle?: AnnotationLifecycle;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Convenience builder — attaches provenance + lifecycle blocks to an
|
|
152
|
+
* annotation without disturbing its existing fields. Returns a new
|
|
153
|
+
* object; does not mutate. Pure function, safe to call in SSR.
|
|
154
|
+
*
|
|
155
|
+
* ```ts
|
|
156
|
+
* withProvenance(
|
|
157
|
+
* { type: "y-threshold", value: 100, label: "SLA breach" },
|
|
158
|
+
* {
|
|
159
|
+
* provenance: { author: "alice", source: "user", createdAt: "2026-05-20T14:00:00Z" },
|
|
160
|
+
* lifecycle: { ttlHint: "P30D", anchor: "semantic" },
|
|
161
|
+
* }
|
|
162
|
+
* )
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
export declare function withProvenance<T extends object>(annotation: T, blocks: {
|
|
166
|
+
provenance?: AnnotationProvenance;
|
|
167
|
+
lifecycle?: AnnotationLifecycle;
|
|
168
|
+
}): Annotated<T>;
|
|
169
|
+
/**
|
|
170
|
+
* Returns an ISO 8601 wall-clock timestamp suitable for stamping
|
|
171
|
+
* `provenance.createdAt`. Sugar over `new Date().toISOString()`, but
|
|
172
|
+
* named to make intent obvious in streaming consumers: "mark this
|
|
173
|
+
* annotation as created now, so the lifecycle helpers can age it."
|
|
174
|
+
*
|
|
175
|
+
* Pair with `applyAnnotationLifecycle({ dataExtent })` on time-series
|
|
176
|
+
* charts to have annotations age against chart-time rather than
|
|
177
|
+
* wall-clock — the chart's latest data point becomes the "now"
|
|
178
|
+
* reference, and recently-stamped annotations stay fresh for as long
|
|
179
|
+
* as new data is flowing.
|
|
180
|
+
*/
|
|
181
|
+
export declare function currentTimestamp(): string;
|
|
182
|
+
/**
|
|
183
|
+
* Stamp an annotation with `provenance.createdAt = currentTimestamp()`
|
|
184
|
+
* (unless it already has a `createdAt`) and optional additional
|
|
185
|
+
* provenance fields. Intended for the streaming "I'm marking the
|
|
186
|
+
* latest data point" pattern, where the annotation's age should be
|
|
187
|
+
* measured from when the consumer added it.
|
|
188
|
+
*
|
|
189
|
+
* Equivalent to:
|
|
190
|
+
* ```ts
|
|
191
|
+
* withProvenance(ann, {
|
|
192
|
+
* provenance: { createdAt: currentTimestamp(), ...rest },
|
|
193
|
+
* lifecycle: ann.lifecycle,
|
|
194
|
+
* })
|
|
195
|
+
* ```
|
|
196
|
+
* — but reads cleaner at call sites and preserves any existing
|
|
197
|
+
* `createdAt`.
|
|
198
|
+
*/
|
|
199
|
+
export declare function withCurrentProvenance<T extends object>(annotation: T, rest?: Omit<AnnotationProvenance, "createdAt"> & {
|
|
200
|
+
createdAt?: string;
|
|
201
|
+
}): Annotated<T>;
|
|
202
|
+
/**
|
|
203
|
+
* Options accepted by `computeAnnotationFreshness` and
|
|
204
|
+
* `applyAnnotationLifecycle`.
|
|
205
|
+
*/
|
|
206
|
+
export interface ComputeAnnotationFreshnessOptions {
|
|
207
|
+
/**
|
|
208
|
+
* "Now" reference for age calculations. Number is epoch ms; string is
|
|
209
|
+
* any value `Date.parse` accepts. When omitted, defaults to the max
|
|
210
|
+
* of `dataExtent`, falling back to `Date.now()`.
|
|
211
|
+
*/
|
|
212
|
+
now?: number | Date | string;
|
|
213
|
+
/**
|
|
214
|
+
* The chart's current temporal extent — typically `[oldest, newest]`
|
|
215
|
+
* x values. Used to derive a sensible "now" for streaming charts
|
|
216
|
+
* (where wall-clock time and the data's notion of "now" can drift).
|
|
217
|
+
*/
|
|
218
|
+
dataExtent?: ReadonlyArray<number | Date | string> | {
|
|
219
|
+
min: number | Date | string;
|
|
220
|
+
max: number | Date | string;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Override the default age thresholds. Each value is a multiplier of
|
|
224
|
+
* `ttlHint`. Defaults: aging at 1×, stale at 1.5×, expired at 3×.
|
|
225
|
+
* Same shape as `LifecycleBandThresholds` from the shared primitive.
|
|
226
|
+
*/
|
|
227
|
+
thresholds?: LifecycleBandThresholds;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Classify an annotation into a freshness band. Exported for tests and
|
|
231
|
+
* for consumers that want the per-annotation band without rebuilding
|
|
232
|
+
* the entire array.
|
|
233
|
+
*
|
|
234
|
+
* Returns the annotation's existing `lifecycle.freshness` verbatim if
|
|
235
|
+
* the annotation lacks the `createdAt` or `ttlHint` needed to compute
|
|
236
|
+
* a band — i.e. an explicit assignment always wins over inference.
|
|
237
|
+
*/
|
|
238
|
+
export declare function annotationFreshnessFor<T>(annotation: Annotated<T>, nowMs: number, thresholds?: LifecycleBandThresholds): AnnotationFreshness;
|
|
239
|
+
/**
|
|
240
|
+
* Walk an annotations array and populate `lifecycle.freshness` on each
|
|
241
|
+
* entry from its `provenance.createdAt` and `lifecycle.ttlHint`.
|
|
242
|
+
*
|
|
243
|
+
* Pure function — returns a new array; does not mutate input. Safe
|
|
244
|
+
* to call in SSR. Annotations missing the inputs needed to compute a
|
|
245
|
+
* band keep whatever `lifecycle.freshness` they already had (so an
|
|
246
|
+
* explicit assignment always wins).
|
|
247
|
+
*
|
|
248
|
+
* For non-temporal charts, pass `now` explicitly. For streaming /
|
|
249
|
+
* time-series charts, pass `dataExtent` — the helper picks the latest
|
|
250
|
+
* value as "now" so freshness tracks chart-time, not wall-clock.
|
|
251
|
+
*/
|
|
252
|
+
export declare function computeAnnotationFreshness<T>(annotations: ReadonlyArray<Annotated<T>>, options?: ComputeAnnotationFreshnessOptions): Annotated<T>[];
|
|
253
|
+
/**
|
|
254
|
+
* Style overrides per freshness band. Each map is partial — bands not
|
|
255
|
+
* present fall back to the defaults below. `null` for a value removes
|
|
256
|
+
* the default rather than applying it (e.g. `{ opacity: { aging: null } }`
|
|
257
|
+
* disables dimming aging annotations).
|
|
258
|
+
*/
|
|
259
|
+
export interface AnnotationLifecycleTreatment {
|
|
260
|
+
opacity?: Partial<Record<AnnotationFreshness, number | null>>;
|
|
261
|
+
strokeDasharray?: Partial<Record<AnnotationFreshness, string | null>>;
|
|
262
|
+
/** Suffix appended to `label` for that band. Default suffixes are off. */
|
|
263
|
+
labelSuffix?: Partial<Record<AnnotationFreshness, string>>;
|
|
264
|
+
/**
|
|
265
|
+
* When true, expired annotations stay in the returned array (with
|
|
266
|
+
* the expired treatment applied). When false (default), expired
|
|
267
|
+
* annotations are filtered out — matching the "hidden by default"
|
|
268
|
+
* contract from the talk-readiness roadmap.
|
|
269
|
+
*/
|
|
270
|
+
showExpiredAnnotations?: boolean;
|
|
271
|
+
}
|
|
272
|
+
export type ApplyAnnotationLifecycleOptions = ComputeAnnotationFreshnessOptions & AnnotationLifecycleTreatment;
|
|
273
|
+
/**
|
|
274
|
+
* Compute freshness and apply the default visual treatment in one pass.
|
|
275
|
+
*
|
|
276
|
+
* Behavior per band (overridable via options):
|
|
277
|
+
* - **fresh** — no change
|
|
278
|
+
* - **aging** — `opacity` 0.55
|
|
279
|
+
* - **stale** — `opacity` 0.35, `strokeDasharray` `"4 4"` (cascades
|
|
280
|
+
* through the annotation's stroked children)
|
|
281
|
+
* - **expired** — filtered out by default; pass
|
|
282
|
+
* `showExpiredAnnotations: true` to keep them with `opacity` 0.2 and
|
|
283
|
+
* `strokeDasharray` `"2 4"`
|
|
284
|
+
*
|
|
285
|
+
* Treatment composes cleanly with annotations that already carry their
|
|
286
|
+
* own `color` / `opacity` — explicit fields on the annotation win,
|
|
287
|
+
* the treatment only fills in what isn't already set.
|
|
288
|
+
*/
|
|
289
|
+
export declare function applyAnnotationLifecycle<T>(annotations: ReadonlyArray<Annotated<T>>, options?: ApplyAnnotationLifecycleOptions): Annotated<T>[];
|
|
290
|
+
/**
|
|
291
|
+
* Style overrides per editorial status. Each map is partial — statuses not
|
|
292
|
+
* present fall back to the defaults below. `null` for a value removes the
|
|
293
|
+
* default rather than applying it.
|
|
294
|
+
*/
|
|
295
|
+
export interface AnnotationStatusVisibility {
|
|
296
|
+
/**
|
|
297
|
+
* Keep `retracted` annotations instead of filtering them out. Default false
|
|
298
|
+
* — retracted is hidden like `expired`.
|
|
299
|
+
*/
|
|
300
|
+
showRetractedAnnotations?: boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Keep an annotation that another *present* note supersedes. Default false
|
|
303
|
+
* — a superseded note is hidden once its replacement is in the array.
|
|
304
|
+
*/
|
|
305
|
+
showSupersededAnnotations?: boolean;
|
|
306
|
+
}
|
|
307
|
+
export interface AnnotationStatusTreatment extends AnnotationStatusVisibility {
|
|
308
|
+
/**
|
|
309
|
+
* Opacity *factor* per status, multiplied into any existing opacity so it
|
|
310
|
+
* composes with the freshness treatment (run `applyAnnotationLifecycle`
|
|
311
|
+
* first, then this). `null` disables the factor for that status.
|
|
312
|
+
*/
|
|
313
|
+
opacity?: Partial<Record<AnnotationStatus, number | null>>;
|
|
314
|
+
strokeDasharray?: Partial<Record<AnnotationStatus, string | null>>;
|
|
315
|
+
/**
|
|
316
|
+
* Suffix appended to a string `label` for that status — the `disputed`
|
|
317
|
+
* default `" (?)"` is the query affordance the strategy calls for.
|
|
318
|
+
*/
|
|
319
|
+
labelSuffix?: Partial<Record<AnnotationStatus, string>>;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Apply the default editorial visibility contract without changing annotation
|
|
323
|
+
* styling. Retracted notes and notes replaced by a present revision are hidden
|
|
324
|
+
* unless explicitly requested. Shared by visual treatment, chart descriptions,
|
|
325
|
+
* and navigation trees so they expose the same current set.
|
|
326
|
+
*/
|
|
327
|
+
export declare function filterAnnotationsByStatus<T>(annotations: ReadonlyArray<Annotated<T>>, options?: AnnotationStatusVisibility): Annotated<T>[];
|
|
328
|
+
/**
|
|
329
|
+
* Apply the editorial-status visual treatment (M7) — the orthogonal companion
|
|
330
|
+
* to {@link applyAnnotationLifecycle}'s temporal-freshness treatment. The two
|
|
331
|
+
* compose (a note can be stale-and-disputed); run freshness first, then this.
|
|
332
|
+
*
|
|
333
|
+
* Per status (overridable via options):
|
|
334
|
+
* - **accepted** — no change (full weight).
|
|
335
|
+
* - **proposed** — `opacity` ×0.7, dashed `"3 3"`, `label` suffix `" (proposed)"`.
|
|
336
|
+
* An unreviewed (e.g. watcher) note reads provisionally.
|
|
337
|
+
* - **disputed** — `opacity` ×0.7, dashed `"2 3"`, `label` suffix `" (?)"`.
|
|
338
|
+
* The suffix is the query affordance: a contested note announces itself.
|
|
339
|
+
* - **retracted** — filtered out by default (like `expired`); pass
|
|
340
|
+
* `showRetractedAnnotations: true` to keep it at `opacity` ×0.25.
|
|
341
|
+
*
|
|
342
|
+
* Also resolves **supersession**: a note whose `provenance.stableId` is the
|
|
343
|
+
* `lifecycle.supersedes` target of another *present, non-retracted* note is
|
|
344
|
+
* hidden (the revision replaced it), unless `showSupersededAnnotations` is set.
|
|
345
|
+
*
|
|
346
|
+
* Pure — returns a new array; safe in SSR. Opacity is multiplied into any
|
|
347
|
+
* existing value, so it composes with freshness dimming and author-set opacity.
|
|
348
|
+
*/
|
|
349
|
+
export declare function applyAnnotationStatus<T>(annotations: ReadonlyArray<Annotated<T>>, options?: AnnotationStatusTreatment): Annotated<T>[];
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { ChartRubric } from "./chartCapabilityTypes";
|
|
2
|
+
import type { AccessibilityAuditResult } from "../charts/shared/auditAccessibility";
|
|
3
|
+
/**
|
|
4
|
+
* The channel an audience receives a chart through. Orthogonal to familiarity:
|
|
5
|
+
* a reader can be highly familiar with a chart type yet unable to *receive* it
|
|
6
|
+
* in their channel (an 8-slice pie is familiar but illegible to a screen
|
|
7
|
+
* reader). Defaults to `"visual"` when unset — no receivability bias applied.
|
|
8
|
+
*
|
|
9
|
+
* • `visual` — sighted reader; the historical default, no bias.
|
|
10
|
+
* • `screen-reader` — non-visual; meaning must survive the data table / nav tree.
|
|
11
|
+
* • `sonified` — audio; density and ordering matter more than color.
|
|
12
|
+
* • `agent` — an LLM reading via the grounding payload; same non-visual
|
|
13
|
+
* "is the meaning recoverable without pixels?" question.
|
|
14
|
+
*/
|
|
15
|
+
export type ReceptionModality = "visual" | "screen-reader" | "sonified" | "agent";
|
|
16
|
+
/**
|
|
17
|
+
* A serializable description of who's reading the charts and what the
|
|
18
|
+
* organization is trying to grow.
|
|
19
|
+
*
|
|
20
|
+
* Semiotic does not measure familiarity — it consumes measurements. Orgs
|
|
21
|
+
* produce an AudienceProfile through whatever channel makes sense (surveys,
|
|
22
|
+
* telemetry, manager judgment, training records) and pass it to the
|
|
23
|
+
* suggestion APIs. The library applies the bias and returns rankings that
|
|
24
|
+
* reflect the audience instead of a generic data-literate baseline.
|
|
25
|
+
*/
|
|
26
|
+
export interface AudienceProfile {
|
|
27
|
+
/**
|
|
28
|
+
* Display name. Surfaced in suggestion `reasons[]` when a target fires so
|
|
29
|
+
* users can see whose policy is influencing the ranking.
|
|
30
|
+
*/
|
|
31
|
+
name?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Per-chart familiarity override (1..5). Replaces the descriptor's
|
|
34
|
+
* `rubric.familiarity`. Charts not listed fall back to the descriptor.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* familiarity: { BarChart: 5, LineChart: 5, PieChart: 4, BoxPlot: 2 }
|
|
38
|
+
*/
|
|
39
|
+
familiarity?: Partial<Record<string, number>>;
|
|
40
|
+
/**
|
|
41
|
+
* Adoption targets — which charts the org is trying to grow or reduce.
|
|
42
|
+
* The engine applies a meaningful score bias (±1..3 depending on weight)
|
|
43
|
+
* so growth targets win close calls and decrease targets fall back unless
|
|
44
|
+
* they're the only fit.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* targets: {
|
|
48
|
+
* PieChart: { direction: "decrease", weight: 1 },
|
|
49
|
+
* BoxPlot: { direction: "increase", weight: 2,
|
|
50
|
+
* reason: "we want the team reading distributions, not means" }
|
|
51
|
+
* }
|
|
52
|
+
*/
|
|
53
|
+
targets?: Partial<Record<string, AudienceTarget>>;
|
|
54
|
+
/**
|
|
55
|
+
* Controls visibility of stretch picks (unfamiliar-but-relevant charts).
|
|
56
|
+
* 0 — never surface stretches; familiar-only rankings
|
|
57
|
+
* 1 — surface in a separate `stretchSuggestions` list (default when audience set)
|
|
58
|
+
* 2 — same as 1 but lowers the familiarity threshold (≤4) for what counts as stretch,
|
|
59
|
+
* widening the menu
|
|
60
|
+
*/
|
|
61
|
+
exposureLevel?: 0 | 1 | 2;
|
|
62
|
+
/**
|
|
63
|
+
* The channel this audience receives charts through. When set to a non-visual
|
|
64
|
+
* modality, `suggestCharts` runs the accessibility audit on each candidate and
|
|
65
|
+
* `applyAudienceBias` down-ranks charts whose meaning doesn't survive that
|
|
66
|
+
* channel (and surfaces the receivability findings as caveats). Unset /
|
|
67
|
+
* `"visual"` keeps the historical behavior — familiarity and targets only.
|
|
68
|
+
* See {@link receivabilityBias}.
|
|
69
|
+
*/
|
|
70
|
+
receptionModality?: ReceptionModality;
|
|
71
|
+
}
|
|
72
|
+
export interface AudienceTarget {
|
|
73
|
+
direction: "increase" | "decrease";
|
|
74
|
+
/** 1..3 — controls bias magnitude. Default 1. */
|
|
75
|
+
weight?: number;
|
|
76
|
+
/** Human-readable rationale. Surfaces in suggestion.reasons when the target fires. */
|
|
77
|
+
reason?: string;
|
|
78
|
+
}
|
|
79
|
+
export interface AudienceBiasResult {
|
|
80
|
+
/** Composite score after audience adjustments. Unclamped — can range outside 0..5. */
|
|
81
|
+
score: number;
|
|
82
|
+
/** Effective rubric for the chart after audience overrides. */
|
|
83
|
+
rubric: ChartRubric;
|
|
84
|
+
/** Reason string to append to the suggestion when a target fired. */
|
|
85
|
+
appliedReason?: string;
|
|
86
|
+
/** Reason string to append when a receivability penalty fired (non-visual modality). */
|
|
87
|
+
receivabilityReason?: string;
|
|
88
|
+
}
|
|
89
|
+
export interface ReceivabilitySignal {
|
|
90
|
+
/** Score delta (≤ 0) — the receivability penalty for this channel. */
|
|
91
|
+
delta: number;
|
|
92
|
+
/** One-line reason, present only when a penalty applied. */
|
|
93
|
+
reason?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Caveat messages for the findings that drove the penalty — the receivability
|
|
96
|
+
* slice of the audit, ready to merge into a suggestion's `caveats[]` alongside
|
|
97
|
+
* the perceptual ones (so both channels read from the same array).
|
|
98
|
+
*/
|
|
99
|
+
caveats: string[];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Translate an accessibility audit into a receivability penalty for a non-visual
|
|
103
|
+
* channel. Pure. `fail` findings on receivability-critical heuristics weigh most;
|
|
104
|
+
* `warn` findings weigh less; `manual`/`pass`/`not-applicable` never penalize
|
|
105
|
+
* (we don't punish what we can't prove). Penalty is clamped to a −3 floor so it
|
|
106
|
+
* reorders rankings without overriding data-shape correctness.
|
|
107
|
+
*
|
|
108
|
+
* ```ts
|
|
109
|
+
* const audit = auditAccessibility("PieChart", props)
|
|
110
|
+
* const { delta, reason } = receivabilityBias(audit, "screen-reader")
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
export declare function receivabilityBias(audit: AccessibilityAuditResult, modality: ReceptionModality): ReceivabilitySignal;
|
|
114
|
+
/**
|
|
115
|
+
* Apply an AudienceProfile's bias to a chart's composite score and rubric.
|
|
116
|
+
* Pure function — used by both `suggestCharts` and `suggestStretchCharts`.
|
|
117
|
+
*
|
|
118
|
+
* Two terms compose additively:
|
|
119
|
+
* • Familiarity bias: (audienceFamiliarity − 3) × 0.5
|
|
120
|
+
* — Range ±1.0. At familiarity 5 we add 1.0; at 1 we subtract 1.0.
|
|
121
|
+
* • Target bias: ±1.0 × weight
|
|
122
|
+
* — Range ±3.0 for weight=3. Strong enough to reorder rankings,
|
|
123
|
+
* not so strong that it overrides chart correctness for the data shape.
|
|
124
|
+
*
|
|
125
|
+
* Score is left unclamped so internal sorting reflects the magnitude of bias.
|
|
126
|
+
*
|
|
127
|
+
* A third term — *receivability* — composes in when the audience declares a
|
|
128
|
+
* non-visual `receptionModality` and the caller passes a precomputed
|
|
129
|
+
* {@link ReceivabilitySignal} (from {@link receivabilityBias}). Familiarity and
|
|
130
|
+
* receivability are different axes: a chart can be familiar yet unreceivable in
|
|
131
|
+
* the target channel, and this folds that signal into the same score the
|
|
132
|
+
* recommender ranks by. The caller computes the signal once and reuses it for
|
|
133
|
+
* the suggestion's caveats too, so the audit is scanned a single time per
|
|
134
|
+
* candidate.
|
|
135
|
+
*/
|
|
136
|
+
export declare function applyAudienceBias(baseScore: number, baseRubric: ChartRubric, component: string, audience: AudienceProfile | undefined, receivability?: ReceivabilitySignal): AudienceBiasResult;
|
|
137
|
+
/**
|
|
138
|
+
* Resolve the effective familiarity for a chart under an audience. Used by
|
|
139
|
+
* the stretch surface to decide whether a chart qualifies as "unfamiliar."
|
|
140
|
+
*/
|
|
141
|
+
export declare function effectiveFamiliarity(component: string, defaultFamiliarity: number, audience: AudienceProfile | undefined): number;
|
|
142
|
+
/**
|
|
143
|
+
* Familiarity threshold for what counts as a "stretch" pick under this audience.
|
|
144
|
+
* Tighter for exposureLevel 1, wider for 2. Returns the highest familiarity a
|
|
145
|
+
* chart can have and still appear in the stretch surface.
|
|
146
|
+
*/
|
|
147
|
+
export declare function stretchFamiliarityCeiling(audience: AudienceProfile | undefined): number;
|