Medicine Wheel graph visualization — circular layout with four-direction node positioning, ceremony-aware edges, OCAP® indicators, and RSIS visualization utilities.
Version: 0.1.1
Package: medicine-wheel-graph-viz
Document ID: rispec-graph-viz-v1
Last Updated: 2026-02-23
Users create visual relational webs rendered as Medicine Wheel circular graphs where:
What this enables: Interactive circular graph visualizations that make relational webs visible. Users see which directions have many nodes, which relations lack ceremony, and where OCAP® compliance gaps exist — all at a glance.
Structural Tension: Between standard force-directed graph layouts (no cultural meaning) and Medicine Wheel spatial semantics (directions carry teachings, seasons, obligations). The layout engine resolves this by placing nodes in culturally meaningful quadrants.
applyWheelLayout(data: MWGraphData, config?: Partial<WheelLayoutConfig>): MWGraphData
// Mutates node x/y positions. Returns the data.
// Direction → Angle mapping (clockwise from East):
// East: 315°–45° (right)
// South: 45°–135° (bottom)
// West: 135°–225° (left)
// North: 225°–315° (top)
// Nodes without direction → center cluster
interface WheelLayoutConfig {
mode: 'wheel' | 'force' | 'radial';
centerX: number; // default: 300
centerY: number; // default: 300
radius: number; // default: 250 (outer)
innerRadius?: number; // default: 60
quadrantPadding?: number; // degrees between quadrants
startAngle?: number; // rotation offset
jitter?: boolean; // avoid overlap
jitterAmount?: number; // pixels
}
getQuadrantGeometries(config?): QuadrantGeometry[]
// Returns per-quadrant: { direction, startAngle, endAngle, centerAngle, color, label, ojibwe }
quadrantArcPath(cx, cy, outerRadius, innerRadius, startAngle, endAngle): string
// SVG arc path for quadrant background sectors
curvedLinkPath(x1, y1, x2, y2, curvature?): string
// SVG path for edges (straight or curved)
directionLabelPosition(cx, cy, radius, direction): { x, y, anchor }
// Positioning for direction labels outside the wheel
interface MWGraphNode {
id: string;
label: string;
type: NodeType;
direction?: DirectionName;
x?: number; y?: number; // set by layout
size?: number;
color?: string;
opacity?: number;
selected?: boolean;
highlighted?: boolean;
ocapCompliant?: boolean;
wilsonAlignment?: number;
data?: RelationalNode;
metadata?: Record<string, unknown>;
}
interface MWGraphLink {
source: string;
target: string;
label?: string;
style?: 'solid' | 'dashed' | 'dotted' | 'ceremony';
strength?: number;
ceremonyHonored?: boolean;
ceremonyType?: CeremonyType;
color?: string;
width?: number;
curvature?: number;
metadata?: Record<string, unknown>;
}
interface MWGraphData {
nodes: MWGraphNode[];
links: MWGraphLink[];
focusedNodeId?: string;
}
nodesToGraphNodes(nodes: RelationalNode[]): MWGraphNode[]
edgesToGraphLinks(edges: RelationalEdge[]): MWGraphLink[]
relationsToGraphLinks(relations: Relation[]): MWGraphLink[]
buildGraphData(nodes, edges, relations?): MWGraphData
<MedicineWheelGraph
data={graphData}
width={600}
height={600}
layout=
showDirectionLabels
showQuadrants
showOcapIndicators
showWilsonHalos
darkMode={false}
onNodeClick={(node) => {}}
onNodeHover={(node) => {}}
onLinkClick={(link) => {}}
/>
toKinshipGraphLayout(hubs, relations): { nodes: KinshipGraphNode[], edges: KinshipGraphEdge[] }
toReciprocityFlowDiagram(flows): { nodes: FlowDiagramNode[], links: FlowDiagramLink[] }
toDirectionWheelData(distribution): DirectionWheelSegment[]
toCeremonyTimelineData(ceremonies): TimelineEntry[]
toMermaidDiagram(nodes, edges): string
// Generates Mermaid graph syntax for documentation embedding
medicine-wheel-ontology-core ^0.1.1react >=18.0.0, react-dom >=18.0.0