diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index b1146c1..1615f6a 100644 Binary files a/__pycache__/app.cpython-313.pyc and b/__pycache__/app.cpython-313.pyc differ diff --git a/app.py b/app.py index 414eb22..cb16aca 100644 --- a/app.py +++ b/app.py @@ -1142,32 +1142,64 @@ def delete_note(note_id): # API routes for mindmap and thoughts @app.route('/api/mindmap') def get_mindmap(): - """API-Endpunkt zur Bereitstellung der Mindmap-Daten in hierarchischer Form.""" - # 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.""" - thought_count = len(node.thoughts) - node_data = { - "id": node.id, - "name": node.name, - "description": node.description or "", - "thought_count": thought_count, - "children": [] - } - for child in node.children: - child_data = build_node_tree(child) - node_data["children"].append(child_data) - return node_data + """Gibt die Mindmap-Struktur zurück""" + try: + # Hauptknoten abrufen (Root-Knoten) + wissen_node = MindMapNode.query.filter_by(name="Wissen").first() + if not wissen_node: + # Wissen-Knoten erstellen, falls nicht vorhanden + wissen_node = MindMapNode( + name="Wissen", + description="Zentrale Wissensbasis", + color_code="#4299E1", + is_public=True + ) + db.session.add(wissen_node) + db.session.commit() + + # Alle anderen aktiven Knoten holen + nodes = MindMapNode.query.filter(MindMapNode.is_public == True).all() + + # Ergebnisdaten vorbereiten + nodes_data = [] + edges_data = [] + + # Knoten hinzufügen + for node in nodes: + nodes_data.append({ + 'id': node.id, + 'name': node.name, + 'description': node.description or '', + 'color_code': node.color_code or '#9F7AEA' + }) + + # Wenn es nicht der Wissen-Knoten ist, Verbindung zum Wissen-Knoten hinzufügen + if node.id != wissen_node.id: + edges_data.append({ + 'source': wissen_node.id, + 'target': node.id + }) + + # Beziehungen zwischen Knoten abfragen und hinzufügen + relationships = db.session.query(node_relationship).all() + for rel in relationships: + if rel.parent_id != wissen_node.id: # Doppelte Kanten vermeiden + edges_data.append({ + 'source': rel.parent_id, + 'target': rel.child_id + }) + + return jsonify({ + 'nodes': nodes_data, + 'edges': edges_data + }) + + except Exception as e: + print(f"Fehler beim Abrufen der Mindmap: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Mindmap konnte nicht geladen werden' + }), 500 @app.route('/api/nodes//thoughts') def get_node_thoughts(node_id): diff --git a/database/systades.db b/database/systades.db index 13acef9..1d9c4d5 100644 Binary files a/database/systades.db and b/database/systades.db differ diff --git a/db_operations.py b/db_operations.py new file mode 100644 index 0000000..3534a72 --- /dev/null +++ b/db_operations.py @@ -0,0 +1,103 @@ +import sqlite3 +import os +import random + +# Verbindung zur Datenbank herstellen +db_path = os.path.join(os.getcwd(), 'database', 'systades.db') +conn = sqlite3.connect(db_path) +cursor = conn.cursor() + +# Schema der mind_map_node Tabelle anzeigen +cursor.execute("PRAGMA table_info(mind_map_node)") +columns = cursor.fetchall() +print("Tabellenschema mind_map_node:") +for column in columns: + print(f"{column[1]} ({column[2]})") + +# Existierende Knoten anzeigen +cursor.execute("SELECT id, name, description, color_code FROM mind_map_node LIMIT 5") +existing_nodes = cursor.fetchall() +print("\nBestehende Knoten:") +for node in existing_nodes: + print(f"ID: {node[0]}, Name: {node[1]}, Beschreibung: {node[2]}") + +# Mögliche Kategorien abrufen (für die Verknüpfung) +cursor.execute("SELECT id, name FROM category") +categories = cursor.fetchall() +print("\nVerfügbare Kategorien:") +for category in categories: + print(f"ID: {category[0]}, Name: {category[1]}") + +# Wissenschaftliche Themengebiete für neue Knoten +scientific_nodes = [ + { + "name": "Quantenphysik", + "description": "Die Quantenphysik befasst sich mit dem Verhalten von Materie und Energie auf atomarer und subatomarer Ebene.", + "color_code": "#4B0082", # Indigo + "icon": "fa-atom" + }, + { + "name": "Neurowissenschaften", + "description": "Interdisziplinäre Wissenschaft, die sich mit der Struktur und Funktion des Nervensystems und des Gehirns beschäftigt.", + "color_code": "#FF4500", # Orange-Rot + "icon": "fa-brain" + }, + { + "name": "Künstliche Intelligenz", + "description": "Forschungsgebiet der Informatik, das sich mit der Automatisierung intelligenten Verhaltens befasst.", + "color_code": "#008080", # Teal + "icon": "fa-robot" + }, + { + "name": "Klimaforschung", + "description": "Wissenschaftliche Untersuchung des Klimas, seiner Variationen und Veränderungen auf allen zeitlichen und räumlichen Skalen.", + "color_code": "#2E8B57", # Seegrün + "icon": "fa-cloud-sun" + }, + { + "name": "Genetik", + "description": "Teilgebiet der Biologie, das sich mit Vererbung sowie der Funktion und Wirkung von Genen beschäftigt.", + "color_code": "#800080", # Lila + "icon": "fa-dna" + }, + { + "name": "Astrophysik", + "description": "Zweig der Astronomie, der sich mit den physikalischen Eigenschaften des Universums befasst.", + "color_code": "#191970", # Mitternachtsblau + "icon": "fa-star" + } +] + +# Neue Knoten hinzufügen +print("\nFüge neue wissenschaftliche Knoten hinzu...") +for node in scientific_nodes: + # Prüfen, ob der Knoten bereits existiert + cursor.execute("SELECT id FROM mind_map_node WHERE name = ?", (node["name"],)) + existing = cursor.fetchone() + if existing: + print(f"Knoten '{node['name']}' existiert bereits mit ID {existing[0]}") + continue + + # Zufällige Kategorie wählen, wenn vorhanden + category_id = None + if categories: + category_id = random.choice(categories)[0] + + # Neuen Knoten einfügen + cursor.execute(""" + INSERT INTO mind_map_node (name, description, color_code, icon, is_public, category_id) + VALUES (?, ?, ?, ?, ?, ?) + """, ( + node["name"], + node["description"], + node["color_code"], + node["icon"], + True, + category_id + )) + print(f"Knoten '{node['name']}' hinzugefügt") + +# Änderungen übernehmen und Verbindung schließen +conn.commit() +print("\nDatenbank erfolgreich aktualisiert!") +conn.close() \ No newline at end of file diff --git a/static/js/update_mindmap.js b/static/js/update_mindmap.js new file mode 100644 index 0000000..be81ba7 --- /dev/null +++ b/static/js/update_mindmap.js @@ -0,0 +1,93 @@ +/** + * Update Mindmap + * Dieses Skript fügt die neuen wissenschaftlichen Knoten zur Mindmap hinzu + * und stellt sicher, dass sie korrekt angezeigt werden. + */ + +// Warte bis DOM geladen ist +document.addEventListener('DOMContentLoaded', function() { + // Prüfe, ob wir auf der Mindmap-Seite sind + const cyContainer = document.getElementById('cy'); + + if (!cyContainer) { + console.log('Kein Mindmap-Container gefunden, überspringe Initialisierung.'); + return; + } + + // Auf das Laden der Mindmap warten + document.addEventListener('mindmap-loaded', function() { + console.log('Mindmap geladen, füge wissenschaftliche Knoten hinzu...'); + enhanceMindmap(); + }); +}); + +/** + * Erweitert die Mindmap mit den neu hinzugefügten wissenschaftlichen Knoten + */ +function enhanceMindmap() { + // Auf die bestehende Cytoscape-Instanz zugreifen + const cy = window.cy; + + if (!cy) { + console.error('Keine Cytoscape-Instanz gefunden.'); + return; + } + + // Aktualisiere das Layout mit zusätzlichem Platz für die neuen Knoten + cy.layout({ + name: 'cose', + animate: true, + animationDuration: 800, + nodeDimensionsIncludeLabels: true, + padding: 100, + spacingFactor: 1.8, + randomize: false, + fit: true + }).run(); + + console.log('Mindmap wurde erfolgreich aktualisiert!'); + + // Wenn ein Wissen-Knoten existiert, sicherstellen, dass er im Zentrum ist + const rootNode = cy.getElementById('1'); + if (rootNode.length > 0) { + cy.center(rootNode); + } +} + +// Hilfe-Funktion zum Hinzufügen eines Flash-Hinweises +function showFlash(message, type = 'info') { + const flashContainer = document.getElementById('flash-messages') || createFlashContainer(); + + const flashMsg = document.createElement('div'); + flashMsg.className = `flash-message flash-${type} mb-2 p-3 rounded`; + flashMsg.innerHTML = ` +
+
${message}
+ +
+ `; + + flashContainer.appendChild(flashMsg); + + // Nach 5 Sekunden automatisch ausblenden + setTimeout(() => { + flashMsg.style.opacity = '0'; + setTimeout(() => flashMsg.remove(), 300); + }, 5000); + + // Close-Button + const closeBtn = flashMsg.querySelector('.close-flash'); + closeBtn.addEventListener('click', () => { + flashMsg.style.opacity = '0'; + setTimeout(() => flashMsg.remove(), 300); + }); +} + +// Hilfsfunktion zum Erstellen eines Flash-Containers, falls keiner existiert +function createFlashContainer() { + const container = document.createElement('div'); + container.id = 'flash-messages'; + container.className = 'fixed top-4 right-4 z-50 w-64'; + document.body.appendChild(container); + return container; +} \ No newline at end of file diff --git a/templates/mindmap.html b/templates/mindmap.html index 9ea0ff9..7b7eea1 100644 --- a/templates/mindmap.html +++ b/templates/mindmap.html @@ -341,17 +341,10 @@ {% endblock %} {% block extra_js %} - - - - - - - + + + + + + {% endblock %} \ No newline at end of file