diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 68d240d..04d4971 100644 Binary files a/__pycache__/app.cpython-313.pyc and b/__pycache__/app.cpython-313.pyc differ diff --git a/__pycache__/models.cpython-313.pyc b/__pycache__/models.cpython-313.pyc index 2c27178..cbe731e 100644 Binary files a/__pycache__/models.cpython-313.pyc and b/__pycache__/models.cpython-313.pyc differ diff --git a/app.py b/app.py index b477fce..a2546d3 100644 --- a/app.py +++ b/app.py @@ -22,7 +22,7 @@ from dotenv import load_dotenv from models import ( db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating, RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote, - node_thought_association, user_thought_bookmark + node_thought_association, user_thought_bookmark, node_relationship ) # Lade .env-Datei @@ -903,45 +903,30 @@ def delete_note(note_id): @app.route('/api/mindmap') def get_mindmap(): """API-Endpunkt zur Bereitstellung der Mindmap-Daten in hierarchischer Form.""" - # Alle root-Nodes (ohne parent) abrufen - root_nodes = MindMapNode.query.filter_by(parent_id=None).all() - - if not root_nodes: - # Wenn keine Nodes existieren, rufen wir initialize_database direkt auf - # anstatt create_sample_mindmap zu verwenden - with app.app_context(): - initialize_database() - root_nodes = MindMapNode.query.filter_by(parent_id=None).all() - - # Ergebnisse in hierarchischer Struktur zurückgeben + # Root-Knoten: Knoten ohne Eltern + root_nodes = MindMapNode.query.\ + outerjoin(node_relationship, MindMapNode.id == node_relationship.c.child_id).\ + filter(node_relationship.c.parent_id == None).all() + result = [] - for node in root_nodes: node_data = build_node_tree(node) result.append(node_data) - return jsonify({"nodes": result}) def build_node_tree(node): """Erzeugt eine hierarchische Darstellung eines Knotens inkl. seiner Kindknoten.""" - # Gedankenzähler abrufen von der many-to-many Beziehung thought_count = len(node.thoughts) - - # Daten für aktuellen Knoten node_data = { "id": node.id, "name": node.name, - "description": f"Knoten mit {thought_count} Gedanken", + "description": node.description or "", "thought_count": thought_count, "children": [] } - - # Rekursiv Kinder hinzufügen - child_nodes = MindMapNode.query.filter_by(parent_id=node.id).all() - for child_node in child_nodes: - child_data = build_node_tree(child_node) + for child in node.children: + child_data = build_node_tree(child) node_data["children"].append(child_data) - return node_data @app.route('/api/nodes//thoughts') @@ -1250,7 +1235,7 @@ def chat_with_assistant(): # Zusammenfassen mehrerer Gedanken oder Analyse anfordern system_message = ( - "Du bist ein hilfreicher Assistent, der Zugriff auf die Wissensdatenbank hat. " + "Du bist ein hilfreicher Assistent, der Zugriff auf die Wissensdatenbank hat. Du antwortest nur auf Fragen bezüglich Systades und der Wissensdatenbank. " "Du kannst Informationen zu Gedanken, Kategorien und Mindmaps liefern. " "Antworte informativ, sachlich und gut strukturiert auf Deutsch." ) diff --git a/database/__pycache__/models.cpython-313.pyc b/database/__pycache__/models.cpython-313.pyc new file mode 100644 index 0000000..78b3d6a Binary files /dev/null and b/database/__pycache__/models.cpython-313.pyc differ diff --git a/instance/systades.db b/instance/systades.db new file mode 100644 index 0000000..e69de29 diff --git a/static/js/main.js b/static/js/main.js index a1a8de7..50e9b4a 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -7,15 +7,6 @@ * Verwaltet die globale Anwendungslogik */ -document.addEventListener('DOMContentLoaded', function() { - // Initialisiere die Anwendung - MindMap.init(); - - // Wende Dunkel-/Hellmodus an - const isDarkMode = localStorage.getItem('darkMode') === 'dark'; - document.documentElement.classList.toggle('dark', isDarkMode); -}); - /** * Hauptobjekt der MindMap-Anwendung */ @@ -24,7 +15,7 @@ const MindMap = { initialized: false, darkMode: document.documentElement.classList.contains('dark'), pageInitializers: {}, - currentPage: document.body.dataset.page, + currentPage: null, /** * Initialisiert die MindMap-Anwendung @@ -32,6 +23,9 @@ const MindMap = { init() { if (this.initialized) return; + // Setze currentPage erst jetzt, wenn DOM garantiert geladen ist + this.currentPage = document.body && document.body.dataset ? document.body.dataset.page : null; + console.log('MindMap-Anwendung wird initialisiert...'); // Initialisiere den ChatGPT-Assistenten @@ -229,6 +223,13 @@ const MindMap = { }); } }; +window.MindMap = MindMap; -// Globale Export für andere Module -window.MindMap = MindMap; \ No newline at end of file +document.addEventListener('DOMContentLoaded', function() { + // Initialisiere die Anwendung + MindMap.init(); + + // Wende Dunkel-/Hellmodus an + const isDarkMode = localStorage.getItem('darkMode') === 'dark'; + document.documentElement.classList.toggle('dark', isDarkMode); +}); \ No newline at end of file diff --git a/static/js/modules/mindmap-page.js b/static/js/modules/mindmap-page.js index f00ae14..a543504 100644 --- a/static/js/modules/mindmap-page.js +++ b/static/js/modules/mindmap-page.js @@ -14,9 +14,18 @@ if (window.MindMap) { window.MindMap.pageInitializers.mindmap = initMindmapPage; } +// Initialisiere die Mindmap-Seite nur, wenn alle Abhängigkeiten vorhanden sind +if (window.MindMap && typeof MindMapVisualization !== 'undefined') { + if (document.body && document.body.dataset && document.body.dataset.page === 'mindmap') { + window.MindMap.pageInitializers = window.MindMap.pageInitializers || {}; + window.MindMap.pageInitializers.mindmap = initMindmapPage; + initMindmapPage(); + } +} + document.addEventListener('DOMContentLoaded', function() { // Prüfe, ob wir auf der Mindmap-Seite sind und initialisiere - if (document.body.dataset.page === 'mindmap') { + if (document.body && document.body.dataset && document.body.dataset.page === 'mindmap') { initMindmapPage(); } }); diff --git a/static/js/modules/mindmap.js b/static/js/modules/mindmap.js index 427545c..0dfc9db 100644 --- a/static/js/modules/mindmap.js +++ b/static/js/modules/mindmap.js @@ -818,6 +818,26 @@ class MindMapVisualization { this.updateNodeAppearance(d.id, isBookmarked); }); } + + /** + * Gibt alle direkt verbundenen Knoten eines Knotens zurück + * @param {Object} node - Der Knoten, für den die Verbindungen gesucht werden + * @returns {Array} Array der verbundenen Knotenobjekte + */ + getConnectedNodes(node) { + if (!node || !this.links || !this.nodes) return []; + const nodeId = node.id; + const connectedIds = new Set(); + this.links.forEach(link => { + if (link.source === nodeId || (link.source && link.source.id === nodeId)) { + connectedIds.add(link.target.id ? link.target.id : link.target); + } + if (link.target === nodeId || (link.target && link.target.id === nodeId)) { + connectedIds.add(link.source.id ? link.source.id : link.source); + } + }); + return this.nodes.filter(n => connectedIds.has(n.id)); + } } // Exportiere die Klasse für die Verwendung in anderen Modulen diff --git a/static/neural-network-background.js b/static/neural-network-background.js index b1b0521..3cb5eb3 100644 --- a/static/neural-network-background.js +++ b/static/neural-network-background.js @@ -68,18 +68,18 @@ class NeuralNetworkBackground { // Config - Drastisch verstärkt für strahlende Animationen und neuronale Vernetzung this.config = { - nodeCount: 120, // Viel mehr Knoten für ein dichtes Netzwerk - nodeSize: 1.4, // Größere Knoten für mehr Sichtbarkeit - nodeVariation: 0.6, // Mehr Variation für organisches Aussehen - connectionDistance: 220, // Deutlich längere Verbindungen für mehr Vernetzung - connectionOpacity: 0.4, // Wesentlich stärkere Verbindungen - animationSpeed: 0.08, // Schnellere Bewegung - pulseSpeed: 0.006, // Schnelleres Pulsieren für lebendiges Aussehen - flowSpeed: 0.8, // Schnellere Flussanimationen - flowDensity: 0.005, // Viel mehr Flussanimationen - flowLength: 0.25, // Längere Flussanimationen - maxConnections: 6, // NEW: Neue Eigenschaft für mehr neuronale Verbindungen pro Knoten - clusteringFactor: 0.3 // NEW: Erzeugt Cluster wie in einem neuronalen Netzwerk + nodeCount: 120, // Anzahl der Knoten bleibt hoch für Netzwerkstruktur + nodeSize: 1.1, // Dezenter: kleinere Knoten + nodeVariation: 0.4, // Weniger Variation für ruhigeres Bild + connectionDistance: 220, // Unverändert: gute Vernetzung + connectionOpacity: 0.18, // Deutlich dezentere Verbindungen + animationSpeed: 0.05, // Ruhigere Bewegung + pulseSpeed: 0.004, // Ruhigeres Pulsieren + flowSpeed: 1.2, // Flows schneller für flüssigere Aktivität + flowDensity: 0.012, // Mehr Flows für sichtbare Aktivität + flowLength: 0.32, // Flows länger sichtbar + maxConnections: 5, // Weniger Überlagerung + clusteringFactor: 0.35 // Mehr Cluster für neuronalen Effekt }; // Initialize @@ -335,17 +335,17 @@ class NeuralNetworkBackground { if (!this.connections.some(conn => (conn.from === i && conn.to === j) || (conn.from === j && conn.to === i) )) { - // Create connection + // Neue Verbindung startet mit progress=0 für animierten Aufbau this.connections.push({ from: i, to: j, distance: distance, opacity: connOpacity, strength: connectionStrength, - hasFlow: false, // Each connection can have a flow - lastActivated: 0 // For neural firing animation + hasFlow: false, + lastActivated: 0, + progress: 0 // Animationsfortschritt für Verbindungsaufbau }); - nodeA.connections.push(j); nodeB.connections.push(i); } @@ -406,6 +406,15 @@ class NeuralNetworkBackground { } } + // Animierter Verbindungsaufbau: progress inkrementieren + for (const connection of this.connections) { + if (connection.progress < 1) { + // Langsamer Aufbau: Geschwindigkeit kann angepasst werden + connection.progress += 0.012; // Sehr langsam, für subtilen Effekt + if (connection.progress > 1) connection.progress = 1; + } + } + // Update flows this.updateFlows(); @@ -515,21 +524,8 @@ class NeuralNetworkBackground { positions[i * 2] = node.x; positions[i * 2 + 1] = node.y; - // Enhanced pulse effect with additional boost for active nodes - let pulse = Math.sin(node.pulsePhase) * 0.4 + 1; - - // Make active nodes pulse more intensely (neural firing effect) - if (node.isActive) { - const timeSinceFired = now - node.lastFired; - if (timeSinceFired < 300) { - // Quick expand then contract effect - const normalizedTime = timeSinceFired / 300; - const fireBoost = 1.5 * (1 - normalizedTime); - pulse += fireBoost; - } - } - - // Nodes with more connections are larger (hub neurons) + // Sichtbarkeit der Neuronen erhöhen + let pulse = Math.sin(node.pulsePhase) * 0.22 + 1.08; const connectivityFactor = 1 + (node.connections.length / this.config.maxConnections) * 0.8; sizes[i] = node.size * pulse * connectivityFactor; } @@ -585,10 +581,11 @@ class NeuralNetworkBackground { b = (b + nodePulseColor.b / 255) / 2; } + // Sehr sichtbare Knoten this.gl.uniform4f( this.programInfo.uniformLocations.color, r, g, b, - 0.95 // Higher opacity for maximum visibility + node.isActive ? 0.98 : 0.8 // Sehr sichtbar ); // Draw each node individually for better control @@ -598,50 +595,40 @@ class NeuralNetworkBackground { renderConnectionsWebGL() { const now = Date.now(); - - // For each connection, draw a line for (const connection of this.connections) { const fromNode = this.nodes[connection.from]; const toNode = this.nodes[connection.to]; - - // Line positions + // Animierter Verbindungsaufbau: nur Teil der Linie zeichnen + const progress = connection.progress || 1; + const x1 = fromNode.x; + const y1 = fromNode.y; + const x2 = x1 + (toNode.x - x1) * progress; + const y2 = y1 + (toNode.y - y1) * progress; const positions = new Float32Array([ - fromNode.x, fromNode.y, - toNode.x, toNode.y + x1, y1, + x2, y2 ]); - - // Bind position buffer this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer); this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW); this.gl.vertexAttribPointer( this.programInfo.attribLocations.vertexPosition, - 2, // components per vertex - this.gl.FLOAT, // data type - false, // normalize - 0, // stride - 0 // offset + 2, + this.gl.FLOAT, + false, + 0, + 0 ); this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition); - - // Disable point size attribute for lines this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize); - - // Set line color with connection opacity const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; let lineColor = this.hexToRgb(colorObj.connectionColor); - - // Highlight recently activated connections for neural pathway effect - let opacity = connection.opacity * 1.4; // Base increased visibility - + // Sehr dezente Grundopazität + let opacity = connection.opacity * 0.7; if (now - connection.lastActivated < 800) { - // Make recently activated connections brighter lineColor = this.hexToRgb(colorObj.flowColor); - - // Fade out effect const timeFactor = 1 - ((now - connection.lastActivated) / 800); - opacity = Math.max(opacity, timeFactor * 0.9); + opacity = Math.max(opacity, timeFactor * 0.32); } - this.gl.uniform4f( this.programInfo.uniformLocations.color, lineColor.r / 255, @@ -649,11 +636,8 @@ class NeuralNetworkBackground { lineColor.b / 255, opacity ); - - // Draw the line - this.gl.enable(this.gl.BLEND); - this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE); - this.gl.lineWidth(1); + // Sehr dünne Linien + this.gl.lineWidth(0.5); this.gl.drawArrays(this.gl.LINES, 0, 2); } } @@ -730,18 +714,18 @@ class NeuralNetworkBackground { // Flow color - much stronger glow const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors; const flowColor = this.hexToRgb(colorObj.flowColor); + + // Flows mit sanftem, aber sichtbarem Glow und höherer Opazität this.gl.uniform4f( this.programInfo.uniformLocations.color, flowColor.r / 255, flowColor.g / 255, flowColor.b / 255, - 0.9 * fadeOpacity * flow.intensity // Much stronger flow opacity with intensity variation + 0.55 * fadeOpacity * (flow.intensity || 1) // Dezenter, aber sichtbar ); - // Draw the flow line - this.gl.enable(this.gl.BLEND); - this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE); - this.gl.lineWidth(2.5); // Even thicker for dramatic visibility + // Dünnere Flows für subtilen Effekt + this.gl.lineWidth(1.2); this.gl.drawArrays(this.gl.LINES, 0, 2); } } @@ -769,13 +753,19 @@ class NeuralNetworkBackground { for (const connection of this.connections) { const fromNode = this.nodes[connection.from]; const toNode = this.nodes[connection.to]; - + // Animierter Verbindungsaufbau: nur Teil der Linie zeichnen + const progress = connection.progress || 1; + const x1 = fromNode.x; + const y1 = fromNode.y; + const x2 = x1 + (toNode.x - x1) * progress; + const y2 = y1 + (toNode.y - y1) * progress; this.ctx.beginPath(); - this.ctx.moveTo(fromNode.x, fromNode.y); - this.ctx.lineTo(toNode.x, toNode.y); - + this.ctx.moveTo(x1, y1); + this.ctx.lineTo(x2, y2); const rgbColor = this.hexToRgb(connectionColor); - this.ctx.strokeStyle = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${connection.opacity})`; + // Sehr dezente Opazität + this.ctx.strokeStyle = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${connection.opacity * 0.7})`; + this.ctx.lineWidth = 0.5; this.ctx.stroke(); } @@ -792,33 +782,22 @@ class NeuralNetworkBackground { : this.lightModeColors.nodePulse; for (const node of this.nodes) { - // Node with subtle glow effect - const pulse = Math.sin(node.pulsePhase) * 0.2 + 1; - const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.3 : 1); - - // Glow effect + // Sichtbarkeit der Neuronen erhöhen + const pulse = Math.sin(node.pulsePhase) * 0.18 + 1.08; // Leicht erhöhte Amplitude + const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.22 : 1); const glow = this.ctx.createRadialGradient( node.x, node.y, 0, - node.x, node.y, nodeSize * 2 + node.x, node.y, nodeSize * 2.2 ); - - const rgbNodeColor = this.hexToRgb(nodeColor); - const rgbPulseColor = this.hexToRgb(nodePulse); - - glow.addColorStop(0, `rgba(${rgbPulseColor.r}, ${rgbPulseColor.g}, ${rgbPulseColor.b}, 0.6)`); - glow.addColorStop(0.5, `rgba(${rgbNodeColor.r}, ${rgbNodeColor.g}, ${rgbNodeColor.b}, 0.2)`); - glow.addColorStop(1, `rgba(${rgbNodeColor.r}, ${rgbNodeColor.g}, ${rgbNodeColor.b}, 0)`); - - this.ctx.beginPath(); - this.ctx.arc(node.x, node.y, nodeSize * 2, 0, Math.PI * 2); - this.ctx.fillStyle = glow; - this.ctx.fill(); - - // Main node + glow.addColorStop(0, `rgba(${nodePulse.r}, ${nodePulse.g}, ${nodePulse.b}, 0.52)`); + glow.addColorStop(0.5, `rgba(${nodeColor.r}, ${nodeColor.g}, ${nodeColor.b}, 0.22)`); + glow.addColorStop(1, `rgba(${nodeColor.r}, ${nodeColor.g}, ${nodeColor.b}, 0)`); this.ctx.beginPath(); this.ctx.arc(node.x, node.y, nodeSize, 0, Math.PI * 2); - this.ctx.fillStyle = nodeColor; + this.ctx.fillStyle = glow; + this.ctx.globalAlpha = node.isActive ? 0.95 : 0.7; // Sehr sichtbar this.ctx.fill(); + this.ctx.globalAlpha = 1.0; } } @@ -876,12 +855,12 @@ class NeuralNetworkBackground { 1 ); - // Draw flow + // Dezente Flows mit sanftem Fade-Out this.ctx.beginPath(); this.ctx.moveTo(p1.x, p1.y); this.ctx.lineTo(p2.x, p2.y); - this.ctx.strokeStyle = `rgba(${rgbFlowColor.r}, ${rgbFlowColor.g}, ${rgbFlowColor.b}, ${0.4 * fadeOpacity})`; - this.ctx.lineWidth = 1.5; + this.ctx.strokeStyle = `rgba(${rgbFlowColor.r}, ${rgbFlowColor.g}, ${rgbFlowColor.b}, ${0.28 * fadeOpacity})`; + this.ctx.lineWidth = 1.1; this.ctx.stroke(); } } diff --git a/systades.db b/systades.db new file mode 100644 index 0000000..e69de29 diff --git a/templates/base.html b/templates/base.html index 180005e..14a8411 100644 --- a/templates/base.html +++ b/templates/base.html @@ -14,11 +14,12 @@ - + + + + \ No newline at end of file diff --git a/templates/mindmap.html b/templates/mindmap.html index 1711c7f..83923a7 100644 --- a/templates/mindmap.html +++ b/templates/mindmap.html @@ -391,7 +391,7 @@
-
+
diff --git a/utils/__pycache__/__init__.cpython-313.pyc b/utils/__pycache__/__init__.cpython-313.pyc index 032f9c9..fb28d80 100644 Binary files a/utils/__pycache__/__init__.cpython-313.pyc and b/utils/__pycache__/__init__.cpython-313.pyc differ diff --git a/utils/__pycache__/db_check.cpython-313.pyc b/utils/__pycache__/db_check.cpython-313.pyc index d3bf2ad..2489e33 100644 Binary files a/utils/__pycache__/db_check.cpython-313.pyc and b/utils/__pycache__/db_check.cpython-313.pyc differ diff --git a/utils/__pycache__/db_fix.cpython-313.pyc b/utils/__pycache__/db_fix.cpython-313.pyc index a3db687..7ee884d 100644 Binary files a/utils/__pycache__/db_fix.cpython-313.pyc and b/utils/__pycache__/db_fix.cpython-313.pyc differ diff --git a/utils/__pycache__/db_rebuild.cpython-313.pyc b/utils/__pycache__/db_rebuild.cpython-313.pyc index 8e4ac13..979e135 100644 Binary files a/utils/__pycache__/db_rebuild.cpython-313.pyc and b/utils/__pycache__/db_rebuild.cpython-313.pyc differ diff --git a/utils/__pycache__/db_test.cpython-313.pyc b/utils/__pycache__/db_test.cpython-313.pyc index 098065f..2be7b9b 100644 Binary files a/utils/__pycache__/db_test.cpython-313.pyc and b/utils/__pycache__/db_test.cpython-313.pyc differ diff --git a/utils/__pycache__/server.cpython-313.pyc b/utils/__pycache__/server.cpython-313.pyc index e7a51f4..47a8b31 100644 Binary files a/utils/__pycache__/server.cpython-313.pyc and b/utils/__pycache__/server.cpython-313.pyc differ diff --git a/utils/__pycache__/user_manager.cpython-313.pyc b/utils/__pycache__/user_manager.cpython-313.pyc index 398b652..3f36b2c 100644 Binary files a/utils/__pycache__/user_manager.cpython-313.pyc and b/utils/__pycache__/user_manager.cpython-313.pyc differ diff --git a/venv/pyvenv.cfg b/venv/pyvenv.cfg index 7d60b7d..413b9e0 100644 --- a/venv/pyvenv.cfg +++ b/venv/pyvenv.cfg @@ -1,5 +1,5 @@ -home = /usr/bin +home = C:\Program Files\Python313 include-system-site-packages = false -version = 3.11.2 -executable = /usr/bin/python3.11 -command = /usr/bin/python3.11 -m venv /home/core/dev/website/venv +version = 3.13.3 +executable = C:\Program Files\Python313\python.exe +command = C:\Program Files\Python313\python.exe -m venv C:\Users\TTOMCZA.EMEA\Dev\website\venv