|
|
""" |
|
|
HITL-KG Styles Module |
|
|
|
|
|
Contains all styling constants for the visualization: |
|
|
- Cytoscape graph stylesheet |
|
|
- Layout configurations |
|
|
- Color schemes |
|
|
- Node descriptions for UI |
|
|
""" |
|
|
|
|
|
from typing import Dict, List, Any |
|
|
|
|
|
|
|
|
COLORS = { |
|
|
"bg_primary": "#0f172a", |
|
|
"bg_secondary": "#1e293b", |
|
|
"bg_tertiary": "#334155", |
|
|
"text_primary": "#f8fafc", |
|
|
"text_secondary": "#e2e8f0", |
|
|
"text_muted": "#94a3b8", |
|
|
"border": "#475569", |
|
|
|
|
|
|
|
|
"query": "#38bdf8", |
|
|
"fact": "#4ade80", |
|
|
"reasoning": "#818cf8", |
|
|
"hypothesis": "#fbbf24", |
|
|
"conclusion": "#f472b6", |
|
|
"evidence": "#2dd4bf", |
|
|
"constraint": "#fb7185", |
|
|
"ghost": "#94a3b8", |
|
|
|
|
|
|
|
|
"edge_default": "#64748b", |
|
|
"edge_supports": "#4ade80", |
|
|
"edge_contradicts": "#f87171", |
|
|
"edge_alternative": "#fbbf24", |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
CYTOSCAPE_STYLESHEET = [ |
|
|
|
|
|
{ |
|
|
"selector": "node", |
|
|
"style": { |
|
|
"label": "data(label)", |
|
|
"background-color": "#818cf8", |
|
|
"color": COLORS["text_primary"], |
|
|
"font-size": "11px", |
|
|
"font-weight": "500", |
|
|
"text-wrap": "wrap", |
|
|
"text-max-width": "120px", |
|
|
"text-valign": "bottom", |
|
|
"text-halign": "center", |
|
|
"text-margin-y": "6px", |
|
|
"text-outline-color": COLORS["bg_primary"], |
|
|
"text-outline-width": "2px", |
|
|
"width": "35px", |
|
|
"height": "35px", |
|
|
"border-width": "2px", |
|
|
"border-color": "#ffffff33", |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
{ |
|
|
"selector": "edge", |
|
|
"style": { |
|
|
"curve-style": "bezier", |
|
|
"target-arrow-shape": "triangle", |
|
|
"target-arrow-color": COLORS["edge_default"], |
|
|
"line-color": COLORS["edge_default"], |
|
|
"width": 2, |
|
|
"opacity": 0.7, |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
{ |
|
|
"selector": ".query", |
|
|
"style": { |
|
|
"background-color": COLORS["query"], |
|
|
"shape": "round-rectangle", |
|
|
"width": "40px", |
|
|
"height": "40px", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".fact", |
|
|
"style": { |
|
|
"background-color": COLORS["fact"], |
|
|
"shape": "diamond", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".reasoning", |
|
|
"style": { |
|
|
"background-color": COLORS["reasoning"], |
|
|
"shape": "ellipse", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".hypothesis", |
|
|
"style": { |
|
|
"background-color": COLORS["hypothesis"], |
|
|
"shape": "hexagon", |
|
|
"width": "38px", |
|
|
"height": "38px", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".conclusion", |
|
|
"style": { |
|
|
"background-color": COLORS["conclusion"], |
|
|
"shape": "star", |
|
|
"width": "45px", |
|
|
"height": "45px", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".evidence", |
|
|
"style": { |
|
|
"background-color": COLORS["evidence"], |
|
|
"shape": "rectangle", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".constraint", |
|
|
"style": { |
|
|
"background-color": COLORS["constraint"], |
|
|
"shape": "triangle", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": ".ghost", |
|
|
"style": { |
|
|
"background-color": COLORS["ghost"], |
|
|
"opacity": 0.5, |
|
|
"border-style": "dashed", |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
{ |
|
|
"selector": "[type = 'supports']", |
|
|
"style": { |
|
|
"line-color": COLORS["edge_supports"], |
|
|
"target-arrow-color": COLORS["edge_supports"], |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": "[type = 'contradicts']", |
|
|
"style": { |
|
|
"line-color": COLORS["edge_contradicts"], |
|
|
"target-arrow-color": COLORS["edge_contradicts"], |
|
|
"line-style": "dashed", |
|
|
} |
|
|
}, |
|
|
{ |
|
|
"selector": "[type = 'alternative']", |
|
|
"style": { |
|
|
"line-color": COLORS["edge_alternative"], |
|
|
"target-arrow-color": COLORS["edge_alternative"], |
|
|
"line-style": "dotted", |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
{ |
|
|
"selector": ":selected", |
|
|
"style": { |
|
|
"border-width": "3px", |
|
|
"border-color": "#ffffff", |
|
|
"background-opacity": 1, |
|
|
} |
|
|
}, |
|
|
|
|
|
|
|
|
{ |
|
|
"selector": "node:active", |
|
|
"style": { |
|
|
"overlay-opacity": 0.2, |
|
|
"overlay-color": "#ffffff", |
|
|
} |
|
|
}, |
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
LAYOUT_CONFIGS = { |
|
|
"hierarchical": { |
|
|
"name": "dagre", |
|
|
"rankDir": "TB", |
|
|
"nodeSep": 50, |
|
|
"rankSep": 70, |
|
|
"edgeSep": 20, |
|
|
"animate": True, |
|
|
"animationDuration": 300, |
|
|
}, |
|
|
"force": { |
|
|
"name": "cose", |
|
|
"animate": True, |
|
|
"animationDuration": 500, |
|
|
"nodeRepulsion": 8000, |
|
|
"idealEdgeLength": 80, |
|
|
"edgeElasticity": 100, |
|
|
"gravity": 0.5, |
|
|
}, |
|
|
"radial": { |
|
|
"name": "concentric", |
|
|
"animate": True, |
|
|
"animationDuration": 300, |
|
|
"minNodeSpacing": 50, |
|
|
"levelWidth": 2, |
|
|
}, |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
NODE_DESCRIPTIONS = { |
|
|
"query": { |
|
|
"icon": "❓", |
|
|
"name": "Query", |
|
|
"color": COLORS["query"], |
|
|
"description": "Your input question or symptom description", |
|
|
}, |
|
|
"fact": { |
|
|
"icon": "📋", |
|
|
"name": "Fact", |
|
|
"color": COLORS["fact"], |
|
|
"description": "Verified medical fact from knowledge base", |
|
|
}, |
|
|
"reasoning": { |
|
|
"icon": "🔍", |
|
|
"name": "Reasoning", |
|
|
"color": COLORS["reasoning"], |
|
|
"description": "Logical inference step connecting evidence", |
|
|
}, |
|
|
"hypothesis": { |
|
|
"icon": "💡", |
|
|
"name": "Hypothesis", |
|
|
"color": COLORS["hypothesis"], |
|
|
"description": "Potential diagnosis being considered", |
|
|
}, |
|
|
"conclusion": { |
|
|
"icon": "✅", |
|
|
"name": "Conclusion", |
|
|
"color": COLORS["conclusion"], |
|
|
"description": "Final diagnostic conclusion or recommendation", |
|
|
}, |
|
|
"evidence": { |
|
|
"icon": "📊", |
|
|
"name": "Evidence", |
|
|
"color": COLORS["evidence"], |
|
|
"description": "Supporting evidence from medical literature", |
|
|
}, |
|
|
"constraint": { |
|
|
"icon": "⚠️", |
|
|
"name": "Constraint", |
|
|
"color": COLORS["constraint"], |
|
|
"description": "Limitation or warning in the reasoning", |
|
|
}, |
|
|
"ghost": { |
|
|
"icon": "👻", |
|
|
"name": "Ghost", |
|
|
"color": COLORS["ghost"], |
|
|
"description": "Pruned reasoning path (can be resurrected)", |
|
|
}, |
|
|
} |
|
|
|
|
|
|
|
|
def create_legend_items() -> List[Dict[str, str]]: |
|
|
"""Create legend items for UI.""" |
|
|
return [ |
|
|
{"label": desc["name"], "color": desc["color"], "description": desc["description"]} |
|
|
for desc in NODE_DESCRIPTIONS.values() |
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
CUSTOM_CSS = """ |
|
|
/* Chat container */ |
|
|
.chat-container { |
|
|
scrollbar-width: thin; |
|
|
scrollbar-color: #475569 #1e293b; |
|
|
} |
|
|
|
|
|
.chat-container::-webkit-scrollbar { |
|
|
width: 6px; |
|
|
} |
|
|
|
|
|
.chat-container::-webkit-scrollbar-track { |
|
|
background: #1e293b; |
|
|
} |
|
|
|
|
|
.chat-container::-webkit-scrollbar-thumb { |
|
|
background-color: #475569; |
|
|
border-radius: 3px; |
|
|
} |
|
|
|
|
|
/* Message styling */ |
|
|
.message { |
|
|
padding: 8px 12px; |
|
|
margin-bottom: 8px; |
|
|
border-radius: 8px; |
|
|
font-size: 0.9rem; |
|
|
line-height: 1.5; |
|
|
} |
|
|
|
|
|
.message-user { |
|
|
background-color: #1e3a5f; |
|
|
border-left: 3px solid #38bdf8; |
|
|
} |
|
|
|
|
|
.message-assistant { |
|
|
background-color: #1e293b; |
|
|
border-left: 3px solid #818cf8; |
|
|
} |
|
|
|
|
|
.message-error { |
|
|
background-color: #450a0a; |
|
|
border-left: 3px solid #f87171; |
|
|
} |
|
|
|
|
|
/* Status dot */ |
|
|
.status-dot { |
|
|
width: 8px; |
|
|
height: 8px; |
|
|
border-radius: 50%; |
|
|
display: inline-block; |
|
|
margin-right: 6px; |
|
|
} |
|
|
|
|
|
.status-dot.active { |
|
|
background-color: #4ade80; |
|
|
} |
|
|
|
|
|
.status-dot.inactive { |
|
|
background-color: #f87171; |
|
|
} |
|
|
|
|
|
/* Quick action buttons */ |
|
|
.quick-action-btn { |
|
|
background-color: #334155; |
|
|
border: 1px solid #475569; |
|
|
color: #e2e8f0; |
|
|
border-radius: 16px; |
|
|
padding: 4px 12px; |
|
|
font-size: 0.8rem; |
|
|
transition: all 0.2s; |
|
|
} |
|
|
|
|
|
.quick-action-btn:hover { |
|
|
background-color: #475569; |
|
|
color: #f8fafc; |
|
|
} |
|
|
|
|
|
/* Node detail box */ |
|
|
.node-detail { |
|
|
background-color: #0f172a; |
|
|
border: 1px solid #475569; |
|
|
border-radius: 8px; |
|
|
padding: 12px; |
|
|
} |
|
|
|
|
|
/* Content preview */ |
|
|
.content-preview { |
|
|
background-color: #0f172a; |
|
|
border-radius: 4px; |
|
|
padding: 8px; |
|
|
margin-top: 8px; |
|
|
} |
|
|
|
|
|
/* Feedback buttons */ |
|
|
.feedback-btn { |
|
|
transition: all 0.2s; |
|
|
} |
|
|
|
|
|
.feedback-btn.correct:not(:disabled):hover { |
|
|
background-color: #22c55e; |
|
|
} |
|
|
|
|
|
.feedback-btn.incorrect:not(:disabled):hover { |
|
|
background-color: #ef4444; |
|
|
} |
|
|
|
|
|
/* Legend */ |
|
|
.legend-container { |
|
|
display: flex; |
|
|
flex-wrap: wrap; |
|
|
justify-content: center; |
|
|
gap: 8px; |
|
|
} |
|
|
|
|
|
.legend-item { |
|
|
display: flex; |
|
|
align-items: center; |
|
|
padding: 2px 8px; |
|
|
background-color: #1e293b; |
|
|
border-radius: 12px; |
|
|
cursor: help; |
|
|
} |
|
|
|
|
|
.legend-dot { |
|
|
width: 10px; |
|
|
height: 10px; |
|
|
border-radius: 50%; |
|
|
margin-right: 6px; |
|
|
} |
|
|
|
|
|
/* Card styling */ |
|
|
.card { |
|
|
border-radius: 8px; |
|
|
} |
|
|
|
|
|
.card-header { |
|
|
padding: 12px 16px; |
|
|
border-bottom: 1px solid #475569; |
|
|
} |
|
|
|
|
|
.card-body { |
|
|
padding: 16px; |
|
|
} |
|
|
|
|
|
/* Slider styling */ |
|
|
.rc-slider-rail { |
|
|
background-color: #334155; |
|
|
} |
|
|
|
|
|
.rc-slider-track { |
|
|
background-color: #818cf8; |
|
|
} |
|
|
|
|
|
.rc-slider-handle { |
|
|
border-color: #818cf8; |
|
|
} |
|
|
|
|
|
/* Dropdown styling */ |
|
|
.Select-control { |
|
|
background-color: #334155 !important; |
|
|
border-color: #475569 !important; |
|
|
} |
|
|
|
|
|
.Select-value-label { |
|
|
color: #f8fafc !important; |
|
|
} |
|
|
|
|
|
.Select-menu-outer { |
|
|
background-color: #1e293b !important; |
|
|
} |
|
|
""" |
|
|
|