feat: refactoring
This commit is contained in:
98
frontend/src/components/browse/buildGraph.ts
Normal file
98
frontend/src/components/browse/buildGraph.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
import type { NetworkNode } from "@/api/client";
|
||||
import { statusRGBA, type RGBA, type StatusColors } from "./graphColors";
|
||||
|
||||
export const SPACE_SIZE = 4096;
|
||||
const CENTER = SPACE_SIZE / 2;
|
||||
|
||||
export interface BuiltGraph {
|
||||
entries: NetworkNode[];
|
||||
positions: Float32Array;
|
||||
colors: Float32Array;
|
||||
sizes: Float32Array;
|
||||
clusterIndices: (number | undefined)[];
|
||||
clusterPositions: (number | undefined)[];
|
||||
clusterStrength: Float32Array;
|
||||
clusterNames: string[];
|
||||
hashToIndex: Map<string, number>;
|
||||
}
|
||||
|
||||
function findParentIface(
|
||||
entry: NetworkNode,
|
||||
interfaces: NetworkNode[],
|
||||
peerIndex: number,
|
||||
): string | undefined {
|
||||
if (entry.interface) {
|
||||
const iface = interfaces.find(i => i.name === entry.interface);
|
||||
if (iface) return iface.hash;
|
||||
}
|
||||
if (interfaces.length > 0) return interfaces[peerIndex % interfaces.length].hash;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function buildGraphArrays(
|
||||
rawNodes: NetworkNode[],
|
||||
prevHashToIndex: Map<string, number>,
|
||||
prevPositions: number[],
|
||||
theme: StatusColors,
|
||||
): BuiltGraph {
|
||||
const interfaces = rawNodes.filter(e => e.type === "interface").sort((a, b) => a.name.localeCompare(b.name));
|
||||
const selfNode = rawNodes.find(e => e.is_self && e.type !== "interface");
|
||||
const peers = rawNodes.filter(e => !e.is_self && e.type !== "interface");
|
||||
|
||||
const entries = selfNode ? [selfNode, ...peers] : peers;
|
||||
const selfIndex = selfNode ? 0 : -1;
|
||||
const n = entries.length;
|
||||
const nClusters = interfaces.length;
|
||||
const hashToIndex = new Map<string, number>();
|
||||
const positions = new Float32Array(n * 2);
|
||||
const colors = new Float32Array(n * 4);
|
||||
const sizes = new Float32Array(n);
|
||||
const clusterIndices: (number | undefined)[] = [];
|
||||
const clusterStrength = new Float32Array(n);
|
||||
|
||||
const clusterMap = new Map<string, number>();
|
||||
interfaces.forEach((iface, i) => clusterMap.set(iface.name, i));
|
||||
const selfClusterIndex = interfaces.length;
|
||||
|
||||
const clusterNames = [...interfaces.map(i => i.name), ...(selfNode ? [selfNode.name] : [])];
|
||||
const clusterPositions: (number | undefined)[] = [];
|
||||
|
||||
entries.forEach((entry, i) => {
|
||||
hashToIndex.set(entry.hash, i);
|
||||
|
||||
// Preserve existing position, or jitter near center for new points
|
||||
const prevIdx = prevHashToIndex.get(entry.hash);
|
||||
if (prevIdx !== undefined && prevPositions.length >= (prevIdx + 1) * 2) {
|
||||
positions[i * 2] = prevPositions[prevIdx * 2]!;
|
||||
positions[i * 2 + 1] = prevPositions[prevIdx * 2 + 1]!;
|
||||
} else {
|
||||
positions[i * 2] = CENTER + (Math.random() - 0.5) * SPACE_SIZE * 0.5;
|
||||
positions[i * 2 + 1] = CENTER + (Math.random() - 0.5) * SPACE_SIZE * 0.5;
|
||||
}
|
||||
|
||||
// Self node = bright white, others by status
|
||||
const rgba: RGBA = i === selfIndex
|
||||
? [1, 1, 1, 1]
|
||||
: statusRGBA(entry, theme);
|
||||
colors[i * 4 + 0] = rgba[0];
|
||||
colors[i * 4 + 1] = rgba[1];
|
||||
colors[i * 4 + 2] = rgba[2];
|
||||
colors[i * 4 + 3] = rgba[3];
|
||||
|
||||
sizes[i] = 3;
|
||||
|
||||
// Cluster assignment
|
||||
if (i === selfIndex) {
|
||||
clusterIndices.push(selfClusterIndex);
|
||||
} else {
|
||||
const pi = peers.indexOf(entry);
|
||||
const parentHash = findParentIface(entry, interfaces, pi);
|
||||
const parentName = parentHash ? interfaces.find(f => f.hash === parentHash)?.name : undefined;
|
||||
clusterIndices.push(parentName !== undefined ? clusterMap.get(parentName) : undefined);
|
||||
}
|
||||
|
||||
clusterStrength[i] = nClusters > 1 ? (nClusters - (i % nClusters)) / nClusters : 1;
|
||||
});
|
||||
|
||||
return { entries, positions, colors, sizes, clusterIndices, clusterPositions, clusterStrength, clusterNames, hashToIndex };
|
||||
}
|
||||
Reference in New Issue
Block a user