Politur: d3Force-Kollision und Quadranten-Clustering korrigiert (Zentrumskraft entfernt, starker charge-Faktor und farbkodierte Kanten)

This commit is contained in:
Hitonabi
2026-07-09 12:23:23 +02:00
parent a261462857
commit 895eb9cac7
4 changed files with 30 additions and 31 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -7,7 +7,7 @@
<link rel="manifest" href="/manifest.webmanifest" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>Mission Control 2.0</title>
<script type="module" crossorigin src="/assets/index-DNXEzn-Z.js"></script>
<script type="module" crossorigin src="/assets/index-Ch3qlJmN.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-1USExdfg.css">
</head>
<body>
+26 -27
View File
@@ -11,7 +11,7 @@ const CAT_LABEL: Record<string, string> = {
identity: "Identität", knowledge: "Wissen", rules: "Regeln", events: "Ereignisse",
}
const AUTO = new Set(["auto", "agent", "hermes"])
const EDGE_HI = "rgba(99, 102, 241, 0.85)"
const EDGE_HI = "rgba(99, 102, 241, 0.9)"
const DIM_EDGE = "rgba(255, 255, 255, 0.02)"
// Hilfsfunktion zur Konvertierung von Hex in RGBA für farbkodierte Verbindungen
@@ -68,22 +68,22 @@ export function GraphView({ data, onDelete }: { data: MemoryGraph; onDelete: (id
return d
}, [data])
// Quadranten-Fokuskoordinaten für sauberes Clustering
// Quadranten-Fokuskoordinaten für sauberes Clustering (Fokuszentren weiter auseinander gezogen)
const getClusterX = (category: string) => {
return {
identity: -160,
knowledge: 160,
rules: -160,
events: 160,
identity: -220,
knowledge: 220,
rules: -220,
events: 220,
}[category] || 0
}
const getClusterY = (category: string) => {
return {
identity: -160,
knowledge: -160,
rules: 160,
events: 160,
identity: -220,
knowledge: -220,
rules: 220,
events: 220,
}[category] || 0
}
@@ -92,26 +92,25 @@ export function GraphView({ data, onDelete }: { data: MemoryGraph; onDelete: (id
const fg = fgRef.current
if (!fg) return
// 1. Clustering-Kräfte (Knoten zu ihren jeweiligen Sektions-Foci ziehen)
fg.d3Force("x", forceX().x((node: any) => getClusterX(node.category)).strength(0.14))
fg.d3Force("y", forceY().y((node: any) => getClusterY(node.category)).strength(0.14))
// 1. Standard-Zentrumskraft entfernen (erlaubt freies Clustering in Quadranten)
fg.d3Force("center", null)
// 2. Kollisionskraft (Verhindert, dass Knoten und Textlabels ineinandergeschoben werden)
fg.d3Force("collide", forceCollide().radius((node: any) => {
const nodeDegree = degree[node.id] || 0
// Radius = Knotengröße + großzügiger Textpuffer
return 28 + Math.min(nodeDegree, 12) * 1.5
}).iterations(2))
// 2. Clustering-Kräfte (Knoten zu ihren jeweiligen Sektions-Foci ziehen)
fg.d3Force("x", forceX().x((node: any) => getClusterX(node.category)).strength(0.18))
fg.d3Force("y", forceY().y((node: any) => getClusterY(node.category)).strength(0.18))
// 3. Abstoßung (Charge) moderat, da collide und foci die Hauptarbeit leisten
// 3. Starke Abstoßung (Charge) für ein weit gefächertes, luftiges Netz
const charge = fg.d3Force("charge")
if (charge) charge.strength(-60)
if (charge) charge.strength(-240)
// 4. Federn (Links)
// 4. Kollisionskraft (Fester, sicherer Radius, verhindert Überlappung)
fg.d3Force("collide", forceCollide().radius(34).iterations(2))
// 5. Federkraft (Links)
const link = fg.d3Force("link")
if (link) link.distance(50)
if (link) link.distance(60)
// Simulation neu anschubsen bei neuen Daten
// Simulation neu starten (Reheat)
fg.d3ReheatSimulation()
}, [graphData])
@@ -191,15 +190,15 @@ export function GraphView({ data, onDelete }: { data: MemoryGraph; onDelete: (id
// Wenn ein anderer Knoten aktiv ist, blenden wir diese Kante fast komplett aus
if (activeNode) return DIM_EDGE
// Standard-Zustand: Kante leuchtet dezent in der Farbe der Kategorie des Quell-Knotens
// Standard-Zustand: Kante leuchtet in der Farbe des Quell-Clusters (deutlich sichtbar mit alpha=0.25)
const sourceNode = graphData.nodes.find(n => n.id === sId)
const catColor = sourceNode ? CAT_COLOR[sourceNode.category] : "#64748b"
return hexToRgba(catColor, 0.16)
return hexToRgba(catColor, 0.25)
}}
linkWidth={(link: any) => {
const sId = typeof link.source === "object" ? link.source.id : link.source
const tId = typeof link.target === "object" ? link.target.id : link.target
return (activeNode === sId || activeNode === tId) ? 2.5 : 1.2
return (activeNode === sId || activeNode === tId) ? 2.5 : 1.4
}}
// Daten-Partikel fließen auf den aktiven Verbindungen