File size: 3,770 Bytes
ef4c917 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | import type { NodeTypeVisibility, NodeTypeSizes, GraphStage } from '../types';
import { NODE_TYPES, NODE_COLORS, NODE_TYPE_LABELS } from '../constants';
interface Props {
visibility: NodeTypeVisibility;
onToggle: (type: string) => void;
nodeSizes: NodeTypeSizes;
onNodeSizeChange: (type: string, size: number) => void;
showEdges: boolean;
onEdgesToggle: () => void;
showFloorplan: boolean;
onFloorplanToggle: () => void;
floorplanOpacity: number;
onFloorplanOpacityChange: (v: number) => void;
hasFloorplan: boolean;
graphStage: GraphStage;
onGraphStageChange: (stage: GraphStage) => void;
hasPrePruning: boolean;
}
export default function VisualControls({
visibility,
onToggle,
nodeSizes,
onNodeSizeChange,
showEdges,
onEdgesToggle,
showFloorplan,
onFloorplanToggle,
floorplanOpacity,
onFloorplanOpacityChange,
hasFloorplan,
graphStage,
onGraphStageChange,
hasPrePruning,
}: Props) {
return (
<div className="panel">
<h3>Visual Controls</h3>
{hasPrePruning && (
<>
<label className="stage-label">Graph Stage</label>
<div className="stage-toggle">
<button
className={`stage-btn${graphStage === 'post_pruning' ? ' active' : ''}`}
onClick={() => onGraphStageChange('post_pruning')}
>
Post-Pruning
</button>
<button
className={`stage-btn${graphStage === 'pre_pruning' ? ' active' : ''}`}
onClick={() => onGraphStageChange('pre_pruning')}
>
Pre-Pruning
</button>
</div>
<hr className="stat-divider" />
</>
)}
<label className="stage-label">Node Types & Sizes</label>
{NODE_TYPES.map((type) => (
<div className="type-control-group" key={type}>
<div className="type-toggle">
<label>
<input
type="checkbox"
checked={visibility[type] !== false}
onChange={() => onToggle(type)}
/>
<span className="type-swatch" style={{ backgroundColor: NODE_COLORS[type] }} />
{NODE_TYPE_LABELS[type]}
</label>
</div>
<div className="size-slider">
<input
type="range"
min={4}
max={60}
value={nodeSizes[type] || 20}
onChange={(e) => onNodeSizeChange(type, Number(e.target.value))}
/>
<span className="size-value">{nodeSizes[type] || 20}</span>
</div>
</div>
))}
<hr className="stat-divider" />
<div className="type-toggle">
<label>
<input type="checkbox" checked={showEdges} onChange={onEdgesToggle} />
Show Edges
</label>
</div>
{hasFloorplan && (
<>
<div className="type-toggle">
<label>
<input
type="checkbox"
checked={showFloorplan}
onChange={onFloorplanToggle}
/>
Show Floorplan Background
</label>
</div>
{showFloorplan && (
<div className="size-slider opacity-slider">
<span className="opacity-label">Opacity</span>
<input
type="range"
min={0}
max={100}
value={Math.round(floorplanOpacity * 100)}
onChange={(e) => onFloorplanOpacityChange(Number(e.target.value) / 100)}
/>
<span className="size-value">{Math.round(floorplanOpacity * 100)}%</span>
</div>
)}
</>
)}
</div>
);
}
|