semiotic 3.8.4 → 3.8.6
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 +9 -5
- package/README.md +52 -46
- package/ai/behaviorContracts.cjs +2 -2
- package/ai/componentMetadata.cjs +2 -2
- package/ai/dist/mcp-server.js +6 -2
- package/ai/examples.md +211 -2
- package/ai/schema.json +1388 -14
- package/ai/surface-manifest.json +8 -4
- package/ai/system-prompt.md +1 -1
- package/dist/chunk-chartContainerDataAudit-FEOD5GTQ.module.min.js +2 -0
- package/dist/chunk-chunk-2CHN2TA3.module.min.js +1 -0
- package/dist/chunk-chunk-2JGJ5GUG.module.min.js +1 -0
- package/dist/chunk-chunk-3NGIKFD6.module.min.js +1 -0
- package/dist/chunk-chunk-3SHB24AG.module.min.js +1 -0
- package/dist/chunk-chunk-4MMOOYTX.module.min.js +2 -0
- package/dist/chunk-chunk-75OTQSXS.module.min.js +1 -0
- package/dist/chunk-chunk-A5GRQUOF.module.min.js +1 -0
- package/dist/chunk-chunk-AAF5LZAU.module.min.js +2 -0
- package/dist/{chunk-chunk-LQBSXO7K.module.min.js → chunk-chunk-ARZGA4LJ.module.min.js} +1 -1
- package/dist/chunk-chunk-CAFLML4L.module.min.js +2 -0
- package/dist/chunk-chunk-CO5KQMGH.module.min.js +1 -0
- package/dist/chunk-chunk-FHBN7OEB.module.min.js +2 -0
- package/dist/{chunk-chunk-KQ546MKE.module.min.js → chunk-chunk-GFTVACTO.module.min.js} +1 -1
- package/dist/chunk-chunk-IP2UE74X.module.min.js +1 -0
- package/dist/chunk-chunk-ITDWLZXV.module.min.js +2 -0
- package/dist/chunk-chunk-LPSPATPC.module.min.js +1 -0
- package/dist/chunk-chunk-OM6NWS4H.module.min.js +2 -0
- package/dist/chunk-chunk-PX5YQGDP.module.min.js +2 -0
- package/dist/chunk-chunk-Q2BS46W2.module.min.js +2 -0
- package/dist/{chunk-chunk-FBGHXL72.module.min.js → chunk-chunk-RA7JCG7D.module.min.js} +1 -1
- package/dist/chunk-chunk-RNUHEXZA.module.min.js +2 -0
- package/dist/chunk-chunk-ROZWKEUG.module.min.js +1 -0
- package/dist/chunk-chunk-SMVD3EQJ.module.min.js +2 -0
- package/dist/chunk-chunk-T2FKJD4O.module.min.js +2 -0
- package/dist/chunk-chunk-UDREYOLV.module.min.js +1 -0
- package/dist/chunk-chunk-VOWE3SAP.module.min.js +2 -0
- package/dist/chunk-chunk-VQPNBUSW.module.min.js +2 -0
- package/dist/{chunk-chunk-7RYBCTK5.module.min.js → chunk-chunk-WAWCIHFJ.module.min.js} +1 -1
- package/dist/{chunk-chunk-F7WFPD4O.module.min.js → chunk-chunk-WYARAXHR.module.min.js} +1 -1
- package/dist/{chunk-chunk-JDXT6ORT.module.min.js → chunk-chunk-XP3OHHFX.module.min.js} +1 -1
- package/dist/chunk-chunk-XV3KGYTR.module.min.js +2 -0
- package/dist/chunk-chunk-YC2IVEPX.module.min.js +1 -0
- package/dist/chunk-chunk-ZXIXAPRE.module.min.js +2 -0
- package/dist/components/ChartContainer.d.ts +10 -0
- package/dist/components/ai/chartCapabilities.d.ts +3 -1
- package/dist/components/ai/chartCapabilityTypes.d.ts +14 -0
- package/dist/components/chartContainerDataAudit.d.ts +10 -0
- package/dist/components/charts/custom/XYCustomChart.d.ts +3 -0
- package/dist/components/charts/geo/DistanceCartogram.d.ts +30 -4
- package/dist/components/charts/index.d.ts +4 -0
- package/dist/components/charts/network/ForceDirectedGraph.d.ts +36 -1
- package/dist/components/charts/ordinal/BarChart.d.ts +7 -14
- package/dist/components/charts/ordinal/GaugeChart.d.ts +3 -0
- package/dist/components/charts/ordinal/GroupedBarChart.d.ts +3 -0
- package/dist/components/charts/ordinal/StackedBarChart.d.ts +3 -0
- package/dist/components/charts/ordinal/SwimlaneChart.d.ts +4 -14
- package/dist/components/charts/physics/CrucibleChart.capability.d.ts +8 -0
- package/dist/components/charts/physics/CrucibleChart.d.ts +63 -0
- package/dist/components/charts/physics/crucibleBodyRenderers.d.ts +27 -0
- package/dist/components/charts/physics/crucibleChartProps.d.ts +90 -0
- package/dist/components/charts/physics/crucibleChrome.d.ts +47 -0
- package/dist/components/charts/physics/crucibleController.d.ts +59 -0
- package/dist/components/charts/physics/crucibleEffects.d.ts +30 -0
- package/dist/components/charts/physics/cruciblePhysics.d.ts +54 -0
- package/dist/components/charts/physics/crucibleProgram.d.ts +38 -0
- package/dist/components/charts/physics/crucibleTypes.d.ts +415 -0
- package/dist/components/charts/shared/chartSpecCore.d.ts +10 -4
- package/dist/components/charts/shared/crucibleWireSchema.d.ts +5 -0
- package/dist/components/charts/shared/diagnoseTypes.d.ts +10 -0
- package/dist/components/charts/shared/gaugeGradient.d.ts +4 -8
- package/dist/components/charts/shared/gradient.d.ts +35 -0
- package/dist/components/charts/shared/hatchFill.d.ts +3 -10
- package/dist/components/charts/shared/hooks.d.ts +2 -50
- package/dist/components/charts/shared/knownChartComponents.d.ts +1 -1
- package/dist/components/charts/shared/streamPropsHelpers.d.ts +1 -2
- package/dist/components/charts/shared/useChartLegend.d.ts +58 -0
- package/dist/components/charts/shared/useChartSetup.d.ts +5 -0
- package/dist/components/charts/shared/useCustomChartSetup.d.ts +6 -1
- package/dist/components/charts/shared/useNetworkChartSetup.d.ts +1 -0
- package/dist/components/charts/shared/useStreamingLegend.d.ts +1 -1
- package/dist/components/charts/xy/AreaChart.d.ts +25 -42
- package/dist/components/charts/xy/BumpChart.capability.d.ts +11 -0
- package/dist/components/charts/xy/BumpChart.d.ts +161 -0
- package/dist/components/charts/xy/DifferenceChart.d.ts +3 -10
- package/dist/components/charts/xy/Heatmap.d.ts +3 -0
- package/dist/components/charts/xy/LineChart.d.ts +6 -8
- package/dist/components/data/auditData.d.ts +51 -0
- package/dist/components/data/dataAuditPresentation.d.ts +18 -0
- package/dist/components/data/dataAuditSources.d.ts +9 -0
- package/dist/components/data/numericContracts.d.ts +59 -0
- package/dist/components/data/numericFieldProfiler.d.ts +23 -0
- package/dist/components/geometry/bumpRibbonGeometry.d.ts +36 -0
- package/dist/components/legendLayout.d.ts +19 -1
- package/dist/components/recipes/netEnsembleLayout.d.ts +167 -0
- package/dist/components/recipes/netEnsembleOverlays.d.ts +20 -0
- package/dist/components/recipes/wordTrails.d.ts +156 -0
- package/dist/components/recipes/wordTrailsProgressiveReveal.d.ts +42 -0
- package/dist/components/semiotic-ai-core.d.ts +3 -0
- package/dist/components/semiotic-ai-data-audit.d.ts +4 -0
- package/dist/components/semiotic-ai.d.ts +9 -6
- package/dist/components/semiotic-geo.d.ts +1 -0
- package/dist/components/semiotic-network.d.ts +1 -0
- package/dist/components/semiotic-ordinal.d.ts +2 -0
- package/dist/components/semiotic-physics.d.ts +2 -0
- package/dist/components/semiotic-realtime-core.d.ts +1 -0
- package/dist/components/semiotic-recipes-core.d.ts +4 -0
- package/dist/components/semiotic-server-edge.d.ts +1 -1
- package/dist/components/semiotic-server.d.ts +1 -1
- package/dist/components/semiotic-utils-core.d.ts +3 -0
- package/dist/components/semiotic-xy.d.ts +4 -0
- package/dist/components/semiotic.d.ts +5 -5
- package/dist/components/server/renderEvidence.d.ts +27 -0
- package/dist/components/server/serverChartConfigs.d.ts +2 -0
- package/dist/components/server/serverChartConfigsPhysics.d.ts +9 -0
- package/dist/components/server/serverChartConfigsXY.d.ts +1 -0
- package/dist/components/server/staticAnnotations.d.ts +12 -0
- package/dist/components/server/staticLegend.d.ts +4 -2
- package/dist/components/server/staticSVGChrome.d.ts +4 -4
- package/dist/components/stream/GeoPipelineStore.d.ts +1 -0
- package/dist/components/stream/GeoSVGOverlay.d.ts +11 -10
- package/dist/components/stream/NetworkSVGOverlay.d.ts +2 -6
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +2 -6
- package/dist/components/stream/SVGOverlay.d.ts +2 -6
- package/dist/components/stream/StalenessBadge.d.ts +2 -6
- package/dist/components/stream/geoCartogram.d.ts +7 -0
- package/dist/components/stream/geoTypes.d.ts +20 -8
- package/dist/components/stream/legendRenderer.d.ts +2 -6
- package/dist/components/stream/networkFrameHandleTypes.d.ts +4 -0
- package/dist/components/stream/ordinalTypes.d.ts +7 -31
- package/dist/components/stream/physics/PhysicsKernel.d.ts +1 -0
- package/dist/components/stream/physics/PhysicsSVGOverlay.d.ts +2 -6
- package/dist/components/stream/physics/PhysicsSettledSVG.d.ts +8 -0
- package/dist/components/stream/physics/StreamPhysicsTypes.d.ts +2 -6
- package/dist/components/stream/pipelineConfig.d.ts +7 -15
- package/dist/components/stream/renderers/canvasRenderHelpers.d.ts +9 -69
- package/dist/components/stream/renderers/cornerRadii.d.ts +2 -9
- package/dist/components/stream/renderers/thresholdLineSegments.d.ts +12 -0
- package/dist/components/stream/sceneToSVGShared.d.ts +3 -5
- package/dist/components/stream/types.d.ts +32 -56
- package/dist/components/stream/xySceneBuilders/areaGradient.d.ts +4 -20
- package/dist/components/stream/xySceneBuilders/types.d.ts +6 -6
- package/dist/components/types/legendTypes.d.ts +15 -6
- package/dist/components/useChartContainerDataAudit.d.ts +7 -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/physics.min.js +1 -1
- package/dist/physics.module.min.js +1 -1
- package/dist/physicsWorker.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai-core.d.ts +3 -0
- package/dist/semiotic-ai-core.min.js +1 -1
- package/dist/semiotic-ai-core.module.min.js +1 -1
- package/dist/semiotic-ai.d.ts +9 -6
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-experimental.min.js +1 -1
- package/dist/semiotic-experimental.module.min.js +1 -1
- package/dist/semiotic-geo.d.ts +1 -0
- package/dist/semiotic-network.d.ts +1 -0
- package/dist/semiotic-ordinal.d.ts +2 -0
- package/dist/semiotic-physics.d.ts +2 -0
- package/dist/semiotic-realtime-core.d.ts +1 -0
- package/dist/semiotic-realtime-core.min.js +1 -1
- package/dist/semiotic-realtime-core.module.min.js +1 -1
- package/dist/semiotic-recipes-core.d.ts +4 -0
- package/dist/semiotic-recipes-core.min.js +1 -1
- package/dist/semiotic-recipes-core.module.min.js +1 -1
- package/dist/semiotic-recipes.min.js +1 -1
- package/dist/semiotic-recipes.module.min.js +1 -1
- package/dist/semiotic-server-edge.d.ts +1 -1
- package/dist/semiotic-server-edge.min.js +1 -1
- package/dist/semiotic-server-edge.module.min.js +1 -1
- package/dist/semiotic-server-node.min.js +1 -1
- package/dist/semiotic-server-node.module.min.js +1 -1
- package/dist/semiotic-server.d.ts +1 -1
- package/dist/semiotic-utils-core.d.ts +3 -0
- package/dist/semiotic-utils-core.min.js +1 -1
- package/dist/semiotic-utils-core.module.min.js +1 -1
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- package/dist/semiotic-xy.d.ts +4 -0
- package/dist/semiotic.d.ts +5 -5
- 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 +2 -2
- package/dist/chunk-chunk-3ILKBVVQ.module.min.js +0 -1
- package/dist/chunk-chunk-6TPGFL7M.module.min.js +0 -2
- package/dist/chunk-chunk-7KZJUTKP.module.min.js +0 -2
- package/dist/chunk-chunk-ANYDWOZF.module.min.js +0 -1
- package/dist/chunk-chunk-AQPQN2HH.module.min.js +0 -2
- package/dist/chunk-chunk-ASKSE5F5.module.min.js +0 -1
- package/dist/chunk-chunk-AVBI6GDT.module.min.js +0 -1
- package/dist/chunk-chunk-B3DRZPBK.module.min.js +0 -2
- package/dist/chunk-chunk-BFHUYEOS.module.min.js +0 -2
- package/dist/chunk-chunk-C57LR3YG.module.min.js +0 -1
- package/dist/chunk-chunk-F5V4UIE6.module.min.js +0 -2
- package/dist/chunk-chunk-FP44FHFO.module.min.js +0 -2
- package/dist/chunk-chunk-HKXUAEPJ.module.min.js +0 -2
- package/dist/chunk-chunk-ICEXPNDC.module.min.js +0 -2
- package/dist/chunk-chunk-JMVEIZXP.module.min.js +0 -1
- package/dist/chunk-chunk-KHCOJMGK.module.min.js +0 -1
- package/dist/chunk-chunk-LRIFN2HK.module.min.js +0 -1
- package/dist/chunk-chunk-MFHF4J2Z.module.min.js +0 -1
- package/dist/chunk-chunk-N6VKKF3A.module.min.js +0 -2
- package/dist/chunk-chunk-NEVE562N.module.min.js +0 -1
- package/dist/chunk-chunk-NKZ75IM5.module.min.js +0 -2
- package/dist/chunk-chunk-PLIDPQNG.module.min.js +0 -2
- package/dist/chunk-chunk-QGZGZI4X.module.min.js +0 -1
- package/dist/chunk-chunk-RP7WTID5.module.min.js +0 -1
- package/dist/chunk-chunk-S7KLNUO6.module.min.js +0 -1
- package/dist/chunk-chunk-SR4ZXOWR.module.min.js +0 -2
- package/dist/chunk-statisticalOverlays-QGDLRUHX.module.min.js +0 -1
- package/dist/chunk-statisticalOverlays-T77OKLDY.module.min.js +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
2
|
+
import type { Diagnosis } from "../charts/shared/diagnoseTypes";
|
|
3
|
+
import { type NumericContracts, type NumericFieldRole, type NumericRequirement } from "./numericContracts";
|
|
4
|
+
export interface DataAuditDiagnosis extends Diagnosis {
|
|
5
|
+
readonly domain: "data";
|
|
6
|
+
readonly field?: string;
|
|
7
|
+
readonly role?: NumericFieldRole;
|
|
8
|
+
/** Bounded, zero-based row indices; `count` carries the full total. */
|
|
9
|
+
readonly rows?: ReadonlyArray<number>;
|
|
10
|
+
readonly count?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CheckedNumericContract {
|
|
13
|
+
readonly role: NumericFieldRole;
|
|
14
|
+
readonly accessor: string;
|
|
15
|
+
readonly dataProp: string;
|
|
16
|
+
readonly requirements: ReadonlyArray<NumericRequirement>;
|
|
17
|
+
readonly allowMissing: boolean;
|
|
18
|
+
readonly missingValue?: number;
|
|
19
|
+
readonly domain: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface DataAuditResult {
|
|
22
|
+
readonly component: string;
|
|
23
|
+
readonly ok: boolean;
|
|
24
|
+
readonly rowCount: number;
|
|
25
|
+
readonly summary: {
|
|
26
|
+
readonly fieldsChecked: number;
|
|
27
|
+
readonly errors: number;
|
|
28
|
+
readonly warnings: number;
|
|
29
|
+
};
|
|
30
|
+
readonly contracts: ReadonlyArray<CheckedNumericContract>;
|
|
31
|
+
readonly diagnoses: ReadonlyArray<DataAuditDiagnosis>;
|
|
32
|
+
}
|
|
33
|
+
export interface AuditDataOptions {
|
|
34
|
+
/** Override the registered/built-in contract (useful for one-off custom charts). */
|
|
35
|
+
readonly contracts?: NumericContracts;
|
|
36
|
+
/** Disable the conservative, 10×IQR scale-domination warning. */
|
|
37
|
+
readonly checkOutliers?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Audit the intrinsic numeric safety of data for a selected chart.
|
|
41
|
+
*
|
|
42
|
+
* This is the input-side companion to `diagnoseConfig` (representation) and
|
|
43
|
+
* `auditAccessibility` (reception). It is pure, deterministic, React-free, and
|
|
44
|
+
* accepts function accessors without serializing or executing arbitrary code
|
|
45
|
+
* outside the caller's own process.
|
|
46
|
+
*/
|
|
47
|
+
export declare function auditData(component: string, props: Datum, data?: ReadonlyArray<Datum>, options?: AuditDataOptions): DataAuditResult;
|
|
48
|
+
export { profileNumericFields } from "./numericFieldProfiler";
|
|
49
|
+
export type { NumericFieldProfile, ProfileNumericFieldsOptions } from "./numericFieldProfiler";
|
|
50
|
+
export { formatDataAudit, toDataAuditNotifications } from "./dataAuditPresentation";
|
|
51
|
+
export type { DataAuditChartNotification, DataAuditNotificationOptions } from "./dataAuditPresentation";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DataAuditResult } from "./auditData";
|
|
2
|
+
export interface DataAuditChartNotification {
|
|
3
|
+
readonly id: string;
|
|
4
|
+
readonly level: "warning" | "error";
|
|
5
|
+
readonly title: string;
|
|
6
|
+
readonly message: string;
|
|
7
|
+
readonly source: "Semiotic data audit";
|
|
8
|
+
readonly dismissible: true;
|
|
9
|
+
}
|
|
10
|
+
export interface DataAuditNotificationOptions {
|
|
11
|
+
/** Maximum individual findings before a final overflow notice. Default 6. */
|
|
12
|
+
readonly max?: number;
|
|
13
|
+
/** Omit non-blocking warnings. Default false. */
|
|
14
|
+
readonly errorsOnly?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export declare function formatDataAudit(result: DataAuditResult): string;
|
|
17
|
+
/** Map audit findings directly onto ChartContainer's notification contract. */
|
|
18
|
+
export declare function toDataAuditNotifications(result: DataAuditResult, options?: DataAuditNotificationOptions): DataAuditChartNotification[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
2
|
+
import type { NumericContracts, NumericFieldContract } from "./numericContracts";
|
|
3
|
+
/** Resolve a contract's outer or line-object nested row source. */
|
|
4
|
+
export declare function rowsForNumericField(field: NumericFieldContract, props: Datum, data: ReadonlyArray<Datum> | undefined): {
|
|
5
|
+
dataProp: string;
|
|
6
|
+
rows: ReadonlyArray<Datum>;
|
|
7
|
+
};
|
|
8
|
+
/** Find explicit empty outer arrays and all-empty declared nested series. */
|
|
9
|
+
export declare function explicitEmptyNumericSources(contracts: NumericContracts, props: Datum, data: ReadonlyArray<Datum> | undefined): string[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serializable numeric input contracts for chart capabilities.
|
|
3
|
+
*
|
|
4
|
+
* The contract table deliberately lives below the AI/capability registry. It is
|
|
5
|
+
* consumed by `diagnoseConfig` and `ChartContainer`, both of which must stay
|
|
6
|
+
* lightweight, while capability descriptors reference the same objects.
|
|
7
|
+
*/
|
|
8
|
+
export type NumericFieldRole = "x" | "y" | "value" | "size" | "count" | "opacity" | "time" | "lower" | "upper" | "open" | "close" | "high" | "low" | (string & {});
|
|
9
|
+
export type NumericRequirement = "finite" | "positive" | "non-negative" | "integer" | "unit-interval";
|
|
10
|
+
export interface NumericFieldContract {
|
|
11
|
+
/** Semantic role used in findings and dynamic scale checks. */
|
|
12
|
+
readonly role: NumericFieldRole;
|
|
13
|
+
/** Name of the chart prop that contains a string/function accessor. */
|
|
14
|
+
readonly accessor: string;
|
|
15
|
+
/** Resolve this field only when every named chart prop is present. */
|
|
16
|
+
readonly whenProps?: ReadonlyArray<string>;
|
|
17
|
+
/** Accessor used by the chart when the prop is omitted. */
|
|
18
|
+
readonly defaultAccessor?: string;
|
|
19
|
+
/** Collection prop to inspect. Defaults to `data`. */
|
|
20
|
+
readonly dataProp?: string;
|
|
21
|
+
/** Prop naming a nested row array (for line-object `coordinates`, for example). */
|
|
22
|
+
readonly nestedDataAccessorProp?: string;
|
|
23
|
+
/** Nested row-array field used when that prop is omitted. */
|
|
24
|
+
readonly defaultNestedDataAccessor?: string;
|
|
25
|
+
/** Every numeric binding is finite by default. */
|
|
26
|
+
readonly requirements?: ReadonlyArray<NumericRequirement>;
|
|
27
|
+
/** Temporal coercion supported by the chart: Date only, or Date + date-like strings. */
|
|
28
|
+
readonly temporalValues?: "date" | "date-like";
|
|
29
|
+
/** Permit null/undefined values as intentional gaps. Default false. */
|
|
30
|
+
readonly allowMissing?: boolean;
|
|
31
|
+
/** Finite numeric fallback the renderer applies to missing values. */
|
|
32
|
+
readonly missingValue?: number;
|
|
33
|
+
/** Whether equal values create a zero-span scale domain. */
|
|
34
|
+
readonly domain?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface NumericAggregateContract {
|
|
37
|
+
readonly kind: "positive-total" | "normalized-total";
|
|
38
|
+
/** Numeric field role to aggregate. */
|
|
39
|
+
readonly role: NumericFieldRole;
|
|
40
|
+
/** Optional grouping accessor prop (for one normalization total per x/category). */
|
|
41
|
+
readonly groupAccessor?: string;
|
|
42
|
+
readonly defaultGroupAccessor?: string;
|
|
43
|
+
/** Only enforce the aggregate when this boolean prop is true. */
|
|
44
|
+
readonly whenProp?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface NumericContracts {
|
|
47
|
+
readonly fields: ReadonlyArray<NumericFieldContract>;
|
|
48
|
+
readonly aggregates?: ReadonlyArray<NumericAggregateContract>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Compact built-in table. Shared contract objects are intentionally reused so
|
|
52
|
+
* this adds very little to `semiotic/utils/core` when diagnostics import it.
|
|
53
|
+
*/
|
|
54
|
+
export declare const BUILT_IN_NUMERIC_CONTRACTS: Readonly<Record<string, NumericContracts>>;
|
|
55
|
+
/** Internal hook used by the public capability registry for third-party charts. */
|
|
56
|
+
export declare function registerNumericContracts(component: string, contracts: NumericContracts | undefined): void;
|
|
57
|
+
/** Internal hook used when a third-party capability is unregistered. */
|
|
58
|
+
export declare function unregisterNumericContracts(component: string): void;
|
|
59
|
+
export declare function getNumericContracts(component: string): NumericContracts | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
2
|
+
export interface NumericFieldProfile {
|
|
3
|
+
readonly field: string;
|
|
4
|
+
readonly observedCount: number;
|
|
5
|
+
readonly finiteCount: number;
|
|
6
|
+
readonly missingCount: number;
|
|
7
|
+
readonly nonFiniteCount: number;
|
|
8
|
+
readonly nonNumericCount: number;
|
|
9
|
+
readonly zeroCount: number;
|
|
10
|
+
readonly negativeCount: number;
|
|
11
|
+
readonly fractionalCount: number;
|
|
12
|
+
readonly min?: number;
|
|
13
|
+
readonly q1?: number;
|
|
14
|
+
readonly median?: number;
|
|
15
|
+
readonly q3?: number;
|
|
16
|
+
readonly max?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ProfileNumericFieldsOptions {
|
|
19
|
+
/** Include exact quartiles. Disable when another profiler already sorts fields. */
|
|
20
|
+
readonly quantiles?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** Profile invalid/missing numeric candidates without silently dropping them. */
|
|
23
|
+
export declare function profileNumericFields(data: ReadonlyArray<Datum> | null | undefined, options?: ProfileNumericFieldsOptions): Readonly<Record<string, NumericFieldProfile>>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Screen-space geometry for magnitude-encoded bump-chart ribbons.
|
|
3
|
+
*
|
|
4
|
+
* A conventional area chart offsets both boundaries vertically. That makes a
|
|
5
|
+
* band look artificially thin when its centerline moves sharply between
|
|
6
|
+
* ranks. This helper follows the idea behind d3.svg.ribbon instead: sample the
|
|
7
|
+
* centerline, calculate its local normal, then offset by the requested radius.
|
|
8
|
+
* The visible thickness therefore stays perpendicular to the trajectory.
|
|
9
|
+
*/
|
|
10
|
+
export interface BumpRibbonPoint {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
/** Half of the desired visible ribbon thickness, in pixels. */
|
|
14
|
+
radius: number;
|
|
15
|
+
}
|
|
16
|
+
export interface BumpRibbonGeometry {
|
|
17
|
+
topPath: [number, number][];
|
|
18
|
+
bottomPath: [number, number][];
|
|
19
|
+
/** Index of the nearest input datum for every sampled path vertex. */
|
|
20
|
+
datumIndices: number[];
|
|
21
|
+
}
|
|
22
|
+
export interface BumpRibbonGeometryOptions {
|
|
23
|
+
/** Smooth horizontal-tangent Béziers or straight segments. */
|
|
24
|
+
curve?: "smooth" | "linear";
|
|
25
|
+
/** Samples emitted for each interval. Stable counts enable path animation. */
|
|
26
|
+
samplesPerSegment?: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build paired boundary paths around a bump-chart centerline.
|
|
30
|
+
*
|
|
31
|
+
* The first sample of every interval after the first is omitted because it is
|
|
32
|
+
* identical to the previous interval's final sample. Every trajectory with
|
|
33
|
+
* the same number of ranking columns therefore emits the same number of
|
|
34
|
+
* vertices, which lets StreamXYFrame interpolate paths during data updates.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildBumpRibbonGeometry(points: BumpRibbonPoint[], options?: BumpRibbonGeometryOptions): BumpRibbonGeometry;
|
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
import type { LegendLayout } from "./types/legendTypes";
|
|
1
|
+
import type { LegendLayout, LegendValue } from "./types/legendTypes";
|
|
2
2
|
export declare const DEFAULT_LEGEND_SWATCH_SIZE = 16;
|
|
3
3
|
export declare const DEFAULT_LEGEND_LABEL_GAP = 6;
|
|
4
4
|
export declare const DEFAULT_LEGEND_ITEM_GAP = 10;
|
|
5
5
|
export declare const DEFAULT_LEGEND_ROW_HEIGHT = 22;
|
|
6
|
+
export declare const DEFAULT_SIDE_LEGEND_WIDTH = 100;
|
|
7
|
+
export declare const DEFAULT_LEGEND_DISTANCE = 10;
|
|
8
|
+
/**
|
|
9
|
+
* SVG text has no useful intrinsic width until after it is mounted. Keep the
|
|
10
|
+
* estimate shared by margin calculation and rendering so side legends never
|
|
11
|
+
* reserve one width and draw into another.
|
|
12
|
+
*/
|
|
13
|
+
export declare function estimateLegendTextWidth(label: string): number;
|
|
14
|
+
/** Resolve the layout box needed by a left/right legend. */
|
|
15
|
+
export declare function resolveSideLegendWidth(legend: LegendValue | null | undefined, layout?: LegendLayout): number;
|
|
16
|
+
/** Resolve the requested gap between the legend edge and plot edge. */
|
|
17
|
+
export declare function resolveLegendDistance(legend: LegendValue | null | undefined): number;
|
|
18
|
+
/** Resolve plot-adjacent chrome reserved before a left/right legend. */
|
|
19
|
+
export declare function resolveLegendSideGutter(layout?: LegendLayout): number;
|
|
20
|
+
/** Estimate the layout-box height used to place a top/bottom legend. */
|
|
21
|
+
export declare function resolveHorizontalLegendHeight(legend: LegendValue | null | undefined, availableWidth: number, layout?: LegendLayout): number;
|
|
22
|
+
/** Margin required to fit a side legend and its plot-edge gap. */
|
|
23
|
+
export declare function resolveSideLegendMargin(legend: LegendValue | null | undefined, layout?: LegendLayout): number;
|
|
6
24
|
export interface LegendMetrics {
|
|
7
25
|
swatchSize: number;
|
|
8
26
|
labelGap: number;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { NetworkCustomLayout } from "../stream/networkCustomLayout";
|
|
2
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
3
|
+
import type { HighlightMatch } from "./recipeUtils";
|
|
4
|
+
/**
|
|
5
|
+
* `netEnsembleLayout` — a layout for **ensembles of disconnected (or only
|
|
6
|
+
* trivially connected) DAGs**: a "bag of little graphs" that force-directed
|
|
7
|
+
* layout scatters into meaningless blobs and hierarchical layouts (dagre,
|
|
8
|
+
* flextree) can't place at all because they assume one connected root.
|
|
9
|
+
*
|
|
10
|
+
* The organizing idea comes from the mathematical notion of a **net** (a
|
|
11
|
+
* Moore–Smith net: a function from a *directed set*). A directed set is a
|
|
12
|
+
* partial order in which every pair of elements has a common upper bound —
|
|
13
|
+
* "everything eventually flows together." A DAG hands you a partial order for
|
|
14
|
+
* free via reachability (`u ≤ v` iff `v` is reachable from `u`), and a finite
|
|
15
|
+
* directed set must have a single greatest element. For a weakly-connected DAG
|
|
16
|
+
* that collapses to a one-line, O(V+E) test: **count the sinks.** Exactly one
|
|
17
|
+
* sink ⟹ the component is a net converging to a single limit; two or more sinks
|
|
18
|
+
* ⟹ it fails directedness (some pair has no common descendant). See
|
|
19
|
+
* `/recipes/net-ensemble` for the full explanation.
|
|
20
|
+
*
|
|
21
|
+
* The layout:
|
|
22
|
+
* 1. splits the graph into weakly-connected components,
|
|
23
|
+
* 2. tests each for directedness (the sink count),
|
|
24
|
+
* 3. fingerprints each component with Weisfeiler–Leman color refinement so
|
|
25
|
+
* order-isomorphic components — the recurring *motifs* — group together,
|
|
26
|
+
* 4. lays each component out so flow converges toward its sink(s) at the
|
|
27
|
+
* bottom (the convergence-to-a-limit made spatial), and
|
|
28
|
+
* 5. arranges the ensemble as small multiples grouped into motif bands,
|
|
29
|
+
* turning a hairball-of-blobs into a **census** ("12 chains, 4 diamonds,
|
|
30
|
+
* 3 branching forks, 1 oddball") — the thing force layout can never show.
|
|
31
|
+
*
|
|
32
|
+
* Emits one hit-testable scene node per drawn mark (individual nodes at full
|
|
33
|
+
* detail, one node per component when cells collapse), so it inherits keyboard
|
|
34
|
+
* nav, annotation anchoring, and shared selection for free. Pure / SSR-safe.
|
|
35
|
+
*/
|
|
36
|
+
export interface NetEnsembleConfig {
|
|
37
|
+
/** Edge field naming the source node id. @default "source" */
|
|
38
|
+
sourceAccessor?: string;
|
|
39
|
+
/** Edge field naming the target node id. @default "target" */
|
|
40
|
+
targetAccessor?: string;
|
|
41
|
+
/** Node field for the display label. @default "label" */
|
|
42
|
+
labelAccessor?: string;
|
|
43
|
+
/** Node field for a category (used by `colorMode: "category"`). @default "category" */
|
|
44
|
+
categoryAccessor?: string;
|
|
45
|
+
/** Group order-isomorphic components into labelled motif bands. When `false`,
|
|
46
|
+
* every component is placed in one band ordered by size. @default true */
|
|
47
|
+
groupByMotif?: boolean;
|
|
48
|
+
/** Band ordering. @default "frequency" */
|
|
49
|
+
sort?: "frequency" | "size" | "directedness";
|
|
50
|
+
/** What node fill encodes. @default "directedness" */
|
|
51
|
+
colorMode?: "directedness" | "category" | "motif";
|
|
52
|
+
/** Node radius at full detail (px). @default 4 */
|
|
53
|
+
nodeRadius?: number;
|
|
54
|
+
/** Gap between component cells (px). @default 16 */
|
|
55
|
+
cellGap?: number;
|
|
56
|
+
/** Gap between motif bands (px). @default 22 */
|
|
57
|
+
bandGap?: number;
|
|
58
|
+
/** Height reserved for a band's header/label + exemplar (px). @default 34 */
|
|
59
|
+
headerHeight?: number;
|
|
60
|
+
/** Below this cell size (px) a component collapses to a single glyph — the
|
|
61
|
+
* census view for large ensembles. @default 38 */
|
|
62
|
+
minCellForFull?: number;
|
|
63
|
+
/** Largest cell edge (px). @default 120 */
|
|
64
|
+
maxCellSize?: number;
|
|
65
|
+
/** Smallest cell edge (px) before the layout stops shrinking to fit. @default 12 */
|
|
66
|
+
minCellSize?: number;
|
|
67
|
+
/** Weisfeiler–Leman refinement rounds for the motif fingerprint. More rounds
|
|
68
|
+
* distinguish subtler structural differences. @default 3 */
|
|
69
|
+
fingerprintRounds?: number;
|
|
70
|
+
/** Draw the motif descriptor + instance count in each band header. @default true */
|
|
71
|
+
showBandLabels?: boolean;
|
|
72
|
+
/** Draw the representative component once per band (the "template"). @default true */
|
|
73
|
+
showExemplars?: boolean;
|
|
74
|
+
/** Draw the directedness legend. @default true */
|
|
75
|
+
showLegend?: boolean;
|
|
76
|
+
/** Fill for converging (single-sink) components. @default theme info */
|
|
77
|
+
convergeColor?: string;
|
|
78
|
+
/** Fill for branching (multi-sink) components. @default theme warning */
|
|
79
|
+
branchColor?: string;
|
|
80
|
+
/** Edge stroke color. @default theme border */
|
|
81
|
+
edgeColor?: string;
|
|
82
|
+
/** Dim marks that don't match this `{field, value}` highlight. */
|
|
83
|
+
highlight?: HighlightMatch | null;
|
|
84
|
+
}
|
|
85
|
+
export interface NetEnsemblePlacedNode {
|
|
86
|
+
id: string;
|
|
87
|
+
cx: number;
|
|
88
|
+
cy: number;
|
|
89
|
+
r: number;
|
|
90
|
+
datum: Datum;
|
|
91
|
+
category: string;
|
|
92
|
+
}
|
|
93
|
+
export interface NetEnsemblePlacedEdge {
|
|
94
|
+
x1: number;
|
|
95
|
+
y1: number;
|
|
96
|
+
x2: number;
|
|
97
|
+
y2: number;
|
|
98
|
+
}
|
|
99
|
+
/** One weakly-connected component of the ensemble, with its net diagnostics. */
|
|
100
|
+
export interface NetEnsembleComponent {
|
|
101
|
+
/** Node ids belonging to this component. */
|
|
102
|
+
ids: string[];
|
|
103
|
+
nodeCount: number;
|
|
104
|
+
edgeCount: number;
|
|
105
|
+
/** Sinks (out-degree 0) and sources (in-degree 0) within the component. */
|
|
106
|
+
sinkCount: number;
|
|
107
|
+
sourceCount: number;
|
|
108
|
+
/**
|
|
109
|
+
* True iff the component is a **directed set** (a net with a single limit):
|
|
110
|
+
* for a weakly-connected DAG this holds exactly when there is one sink, so
|
|
111
|
+
* every pair of nodes shares a common descendant. Multiple sinks ⟹ some pair
|
|
112
|
+
* has no common upper bound and the component fails directedness.
|
|
113
|
+
*/
|
|
114
|
+
directed: boolean;
|
|
115
|
+
/** Weisfeiler–Leman fingerprint — order-isomorphic components share it. */
|
|
116
|
+
motif: string;
|
|
117
|
+
/** Short human descriptor of the shape (e.g. `"chain of 5"`, `"diamond / mesh"`). */
|
|
118
|
+
descriptor: string;
|
|
119
|
+
}
|
|
120
|
+
/** A motif class: one recurring structural shape and how many times it appears. */
|
|
121
|
+
export interface NetEnsembleMotif {
|
|
122
|
+
motif: string;
|
|
123
|
+
descriptor: string;
|
|
124
|
+
count: number;
|
|
125
|
+
directed: boolean;
|
|
126
|
+
}
|
|
127
|
+
export interface NetEnsembleAnalysis {
|
|
128
|
+
/** Every weakly-connected component, with net diagnostics. */
|
|
129
|
+
components: NetEnsembleComponent[];
|
|
130
|
+
/** The distinct motif classes, most frequent first. */
|
|
131
|
+
motifs: NetEnsembleMotif[];
|
|
132
|
+
/** Components that converge to a single sink (are directed nets). */
|
|
133
|
+
directedCount: number;
|
|
134
|
+
/** Components that branch to two or more sinks. */
|
|
135
|
+
branchingCount: number;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Analyze a graph as an **ensemble of nets** — headless, no rendering. Splits
|
|
139
|
+
* the graph into weakly-connected components, tests each for directedness (the
|
|
140
|
+
* sink count), fingerprints them so recurring motifs group together, and
|
|
141
|
+
* returns the motif census. The pure core of {@link netEnsembleLayout}; reach
|
|
142
|
+
* for it when you want the diagnostics (how many chains? how many branch?)
|
|
143
|
+
* without drawing, e.g. to drive a summary readout or a data-quality check.
|
|
144
|
+
*/
|
|
145
|
+
export declare function analyzeNetEnsemble(nodes: ReadonlyArray<{
|
|
146
|
+
id: string;
|
|
147
|
+
}>, edges: ReadonlyArray<{
|
|
148
|
+
source: string;
|
|
149
|
+
target: string;
|
|
150
|
+
}>, options?: {
|
|
151
|
+
fingerprintRounds?: number;
|
|
152
|
+
}): NetEnsembleAnalysis;
|
|
153
|
+
export interface BandInfo {
|
|
154
|
+
motif: string;
|
|
155
|
+
descriptor: string;
|
|
156
|
+
count: number;
|
|
157
|
+
directed: boolean;
|
|
158
|
+
x: number;
|
|
159
|
+
y: number;
|
|
160
|
+
width: number;
|
|
161
|
+
height: number;
|
|
162
|
+
exemplar: {
|
|
163
|
+
nodes: NetEnsemblePlacedNode[];
|
|
164
|
+
edges: NetEnsemblePlacedEdge[];
|
|
165
|
+
} | null;
|
|
166
|
+
}
|
|
167
|
+
export declare const netEnsembleLayout: NetworkCustomLayout<NetEnsembleConfig>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import type { BandInfo } from "./netEnsembleLayout";
|
|
3
|
+
export interface NetEnsembleOverlayOptions {
|
|
4
|
+
convergeColor: string;
|
|
5
|
+
branchColor: string;
|
|
6
|
+
edgeColor: string;
|
|
7
|
+
plot: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
showBandLabels: boolean;
|
|
14
|
+
showExemplars: boolean;
|
|
15
|
+
showLegend: boolean;
|
|
16
|
+
textColor: string;
|
|
17
|
+
subText: string;
|
|
18
|
+
}
|
|
19
|
+
/** Render presentation-only band labels, exemplars, and the directedness key. */
|
|
20
|
+
export declare function buildNetEnsembleOverlays(bands: BandInfo[], o: NetEnsembleOverlayOptions): ReactNode;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { OrdinalCustomLayout } from "../stream/ordinalCustomLayout";
|
|
2
|
+
import type { Datum } from "../charts/shared/datumTypes";
|
|
3
|
+
export { wordTrailsProgressiveReveal, type WordTrailsProgressiveRevealOptions } from "./wordTrailsProgressiveReveal";
|
|
4
|
+
/**
|
|
5
|
+
* Word Trails — a *quantitatively honest* word cloud.
|
|
6
|
+
*
|
|
7
|
+
* Where a classic word cloud (d3-cloud / amueller) packs words into free space
|
|
8
|
+
* with only size encoding frequency and position meaning nothing, Word Trails
|
|
9
|
+
* gives position meaning on both axes:
|
|
10
|
+
*
|
|
11
|
+
* - **columns** (x) are a category — e.g. each speaker in a debate;
|
|
12
|
+
* - **the vertical axis** (y) is an ordered value — e.g. the debate segment
|
|
13
|
+
* where the word peaked, so a word's height reads as *when* it was said;
|
|
14
|
+
* - **font size** encodes frequency/weight.
|
|
15
|
+
*
|
|
16
|
+
* Each column is laid out with greedy, largest-first placement: every word
|
|
17
|
+
* searches outward from its segment anchor for the nearest free spot, so the
|
|
18
|
+
* result is **overlap-free by construction**. A single global font scale
|
|
19
|
+
* (`scaleToFit`) shrinks every word together until it all fits — relative
|
|
20
|
+
* magnitude is preserved, nothing is clipped or dropped.
|
|
21
|
+
*
|
|
22
|
+
* The reading: scan a column top-to-bottom to follow one speaker through time;
|
|
23
|
+
* scan across a row to compare what everyone emphasised at the same moment.
|
|
24
|
+
*
|
|
25
|
+
* Inspired by Elijah Meeks's 2016 "Word Trails" debate visualization. Because
|
|
26
|
+
* placement is *box*-aware (not sprite/pixel), the layout needs no canvas text
|
|
27
|
+
* measurement — it is pure and SSR-clean.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { OrdinalCustomChart } from "semiotic/ordinal"
|
|
32
|
+
* import { wordTrailsLayout } from "semiotic/recipes"
|
|
33
|
+
*
|
|
34
|
+
* <OrdinalCustomChart
|
|
35
|
+
* data={terms} // [{ word, weight, speaker, segment }]
|
|
36
|
+
* layout={wordTrailsLayout}
|
|
37
|
+
* layoutConfig={{
|
|
38
|
+
* textAccessor: "word",
|
|
39
|
+
* weightAccessor: "weight",
|
|
40
|
+
* columnAccessor: "speaker",
|
|
41
|
+
* segmentAccessor: "segment",
|
|
42
|
+
* }}
|
|
43
|
+
* width={860}
|
|
44
|
+
* height={520}
|
|
45
|
+
* />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export interface WordTrailsWordInfo {
|
|
49
|
+
/** Rendered word text. */
|
|
50
|
+
word: string;
|
|
51
|
+
/** Column containing this word. */
|
|
52
|
+
column: string;
|
|
53
|
+
/** Quantitative weight used to size this word. */
|
|
54
|
+
weight: number;
|
|
55
|
+
/** Ordered segment/time value anchoring this word vertically. */
|
|
56
|
+
segment: number;
|
|
57
|
+
/** Exact source row supplied to the chart. */
|
|
58
|
+
datum: Datum;
|
|
59
|
+
/** Index of `datum` in the chart's input data. */
|
|
60
|
+
dataIndex: number;
|
|
61
|
+
/** Index of the word's column in the final rendered column order. */
|
|
62
|
+
columnIndex: number;
|
|
63
|
+
/** Column color after `columnColor` / the chart theme has been resolved. */
|
|
64
|
+
resolvedColumnColor: string;
|
|
65
|
+
}
|
|
66
|
+
export interface WordTrailsConfig {
|
|
67
|
+
/** Field (or fn) giving the word text. */
|
|
68
|
+
textAccessor: string | ((d: Datum) => string);
|
|
69
|
+
/** Field (or fn) giving the word weight (→ font size). */
|
|
70
|
+
weightAccessor: string | ((d: Datum) => number);
|
|
71
|
+
/** Field (or fn) giving the column category (→ x band). */
|
|
72
|
+
columnAccessor: string | ((d: Datum) => string);
|
|
73
|
+
/** Field (or fn) giving the ordered segment/time value (→ pinned y). */
|
|
74
|
+
segmentAccessor: string | ((d: Datum) => number);
|
|
75
|
+
/** `[min, max]` of the segment axis. Derived from data when omitted. */
|
|
76
|
+
segmentDomain?: [number, number];
|
|
77
|
+
/** Explicit column order. Data insertion order when omitted. */
|
|
78
|
+
columnOrder?: string[];
|
|
79
|
+
/** Smallest font size, px. @default 11 */
|
|
80
|
+
minFontSize?: number;
|
|
81
|
+
/** Largest font size, px. @default 42 */
|
|
82
|
+
maxFontSize?: number;
|
|
83
|
+
/** Gap between columns, px. @default 18 */
|
|
84
|
+
columnGutter?: number;
|
|
85
|
+
/**
|
|
86
|
+
* Gap kept between word boxes, px — the density knob. `0` packs words as
|
|
87
|
+
* tightly as their glyph boxes allow (crowded, still overlap-free); larger
|
|
88
|
+
* values open the cloud up. @default 2
|
|
89
|
+
*/
|
|
90
|
+
collisionPadding?: number;
|
|
91
|
+
/**
|
|
92
|
+
* Per-word fill override. Return a color for a word (e.g. from a
|
|
93
|
+
* distinctiveness / sentiment model) or `undefined` to fall back to the
|
|
94
|
+
* column color. Same word ⇒ same color across columns if you key on the text.
|
|
95
|
+
*/
|
|
96
|
+
wordColor?: (info: WordTrailsWordInfo) => string | undefined | null;
|
|
97
|
+
/**
|
|
98
|
+
* Per-word reveal opacity. Return a value in `[0, 1]`; values are clamped,
|
|
99
|
+
* and non-finite values resolve to `0`. Every row still participates in
|
|
100
|
+
* scale-to-fit and collision placement, so changing opacity cannot move the
|
|
101
|
+
* remaining words. A resolved `0` emits neither a glyph nor an interactive
|
|
102
|
+
* hit target. By default a nonzero value multiplies the built-in weight
|
|
103
|
+
* opacity; set `weightOpacity` to `false` when this callback should be the
|
|
104
|
+
* exact rendered opacity.
|
|
105
|
+
* @default () => 1
|
|
106
|
+
*/
|
|
107
|
+
wordOpacity?: (info: WordTrailsWordInfo) => number;
|
|
108
|
+
/**
|
|
109
|
+
* Fade lower-weight words from `0.5` to `1` opacity in addition to encoding
|
|
110
|
+
* weight with font size. Disable this when opacity carries an independent
|
|
111
|
+
* variable such as recency; `wordOpacity` then controls rendered opacity
|
|
112
|
+
* exactly. @default true
|
|
113
|
+
*/
|
|
114
|
+
weightOpacity?: boolean;
|
|
115
|
+
/** Per-column label color override. Falls back to the categorical palette. */
|
|
116
|
+
columnColor?: (column: string) => string | undefined | null;
|
|
117
|
+
/** Draw the speaker/column labels along the top. @default true */
|
|
118
|
+
showColumnLabels?: boolean;
|
|
119
|
+
/** Draw the segment/time value axis on the left. @default true */
|
|
120
|
+
showSegmentAxis?: boolean;
|
|
121
|
+
/** Approx. number of ticks on the segment axis. @default 6 */
|
|
122
|
+
segmentTickCount?: number;
|
|
123
|
+
/** Formats a segment value for the axis + tooltip. @default String */
|
|
124
|
+
segmentTickFormat?: (v: number) => string;
|
|
125
|
+
/** Title shown above the segment axis (e.g. "Debate segment"). */
|
|
126
|
+
segmentAxisLabel?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Max rotation magnitude, degrees. Each word gets a deterministic angle in
|
|
129
|
+
* `[-rotate, +rotate]`. `0` keeps every word horizontal (most legible).
|
|
130
|
+
* @default 0
|
|
131
|
+
*/
|
|
132
|
+
rotate?: number;
|
|
133
|
+
/**
|
|
134
|
+
* Allow the same word to appear more than once in a column. When `false`
|
|
135
|
+
* (default), duplicate `(column, word)` rows are merged to a single entry at
|
|
136
|
+
* the row with the greatest weight (its peak) — the classic word-cloud
|
|
137
|
+
* reading. When `true`, every row is kept, so a word can trail down its
|
|
138
|
+
* column once per segment it appeared in. @default false
|
|
139
|
+
*/
|
|
140
|
+
repeatWords?: boolean;
|
|
141
|
+
/**
|
|
142
|
+
* Uniformly shrink every word by one global factor until nothing overlaps.
|
|
143
|
+
* Relative magnitude is preserved (a word twice as frequent stays twice the
|
|
144
|
+
* area) — only the absolute scale drops as words are added. Turn it off to
|
|
145
|
+
* keep exact `minFontSize`/`maxFontSize` sizing and accept overlap.
|
|
146
|
+
* @default true
|
|
147
|
+
*/
|
|
148
|
+
scaleToFit?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Target fraction of each column's area filled by word boxes before the
|
|
151
|
+
* global scale is reduced. Lower packs looser (more whitespace); higher
|
|
152
|
+
* starts larger and lets the greedy placer crowd words in. @default 0.6
|
|
153
|
+
*/
|
|
154
|
+
packingDensity?: number;
|
|
155
|
+
}
|
|
156
|
+
export declare const wordTrailsLayout: OrdinalCustomLayout<WordTrailsConfig>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { WordTrailsConfig } from "./wordTrails";
|
|
2
|
+
/** Options for a stable, progressive Word Trails reveal. */
|
|
3
|
+
export interface WordTrailsProgressiveRevealOptions {
|
|
4
|
+
/** Segment that is currently active/reached. Values are clamped to `segmentDomain`. */
|
|
5
|
+
currentSegment: number;
|
|
6
|
+
/** Ordered `[oldest, newest]` segment extent used for the fade. */
|
|
7
|
+
segmentDomain: readonly [number, number];
|
|
8
|
+
/** Opacity of the oldest reached segment. @default 0.25 */
|
|
9
|
+
oldestOpacity?: number;
|
|
10
|
+
/** Opacity of the current segment. @default 1 */
|
|
11
|
+
currentOpacity?: number;
|
|
12
|
+
/** Opacity of unreached segments. `0` hides their glyphs and hit targets. @default 0 */
|
|
13
|
+
futureOpacity?: number;
|
|
14
|
+
/** Also multiply the reveal by Word Trails' built-in weight fade. @default false */
|
|
15
|
+
combineWeightOpacity?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build the two config fields for a stable, progressive segment reveal.
|
|
19
|
+
*
|
|
20
|
+
* Reached rows fade linearly from `oldestOpacity` at the start of the domain
|
|
21
|
+
* to `currentOpacity` at `currentSegment`; future rows use `futureOpacity`.
|
|
22
|
+
* Word Trails still lays out zero-opacity rows, so playback changes visibility
|
|
23
|
+
* without reflow. The returned config disables the independent weight-opacity
|
|
24
|
+
* encoding unless `combineWeightOpacity` is explicitly enabled.
|
|
25
|
+
*
|
|
26
|
+
* This is the Word Trails composition counterpart to the runtime-neutral
|
|
27
|
+
* `opacityFromAge` helper: it keeps the same linear newest-to-oldest reading,
|
|
28
|
+
* then adds future hiding, layout reservation, and exact weight-opacity
|
|
29
|
+
* semantics without making the recipes entry point depend on a motion runtime.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* layoutConfig={{
|
|
34
|
+
* ...config,
|
|
35
|
+
* ...wordTrailsProgressiveReveal({
|
|
36
|
+
* currentSegment: iteration,
|
|
37
|
+
* segmentDomain: [0, lastIteration]
|
|
38
|
+
* })
|
|
39
|
+
* }}
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function wordTrailsProgressiveReveal(options: WordTrailsProgressiveRevealOptions): Pick<WordTrailsConfig, "wordOpacity" | "weightOpacity">;
|
|
@@ -18,6 +18,9 @@ export { toConfig, fromConfig, toURL, fromURL, copyConfig, configToJSX } from ".
|
|
|
18
18
|
export type { ChartConfig, ToConfigOptions, CopyFormat } from "./export/chartConfig";
|
|
19
19
|
export { summarizeData } from "./data/DataSummarizer";
|
|
20
20
|
export type { DataSummary, FieldSummary, FieldType, SummarizeOptions } from "./data/DataSummarizer";
|
|
21
|
+
export { auditData, formatDataAudit, profileNumericFields, toDataAuditNotifications, } from "./data/auditData";
|
|
22
|
+
export type { AuditDataOptions, CheckedNumericContract, DataAuditChartNotification, DataAuditDiagnosis, DataAuditNotificationOptions, DataAuditResult, NumericFieldProfile, ProfileNumericFieldsOptions, } from "./data/auditData";
|
|
23
|
+
export type { NumericAggregateContract, NumericContracts, NumericFieldContract, NumericFieldRole, NumericRequirement, } from "./data/numericContracts";
|
|
21
24
|
export { profileData } from "./ai/profileData";
|
|
22
25
|
export type { ProfileDataOptions } from "./ai/profileData";
|
|
23
26
|
export { inferIntent } from "./ai/inferIntent";
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { auditData, formatDataAudit, profileNumericFields, toDataAuditNotifications, } from "./data/auditData";
|
|
2
|
+
export type { AuditDataOptions, CheckedNumericContract, DataAuditChartNotification, DataAuditDiagnosis, DataAuditNotificationOptions, DataAuditResult, NumericFieldProfile, ProfileNumericFieldsOptions, } from "./data/auditData";
|
|
3
|
+
export type { NumericAggregateContract, NumericContracts, NumericFieldContract, NumericFieldRole, NumericRequirement, } from "./data/numericContracts";
|
|
4
|
+
export type { ChartContainerDataAudit, ChartContainerDataAuditOptions, } from "./chartContainerDataAudit";
|