Inicia integrar Anzograph
This commit is contained in:
47
src/App.tsx
47
src/App.tsx
@@ -6,6 +6,7 @@ export default function App() {
|
||||
const rendererRef = useRef<Renderer | null>(null);
|
||||
const [status, setStatus] = useState("Loading node positions…");
|
||||
const [nodeCount, setNodeCount] = useState(0);
|
||||
const uriMapRef = useRef<Map<number, { uri: string; label: string; isPrimary: boolean }>>(new Map());
|
||||
const [stats, setStats] = useState({
|
||||
fps: 0,
|
||||
drawn: 0,
|
||||
@@ -14,7 +15,7 @@ export default function App() {
|
||||
ptSize: 0,
|
||||
});
|
||||
const [error, setError] = useState("");
|
||||
const [hoveredNode, setHoveredNode] = useState<{ x: number; y: number; screenX: number; screenY: number } | null>(null);
|
||||
const [hoveredNode, setHoveredNode] = useState<{ x: number; y: number; screenX: number; screenY: number; index?: number } | null>(null);
|
||||
const [selectedNodes, setSelectedNodes] = useState<Set<number>>(new Set());
|
||||
|
||||
// Store mouse position in a ref so it can be accessed in render loop without re-renders
|
||||
@@ -39,19 +40,21 @@ export default function App() {
|
||||
(async () => {
|
||||
try {
|
||||
setStatus("Fetching data files…");
|
||||
const [nodesResponse, primaryEdgesResponse, secondaryEdgesResponse] = await Promise.all([
|
||||
const [nodesResponse, primaryEdgesResponse, secondaryEdgesResponse, uriMapResponse] = await Promise.all([
|
||||
fetch("/node_positions.csv"),
|
||||
fetch("/primary_edges.csv"),
|
||||
fetch("/secondary_edges.csv"),
|
||||
fetch("/uri_map.csv"),
|
||||
]);
|
||||
if (!nodesResponse.ok) throw new Error(`Failed to fetch nodes: ${nodesResponse.status}`);
|
||||
if (!primaryEdgesResponse.ok) throw new Error(`Failed to fetch primary edges: ${primaryEdgesResponse.status}`);
|
||||
if (!secondaryEdgesResponse.ok) throw new Error(`Failed to fetch secondary edges: ${secondaryEdgesResponse.status}`);
|
||||
|
||||
const [nodesText, primaryEdgesText, secondaryEdgesText] = await Promise.all([
|
||||
const [nodesText, primaryEdgesText, secondaryEdgesText, uriMapText] = await Promise.all([
|
||||
nodesResponse.text(),
|
||||
primaryEdgesResponse.text(),
|
||||
secondaryEdgesResponse.text(),
|
||||
uriMapResponse.ok ? uriMapResponse.text() : Promise.resolve(""),
|
||||
]);
|
||||
if (cancelled) return;
|
||||
|
||||
@@ -90,6 +93,21 @@ export default function App() {
|
||||
edgeData[idx++] = parseInt(parts[1], 10);
|
||||
}
|
||||
|
||||
// Parse URI map if available
|
||||
if (uriMapText) {
|
||||
const uriLines = uriMapText.split("\n").slice(1).filter(l => l.trim().length > 0);
|
||||
for (const line of uriLines) {
|
||||
const parts = line.split(",");
|
||||
if (parts.length >= 4) {
|
||||
const id = parseInt(parts[0], 10);
|
||||
const uri = parts[1];
|
||||
const label = parts[2];
|
||||
const isPrimary = parts[3].trim() === "1";
|
||||
uriMapRef.current.set(id, { uri, label, isPrimary });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cancelled) return;
|
||||
|
||||
setStatus("Building spatial index…");
|
||||
@@ -182,9 +200,9 @@ export default function App() {
|
||||
frameCount++;
|
||||
|
||||
// Find hovered node using quadtree
|
||||
const node = renderer.findNodeAt(mousePos.current.x, mousePos.current.y);
|
||||
if (node) {
|
||||
setHoveredNode({ ...node, screenX: mousePos.current.x, screenY: mousePos.current.y });
|
||||
const nodeResult = renderer.findNodeIndexAt(mousePos.current.x, mousePos.current.y);
|
||||
if (nodeResult) {
|
||||
setHoveredNode({ x: nodeResult.x, y: nodeResult.y, screenX: mousePos.current.x, screenY: mousePos.current.y, index: nodeResult.index });
|
||||
} else {
|
||||
setHoveredNode(null);
|
||||
}
|
||||
@@ -331,7 +349,22 @@ export default function App() {
|
||||
boxShadow: "0 2px 8px rgba(0,0,0,0.5)",
|
||||
}}
|
||||
>
|
||||
({hoveredNode.x.toFixed(2)}, {hoveredNode.y.toFixed(2)})
|
||||
{(() => {
|
||||
if (hoveredNode.index !== undefined && rendererRef.current) {
|
||||
const vertexId = rendererRef.current.getVertexId(hoveredNode.index);
|
||||
const info = vertexId !== undefined ? uriMapRef.current.get(vertexId) : undefined;
|
||||
if (info) {
|
||||
return (
|
||||
<>
|
||||
<div style={{ fontWeight: "bold", marginBottom: 2 }}>{info.label}</div>
|
||||
<div style={{ fontSize: "10px", color: "#8cf", wordBreak: "break-all", maxWidth: 400 }}>{info.uri}</div>
|
||||
{info.isPrimary && <div style={{ color: "#ff0", fontSize: "10px", marginTop: 2 }}>⭐ Primary (rdf:type)</div>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
return <>({hoveredNode.x.toFixed(2)}, {hoveredNode.y.toFixed(2)})</>;
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user