@eledah/parto
Version:
Framework-agnostic argument map sunburst charts with light/dark themes
234 lines (201 loc) • 6.69 kB
TypeScript
export declare interface ArgumentMapChart {
setData(data: ArgumentMapData): void;
setLoading(loading: boolean): void;
showError(message?: string): void;
setTheme(theme: ThemeMode): void;
setColors(colors: Partial<ArgumentMapColors>): void;
highlight(nodeId: string | null): void;
zoomTo(nodeId: string): void;
zoomToPath(nodeIds: string[]): void;
zoomOut(): void;
resetZoom(): void;
resize(): void;
destroy(): void;
getZoomPath(): NodeContext[];
}
declare interface ArgumentMapColorConfig {
center: string;
support: string;
attack: string;
border: string;
}
export declare interface ArgumentMapColors {
center: string;
support: string;
attack: string;
border: string;
}
export declare interface ArgumentMapData {
new_nodes: ArgumentMapNode[];
}
export declare class ArgumentMapError extends Error {
constructor(message: string);
}
export declare interface ArgumentMapLabels {
legend?: string;
center: string;
support: string;
attack: string;
claim: string;
unknownSpeaker: string;
intensity: string;
confidence: string;
statusLoading: string;
statusEmpty: string;
statusError: string;
}
export declare interface ArgumentMapNode {
id: string;
type: string;
title: string;
description: string;
quote: string;
speaker: string;
relations: Relation[];
score?: NodeScore;
}
export declare interface ArgumentMapOptions {
theme?: ThemeMode;
colors?: Partial<ArgumentMapColors>;
/** Show the centered semantic-color legend inside the chart. Defaults to true. */
legend?: boolean;
tooltip?: boolean | TooltipRenderer;
zoom?: boolean;
direction?: Direction;
lang?: string;
labels?: Partial<ArgumentMapLabels>;
ariaLabel?: string;
onNodeHover?: (node: TreeNode, event: MouseEvent | FocusEvent | PointerEvent) => void;
onNodeLeave?: () => void;
onNodeClick?: (node: TreeNode, depth: number, hasChildren: boolean) => void;
onZoomChange?: (path: NodeContext[]) => void;
onWarning?: (message: string) => void;
}
/**
* Build a nested tree from flat nodes. Uses adjacency indexing for O(n + edges).
* Multi-parent nodes appear under each parent as separate copies with unique pathKeys.
*/
export declare function buildTree(nodes: ArgumentMapNode[]): BuildTreeResult;
declare interface BuildTreeResult {
tree: TreeNode | null;
warnings: string[];
}
export declare const chartConfig: {
colors: ArgumentMapColorConfig;
chart: {
maxCenterRadius: number;
radiusPadding: number;
minRadius: number;
cornerRadius: number;
strokeWidth: number;
};
spacing: {
verticalGap: number;
padAngle: {
inner: number;
outer: number;
};
radiusExponent: {
base: number;
perLevel: number;
};
exponentDepthThreshold: number;
};
};
export declare function createArgumentMap(target: string | HTMLElement, data?: ArgumentMapData | null, options?: ArgumentMapOptions): ArgumentMapChart;
export declare function createDefaultTooltip(node: TreeNode, labels?: ArgumentMapLabels): HTMLElement;
export declare const DEFAULT_COLORS: ArgumentMapColors;
export declare const DEFAULT_LABELS: ArgumentMapLabels;
export declare type Direction = 'ltr' | 'rtl' | 'inherit';
export declare function findNodeById(root: TreeNode | null, id: string): TreeNode | null;
declare type InteractionEvent = PointerEvent | FocusEvent;
export declare interface NodeContext {
id: string;
title: string;
type: string;
relationType?: RelationType;
}
export declare interface NodeScore {
intensity: number;
confidence: number;
}
export declare function pathToNode(root: TreeNode, targetId: string): TreeNode[];
export declare interface Relation {
target_node_id: string;
relation_type: RelationType;
reasoning: string;
}
export declare type RelationType = 'support' | 'attack';
export declare class SunburstRenderer {
private container;
private chartRoot;
private width;
private height;
private radius;
private svg;
private g;
private partition;
private arc;
private legend;
private currentRoot;
private highlightId;
private resizeObserver;
private options;
private tooltipId;
/** First touch tap shows tooltip; second tap on same arc triggers zoom. */
private touchZoomPathKey;
private touchOutsideHandler;
constructor(container: HTMLElement, options: SunburstRendererOptions);
destroy(): void;
resize(): void;
setHighlight(nodeId: string | null): void;
render(rootNode: TreeNode): void;
getTooltipElementId(): string;
private createLegend;
private bindTouchOutsideDismiss;
private unbindTouchOutsideDismiss;
}
declare interface SunburstRendererOptions {
ariaLabel: string;
legend?: boolean;
labels?: ArgumentMapLabels;
zoomEnabled: boolean;
onHover?: (node: TreeNode, event: InteractionEvent) => void;
onLeave?: () => void;
onClick?: (node: TreeNode, depth: number, hasChildren: boolean) => void;
}
export declare type ThemeMode = 'light' | 'dark' | 'auto';
export declare type TooltipRenderer = (node: TreeNode, labels: ArgumentMapLabels) => HTMLElement;
export declare interface TreeNode extends ArgumentMapNode {
children: TreeNode[];
value: number;
relationType?: RelationType;
relationReasoning?: string;
parentId?: string;
/** Unique key for this visual occurrence (supports multi-parent nodes). */
pathKey: string;
}
export declare function validateMapData(input: unknown): ValidationResult;
export declare class ValidationError extends ArgumentMapError {
readonly issues: string[];
constructor(issues: string[]);
}
declare interface ValidationResult {
data: ArgumentMapData;
warnings: string[];
}
export declare class ZoomController {
private fullTree;
private zoomStack;
setTree(tree: TreeNode | null): void;
getFocusRoot(): TreeNode | null;
getFullTree(): TreeNode | null;
getZoomPath(): NodeContext[];
resetZoom(): void;
zoomTo(nodeId: string): boolean;
zoomToPath(nodeIds: string[]): boolean;
zoomIn(node: TreeNode): boolean;
zoomOut(): boolean;
handleClick(node: TreeNode, depth: number, hasChildren: boolean): void;
}
export { }