Skip to content

Commit ab33409

Browse files
committed
fix: dark theme for graph view -- dark bg, subtle edges, better label density
- Set canvas background to zinc-950 (#09090b) matching our dark theme - Edges now nearly invisible (12% opacity) until hover reveals neighbors - Label density reduced so only important nodes show labels at default zoom - Hovered node gets white border glow, neighbors show labels - Non-neighbor nodes fade to 30% opacity on hover - Legend uses glass card style with backdrop blur - Added border around graph container for visual definition
1 parent 3f6ac31 commit ab33409

2 files changed

Lines changed: 49 additions & 21 deletions

File tree

frontend/src/components/DependencyGraph/GraphView/index.tsx

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,28 @@ interface GraphViewProps {
2121
onSelectFile?: (filePath: string) => void
2222
}
2323

24-
// Dark theme settings for sigma
24+
// dark theme -- bg matches zinc-950, edges nearly invisible until hover
2525
const SIGMA_SETTINGS = {
2626
defaultNodeColor: '#6366f1',
27-
defaultEdgeColor: '#374151',
27+
defaultEdgeColor: 'rgba(75, 85, 99, 0.15)',
2828
defaultEdgeType: 'arrow' as const,
29+
edgeReducer: null as any,
30+
nodeReducer: null as any,
2931
renderEdgeLabels: false,
3032
labelFont: 'Inter, system-ui, sans-serif',
31-
labelSize: 12,
32-
labelColor: { color: '#e5e7eb' },
33-
labelRenderedSizeThreshold: 8,
33+
labelSize: 11,
34+
labelWeight: '500',
35+
labelColor: { color: '#d1d5db' },
36+
// only show labels for large (important) nodes at default zoom
37+
labelRenderedSizeThreshold: 14,
38+
labelDensity: 0.15,
3439
zIndex: true,
35-
minCameraRatio: 0.05,
40+
minCameraRatio: 0.03,
3641
maxCameraRatio: 3,
42+
stagePadding: 40,
43+
// subtle node borders
44+
defaultNodeBorderSize: 1,
45+
defaultNodeBorderColor: 'rgba(255, 255, 255, 0.08)',
3746
}
3847

3948
// Loads graph into Sigma and fits camera
@@ -43,7 +52,6 @@ function LoadAndDisplay({ graph }: { graph: Graph }) {
4352

4453
useEffect(() => {
4554
loadGraph(graph)
46-
// fit camera after graph loads
4755
requestAnimationFrame(() => {
4856
sigma.getCamera().animatedReset({ duration: 300 })
4957
})
@@ -52,7 +60,7 @@ function LoadAndDisplay({ graph }: { graph: Graph }) {
5260
return null
5361
}
5462

55-
// Handles all mouse/keyboard interactions on the graph
63+
// Handles hover/click interactions and drives node/edge reducers
5664
function Interactions({ onSelectFile }: { onSelectFile?: (filePath: string) => void }) {
5765
const sigma = useSigma()
5866
const registerEvents = useRegisterEvents()
@@ -89,7 +97,7 @@ function Interactions({ onSelectFile }: { onSelectFile?: (filePath: string) => v
8997
})
9098
}, [registerEvents, sigma, onSelectFile])
9199

92-
// highlight hovered node neighborhood, fade everything else
100+
// highlight hovered neighborhood, fade everything else
93101
useEffect(() => {
94102
const graph = sigma.getGraph()
95103

@@ -98,14 +106,32 @@ function Interactions({ onSelectFile }: { onSelectFile?: (filePath: string) => v
98106
neighbors.add(hoveredNode)
99107

100108
sigma.setSetting('nodeReducer', (node, data) => {
101-
if (neighbors.has(node)) return { ...data, zIndex: 1 }
102-
return { ...data, color: '#1f2937', label: '', zIndex: 0 }
109+
if (neighbors.has(node)) {
110+
return {
111+
...data,
112+
zIndex: 1,
113+
// show label on hover for all neighbors
114+
label: data.label,
115+
// slight glow effect via larger border
116+
borderSize: node === hoveredNode ? 3 : 1,
117+
borderColor: node === hoveredNode ? '#ffffff' : 'rgba(255,255,255,0.2)',
118+
}
119+
}
120+
// fade non-neighbors hard
121+
return {
122+
...data,
123+
color: 'rgba(31, 41, 55, 0.3)',
124+
label: '',
125+
zIndex: 0,
126+
borderSize: 0,
127+
}
103128
})
129+
104130
sigma.setSetting('edgeReducer', (edge, data) => {
105131
const src = graph.source(edge)
106132
const tgt = graph.target(edge)
107133
if (neighbors.has(src) && neighbors.has(tgt)) {
108-
return { ...data, color: '#6366f1', size: 1.5 }
134+
return { ...data, color: 'rgba(99, 102, 241, 0.6)', size: 1.5 }
109135
}
110136
return { ...data, hidden: true }
111137
})
@@ -115,7 +141,6 @@ function Interactions({ onSelectFile }: { onSelectFile?: (filePath: string) => v
115141
}
116142
}, [hoveredNode, sigma])
117143

118-
// build tooltip data from graph attributes
119144
const tooltipData = (() => {
120145
if (!tooltip) return null
121146
const graph = sigma.getGraph()
@@ -147,22 +172,23 @@ export function GraphView({ data, onSelectFile }: GraphViewProps) {
147172
}
148173

149174
return (
150-
<div className="relative h-[700px] bg-zinc-950 rounded-lg overflow-hidden">
175+
<div className="relative h-[700px] rounded-lg overflow-hidden border border-zinc-800">
151176
<SigmaContainer
152-
style={{ height: '100%', width: '100%' }}
177+
style={{ height: '100%', width: '100%', background: '#09090b' }}
153178
settings={SIGMA_SETTINGS}
154179
>
155180
<LoadAndDisplay graph={graph} />
156181
<Interactions onSelectFile={onSelectFile} />
157182
</SigmaContainer>
158183

159-
<div className="absolute bottom-4 right-4 bg-zinc-900/90 border border-zinc-700 rounded-lg p-3 text-xs">
160-
<div className="text-zinc-400 font-medium mb-2">Legend</div>
161-
<div className="space-y-1 text-zinc-500">
184+
{/* legend - glass card style */}
185+
<div className="absolute bottom-4 right-4 bg-zinc-900/80 backdrop-blur-sm border border-zinc-800 rounded-lg px-3 py-2.5 text-[11px]">
186+
<div className="text-zinc-400 font-medium mb-1.5">Legend</div>
187+
<div className="space-y-0.5 text-zinc-500">
162188
<div>Node size = dependents count</div>
163-
<div>Node color = module cluster</div>
164-
<div>Hover to highlight neighbors</div>
165-
<div>Click to analyze impact</div>
189+
<div>Color = module cluster</div>
190+
<div>Hover = highlight neighbors</div>
191+
<div>Click = impact analysis</div>
166192
</div>
167193
</div>
168194
</div>

frontend/src/components/DependencyGraph/GraphView/useGraphData.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ export function useGraphData(apiData: DependencyApiResponse | undefined) {
7171
graph.addEdge(edge.source, edge.target, {
7272
weight: 1,
7373
type: 'arrow',
74+
size: 0.5,
75+
color: 'rgba(75, 85, 99, 0.12)',
7476
})
7577
}
7678
}

0 commit comments

Comments
 (0)