/** * @file Custom renderers for trading analytics dashboard connections and ports */ import * as React from "react"; import type { ConnectionRenderContext, PortRenderContext } from "../../../../../types/NodeDefinition"; import { calculateConnectionControlPoints, calculateConnectionPath } from "../../../../../core/connection/path"; import { cubicBezierPoint } from "../../../../../core/geometry/curve"; /** * Custom connection renderer with dotted curved lines and correlation coefficient badges */ export const renderTradingConnection = ( context: ConnectionRenderContext, defaultRender: () => React.ReactElement, ): React.ReactElement => { const { connection, fromPosition, toPosition, fromPort: _fromPort, toPort, handlers, isSelected, isHovered } = context; // If no connection exists yet (preview mode), use default if (!connection) { return defaultRender(); } // Get correlation coefficient from connection data const correlation = connection.data?.correlation as number | undefined; // Fallback to default if toPort is undefined (should not happen in connected state) if (!toPort) { return defaultRender(); } // Calculate bezier path for curved connection const pathData = calculateConnectionPath(fromPosition, toPosition); // Calculate midpoint for badge placement const { cp1, cp2 } = calculateConnectionControlPoints(fromPosition, toPosition); const midPoint = cubicBezierPoint(fromPosition, cp1, cp2, toPosition, 0.5); // Determine colors based on correlation coefficient - matching reference image const getCorrelationColor = (coeff: number | undefined): string => { if (coeff === undefined) {return "#94a3b8";} if (coeff >= 0.9) {return "#34d399";} // Strong positive - green-400 if (coeff >= 0.7) {return "#34d399";} // Moderate positive - green-400 if (coeff >= 0.3) {return "#34d399";} // Weak positive - green-400 if (coeff >= -0.3) {return "#fbbf24";} // No correlation - amber-400 if (coeff >= -0.7) {return "#fb923c";} // Weak negative - orange-400 return "#ef4444"; // Strong negative correlation - red-500 }; const correlationColor = getCorrelationColor(correlation); // Use the correlation color for the connection line const strokeColor = isSelected || isHovered ? correlationColor : correlationColor; const strokeWidth = 3; return ( {/* Dotted connection path */} {/* Correlation coefficient badge at midpoint */} {correlation !== undefined && ( {/* Badge background rounded rectangle */} {/* Correlation coefficient text */} {correlation.toFixed(3)} )} ); }; /** * Custom port renderer with circular dots (hidden by default, visible on interaction) */ export const renderTradingPort = ( context: PortRenderContext, defaultRender: () => React.ReactElement, ): React.ReactElement => { const { port, isConnecting, isConnectable, isCandidate, isHovered, position, handlers } = context; if (!position) { return defaultRender(); } // Determine port appearance based on state - completely hidden to match reference image const getPortSize = (): number => { if (isConnecting && isCandidate) {return 6;} if (isHovered) {return 4;} return 0; // Hidden by default }; const getPortColor = (): string => { if (isConnecting && isConnectable) {return "#10b981";} // Emerald green when connectable if (isConnecting) {return "#ef4444";} // Red when not connectable if (isHovered) {return "#94a3b8";} // Subtle gray when hovered return "transparent"; }; const portSize = getPortSize(); const portColor = getPortColor(); return (
{portSize > 0 && (
)}
); };