Politur: d3Force-Kollision und Quadranten-Clustering korrigiert (Zentrumskraft entfernt, starker charge-Faktor und farbkodierte Kanten)
This commit is contained in:
+2
-2
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<link rel="manifest" href="/manifest.webmanifest" />
|
<link rel="manifest" href="/manifest.webmanifest" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<title>Mission Control 2.0</title>
|
<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">
|
<link rel="stylesheet" crossorigin href="/assets/index-1USExdfg.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const CAT_LABEL: Record<string, string> = {
|
|||||||
identity: "Identität", knowledge: "Wissen", rules: "Regeln", events: "Ereignisse",
|
identity: "Identität", knowledge: "Wissen", rules: "Regeln", events: "Ereignisse",
|
||||||
}
|
}
|
||||||
const AUTO = new Set(["auto", "agent", "hermes"])
|
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)"
|
const DIM_EDGE = "rgba(255, 255, 255, 0.02)"
|
||||||
|
|
||||||
// Hilfsfunktion zur Konvertierung von Hex in RGBA für farbkodierte Verbindungen
|
// 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
|
return d
|
||||||
}, [data])
|
}, [data])
|
||||||
|
|
||||||
// Quadranten-Fokuskoordinaten für sauberes Clustering
|
// Quadranten-Fokuskoordinaten für sauberes Clustering (Fokuszentren weiter auseinander gezogen)
|
||||||
const getClusterX = (category: string) => {
|
const getClusterX = (category: string) => {
|
||||||
return {
|
return {
|
||||||
identity: -160,
|
identity: -220,
|
||||||
knowledge: 160,
|
knowledge: 220,
|
||||||
rules: -160,
|
rules: -220,
|
||||||
events: 160,
|
events: 220,
|
||||||
}[category] || 0
|
}[category] || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const getClusterY = (category: string) => {
|
const getClusterY = (category: string) => {
|
||||||
return {
|
return {
|
||||||
identity: -160,
|
identity: -220,
|
||||||
knowledge: -160,
|
knowledge: -220,
|
||||||
rules: 160,
|
rules: 220,
|
||||||
events: 160,
|
events: 220,
|
||||||
}[category] || 0
|
}[category] || 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,26 +92,25 @@ export function GraphView({ data, onDelete }: { data: MemoryGraph; onDelete: (id
|
|||||||
const fg = fgRef.current
|
const fg = fgRef.current
|
||||||
if (!fg) return
|
if (!fg) return
|
||||||
|
|
||||||
// 1. Clustering-Kräfte (Knoten zu ihren jeweiligen Sektions-Foci ziehen)
|
// 1. Standard-Zentrumskraft entfernen (erlaubt freies Clustering in Quadranten)
|
||||||
fg.d3Force("x", forceX().x((node: any) => getClusterX(node.category)).strength(0.14))
|
fg.d3Force("center", null)
|
||||||
fg.d3Force("y", forceY().y((node: any) => getClusterY(node.category)).strength(0.14))
|
|
||||||
|
|
||||||
// 2. Kollisionskraft (Verhindert, dass Knoten und Textlabels ineinandergeschoben werden)
|
// 2. Clustering-Kräfte (Knoten zu ihren jeweiligen Sektions-Foci ziehen)
|
||||||
fg.d3Force("collide", forceCollide().radius((node: any) => {
|
fg.d3Force("x", forceX().x((node: any) => getClusterX(node.category)).strength(0.18))
|
||||||
const nodeDegree = degree[node.id] || 0
|
fg.d3Force("y", forceY().y((node: any) => getClusterY(node.category)).strength(0.18))
|
||||||
// Radius = Knotengröße + großzügiger Textpuffer
|
|
||||||
return 28 + Math.min(nodeDegree, 12) * 1.5
|
|
||||||
}).iterations(2))
|
|
||||||
|
|
||||||
// 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")
|
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")
|
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()
|
fg.d3ReheatSimulation()
|
||||||
}, [graphData])
|
}, [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
|
// Wenn ein anderer Knoten aktiv ist, blenden wir diese Kante fast komplett aus
|
||||||
if (activeNode) return DIM_EDGE
|
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 sourceNode = graphData.nodes.find(n => n.id === sId)
|
||||||
const catColor = sourceNode ? CAT_COLOR[sourceNode.category] : "#64748b"
|
const catColor = sourceNode ? CAT_COLOR[sourceNode.category] : "#64748b"
|
||||||
return hexToRgba(catColor, 0.16)
|
return hexToRgba(catColor, 0.25)
|
||||||
}}
|
}}
|
||||||
linkWidth={(link: any) => {
|
linkWidth={(link: any) => {
|
||||||
const sId = typeof link.source === "object" ? link.source.id : link.source
|
const sId = typeof link.source === "object" ? link.source.id : link.source
|
||||||
const tId = typeof link.target === "object" ? link.target.id : link.target
|
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
|
// Daten-Partikel fließen auf den aktiven Verbindungen
|
||||||
|
|||||||
Reference in New Issue
Block a user