/** * Update Mindmap * Dieses Skript fügt Knoten zur Mindmap hinzu und stellt sicher, * dass sie im neuronalen Netzwerk-Design angezeigt werden. * Implementiert Lazy Loading & Progressive Disclosure */ // Mock-Datenbank für Subthemen (später durch echte DB-Abfragen ersetzen) const subthemesDatabase = { 'philosophy': [ { id: 'epistemology', label: 'Erkenntnistheorie', category: 'Philosophie', description: 'Untersuchung der Natur und Grenzen menschlicher Erkenntnis', hasChildren: true }, { id: 'ethics', label: 'Ethik', category: 'Philosophie', description: 'Lehre vom moralisch richtigen Handeln', hasChildren: true }, { id: 'metaphysics', label: 'Metaphysik', category: 'Philosophie', description: 'Grundfragen des Seins und der Wirklichkeit', hasChildren: true } ], 'science': [ { id: 'physics', label: 'Physik', category: 'Wissenschaft', description: 'Lehre von der Materie und ihren Wechselwirkungen', hasChildren: true }, { id: 'biology', label: 'Biologie', category: 'Wissenschaft', description: 'Lehre von den Lebewesen und ihren Lebensprozessen', hasChildren: true }, { id: 'chemistry', label: 'Chemie', category: 'Wissenschaft', description: 'Wissenschaft von den Stoffen und ihren Reaktionen', hasChildren: true } ], 'technology': [ { id: 'ai', label: 'Künstliche Intelligenz', category: 'Technologie', description: 'Maschinelles Lernen und intelligente Systeme', hasChildren: true }, { id: 'robotics', label: 'Robotik', category: 'Technologie', description: 'Entwicklung und Steuerung von Robotern', hasChildren: true }, { id: 'quantum_computing', label: 'Quantencomputing', category: 'Technologie', description: 'Computer basierend auf Quantenmechanik', hasChildren: true } ], 'arts': [ { id: 'visual_arts', label: 'Bildende Kunst', category: 'Künste', description: 'Malerei, Bildhauerei und andere visuelle Kunstformen', hasChildren: true }, { id: 'music', label: 'Musik', category: 'Künste', description: 'Tonkunst und musikalische Komposition', hasChildren: true }, { id: 'literature', label: 'Literatur', category: 'Künste', description: 'Schriftliche Kunstwerke und Poesie', hasChildren: true } ] }; // Initiale Mindmap-Daten (nur oberste Ebene) const mindmapData = { nodes: [ { id: 'philosophy', label: 'Philosophie', category: 'Philosophie', description: 'Die Lehre vom Denken und der Erkenntnis', hasChildren: true, expanded: false, neuronSize: 8, neuronActivity: 0.8 }, { id: 'science', label: 'Wissenschaft', category: 'Wissenschaft', description: 'Systematische Erforschung der Natur und Gesellschaft', hasChildren: true, expanded: false, neuronSize: 8, neuronActivity: 0.8 }, { id: 'technology', label: 'Technologie', category: 'Technologie', description: 'Anwendung wissenschaftlicher Erkenntnisse', hasChildren: true, expanded: false, neuronSize: 8, neuronActivity: 0.8 }, { id: 'arts', label: 'Künste', category: 'Künste', description: 'Kreativer Ausdruck und künstlerische Gestaltung', hasChildren: true, expanded: false, neuronSize: 8, neuronActivity: 0.8 } ], edges: [ { source: 'philosophy', target: 'science', strength: 0.8 }, { source: 'science', target: 'technology', strength: 0.8 }, { source: 'technology', target: 'arts', strength: 0.6 }, { source: 'arts', target: 'philosophy', strength: 0.6 }, { source: 'philosophy', target: 'technology', strength: 0.4 }, { source: 'science', target: 'arts', strength: 0.4 } ] }; // Warte bis DOM geladen ist document.addEventListener('DOMContentLoaded', function() { console.log('DOMContentLoaded Event ausgelöst'); // Prüfe, ob der Container existiert const cyContainer = document.getElementById('cy'); console.log('Container gefunden:', cyContainer); if (!cyContainer) { console.error('Mindmap-Container #cy nicht gefunden!'); return; } // Prüfe, ob Cytoscape verfügbar ist if (typeof cytoscape === 'undefined') { console.error('Cytoscape ist nicht definiert!'); return; } console.log('Cytoscape ist verfügbar'); // Beispiel-Daten entfernt, stattdessen große Mindmap-Daten verwenden const elements = [ // Knoten ...mindmapData.nodes.map(node => ({ data: { id: node.id, label: node.label, category: node.category, description: node.description, hasChildren: node.hasChildren, expanded: node.expanded, neuronSize: node.neuronSize, neuronActivity: node.neuronActivity } })), // Kanten ...mindmapData.edges.map(edge => ({ data: { source: edge.source, target: edge.target, label: edge.label, strength: edge.strength } })) ]; console.log('Initialisiere Cytoscape...'); // Initialisiere Cytoscape mit neuronalem Design window.cy = cytoscape({ container: cyContainer, elements: elements, style: [ { selector: 'node', style: { 'background-color': 'data(color)', 'label': 'data(label)', 'color': '#fff', 'text-background-color': 'rgba(0, 0, 0, 0.7)', 'text-background-opacity': 0.8, 'text-background-padding': '4px', 'text-valign': 'center', 'text-halign': 'center', 'font-size': 16, 'width': 'mapData(neuronSize, 3, 10, 30, 60)', 'height': 'mapData(neuronSize, 3, 10, 30, 60)', 'border-width': 2, 'border-color': '#fff', 'border-opacity': 0.8, 'overlay-padding': 4, 'z-index': 10, 'shape': 'ellipse', 'background-opacity': 0.85, 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 10, 20)', 'shadow-color': 'data(color)', 'shadow-opacity': 0.6, 'shadow-offset-x': 0, 'shadow-offset-y': 0 } }, { selector: 'node[!color]', style: { 'background-color': '#60a5fa' } }, { selector: 'node:selected', style: { 'border-color': '#f59e42', 'border-width': 4, 'shadow-blur': 30, 'shadow-opacity': 0.8 } }, { selector: 'edge', style: { 'width': 'mapData(strength, 0.2, 1, 1, 3)', 'line-color': '#a78bfa', 'line-opacity': 'mapData(strength, 0.2, 1, 0.4, 0.8)', 'target-arrow-color': '#a78bfa', 'target-arrow-shape': 'none', 'curve-style': 'bezier', 'control-point-distances': [20, -20], 'control-point-weights': [0.5, 0.5], 'edge-distances': 'intersection', 'loop-direction': '-45deg', 'loop-sweep': '-90deg', 'line-style': function(ele) { const strength = ele.data('strength'); if (strength <= 0.4) return 'dotted'; if (strength <= 0.6) return 'dashed'; return 'solid'; } } }, { selector: 'edge:selected', style: { 'width': 5, 'line-color': '#f59e42', 'target-arrow-color': '#f59e42', 'opacity': 1, 'line-style': 'solid' } } ], layout: { name: 'cose', animate: true, animationDuration: 1000, nodeDimensionsIncludeLabels: true, padding: 100, spacingFactor: 1.8, randomize: false, fit: true, componentSpacing: 100, nodeRepulsion: 8000, edgeElasticity: 100, animate: true } }); console.log('Cytoscape initialisiert'); // Füge neuronale Eigenschaften zu allen Knoten hinzu cy.nodes().forEach(node => { const data = node.data(); node.data({ ...data, neuronSize: data.neuronSize || 8, neuronActivity: data.neuronActivity || 0.8, refractionPeriod: Math.random() * 300 + 700, threshold: Math.random() * 0.3 + 0.6, lastFired: 0, color: categoryColors[data.category] || '#60a5fa' }); }); // Füge synaptische Eigenschaften zu allen Kanten hinzu cy.edges().forEach(edge => { const data = edge.data(); edge.data({ ...data, strength: data.strength || 0.5, conductionVelocity: Math.random() * 0.5 + 0.3, latency: Math.random() * 100 + 50 }); }); // Starte neuronale Aktivitätssimulation startNeuralActivitySimulation(cy); // Mindmap mit echten Daten befüllen (Styles, Farben etc.) updateMindmap(); // Event auslösen, damit andere Scripte reagieren können document.dispatchEvent(new Event('mindmap-loaded')); console.log('mindmap-loaded Event ausgelöst'); // Event-Listener für Knoten-Klicks cy.on('tap', 'node', async function(evt) { const node = evt.target; console.log('Node clicked:', node.id(), 'hasChildren:', node.data('hasChildren'), 'expanded:', node.data('expanded')); if (node.data('hasChildren') && !node.data('expanded')) { await loadSubthemes(node); } }); }); // Kategorie-Farben definieren const categoryColors = { 'Philosophie': '#60a5fa', 'Wissenschaft': '#8b5cf6', 'Technologie': '#10b981', 'Künste': '#f59e0b', 'Psychologie': '#ef4444' }; // Funktion zum Initialisieren des neuronalen Designs function initializeNeuralDesign(cy) { // Füge neuronale Eigenschaften zu allen Knoten hinzu cy.nodes().forEach(node => { const data = node.data(); node.data({ ...data, neuronSize: data.neuronSize || 8, neuronActivity: data.neuronActivity || 0.8, refractionPeriod: Math.random() * 300 + 700, threshold: Math.random() * 0.3 + 0.6, lastFired: 0, color: categoryColors[data.category] || '#60a5fa' }); }); // Füge synaptische Eigenschaften zu allen Kanten hinzu cy.edges().forEach(edge => { const data = edge.data(); edge.data({ ...data, strength: data.strength || 0.5, conductionVelocity: Math.random() * 0.5 + 0.3, latency: Math.random() * 100 + 50 }); }); // Wende neuronales Styling an cy.style() .selector('node') .style({ 'background-color': 'data(color)', 'label': 'data(label)', 'color': '#fff', 'text-background-color': 'rgba(0, 0, 0, 0.7)', 'text-background-opacity': 0.8, 'text-background-padding': '4px', 'text-valign': 'center', 'text-halign': 'center', 'font-size': 16, 'width': 'mapData(neuronSize, 3, 10, 30, 60)', 'height': 'mapData(neuronSize, 3, 10, 30, 60)', 'border-width': 2, 'border-color': '#fff', 'border-opacity': 0.8, 'overlay-padding': 4, 'z-index': 10, 'shape': 'ellipse', 'background-opacity': 0.85, 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 10, 20)', 'shadow-color': 'data(color)', 'shadow-opacity': 0.6, 'shadow-offset-x': 0, 'shadow-offset-y': 0 }) .selector('edge') .style({ 'width': 'mapData(strength, 0.2, 1, 1, 3)', 'line-color': '#a78bfa', 'line-opacity': 'mapData(strength, 0.2, 1, 0.4, 0.8)', 'target-arrow-color': '#a78bfa', 'target-arrow-shape': 'none', 'curve-style': 'bezier', 'control-point-distances': [20, -20], 'control-point-weights': [0.5, 0.5], 'edge-distances': 'intersection', 'loop-direction': '-45deg', 'loop-sweep': '-90deg', 'line-style': function(ele) { const strength = ele.data('strength'); if (strength <= 0.4) return 'dotted'; if (strength <= 0.6) return 'dashed'; return 'solid'; } }) .update(); // Starte neuronale Aktivitätssimulation startNeuralActivitySimulation(cy); } // Modifiziere die updateMindmap Funktion function updateMindmap() { if (!cy) return; // Bestehende Elemente entfernen cy.elements().remove(); // Neue Knoten hinzufügen mindmapData.nodes.forEach(node => { cy.add({ group: 'nodes', data: { id: node.id, label: node.label, category: node.category, description: node.description, hasChildren: node.hasChildren, expanded: node.expanded, neuronSize: node.neuronSize, neuronActivity: node.neuronActivity } }); }); // Neue Kanten hinzufügen mindmapData.edges.forEach(edge => { cy.add({ group: 'edges', data: { source: edge.source, target: edge.target, strength: edge.strength } }); }); // Neuronales Design initialisieren initializeNeuralDesign(cy); // Layout anwenden cy.layout({ name: 'cose', animate: true, animationDuration: 1000, nodeDimensionsIncludeLabels: true, padding: 100, spacingFactor: 1.8, randomize: false, fit: true, componentSpacing: 100, nodeRepulsion: 8000, edgeElasticity: 100, nestingFactor: 1.2, gravity: 80 }).run(); } /** * Erweitert die Mindmap mit dem neuronalen Netzwerk-Design */ function enhanceMindmap() { // Auf die bestehende Cytoscape-Instanz zugreifen const cy = window.cy; if (!cy) { console.error('Keine Cytoscape-Instanz gefunden.'); return; } // Aktualisiere das Layout für eine bessere Verteilung cy.layout({ name: 'cose', animate: true, animationDuration: 1800, nodeDimensionsIncludeLabels: true, padding: 100, spacingFactor: 1.8, randomize: false, fit: true, componentSpacing: 100, nodeRepulsion: 8000, edgeElasticity: 100, nestingFactor: 1.2, gravity: 80 }).run(); // Neuronen-Namen mit besserer Lesbarkeit umgestalten cy.style() .selector('node') .style({ 'text-background-color': 'rgba(10, 14, 25, 0.7)', 'text-background-opacity': 0.7, 'text-background-padding': '2px', 'text-border-opacity': 0.2, 'text-border-width': 1, 'text-border-color': '#8b5cf6' }) .update(); // Sicherstellen, dass alle Knoten Neuronen-Eigenschaften haben cy.nodes().forEach(node => { if (!node.data('neuronSize')) { const neuronSize = Math.floor(Math.random() * 8) + 3; node.data('neuronSize', neuronSize); } if (!node.data('neuronActivity')) { const neuronActivity = Math.random() * 0.7 + 0.3; node.data('neuronActivity', neuronActivity); } // Zusätzliche Neuronale Eigenschaften node.data('pulseFrequency', Math.random() * 4 + 2); // Pulsfrequenz (2-6 Hz) node.data('refractionPeriod', Math.random() * 300 + 700); // Refraktionszeit (700-1000ms) node.data('threshold', Math.random() * 0.3 + 0.6); // Aktivierungsschwelle (0.6-0.9) }); // Sicherstellen, dass alle Kanten Synapse-Eigenschaften haben cy.edges().forEach(edge => { if (!edge.data('strength')) { const strength = Math.random() * 0.6 + 0.2; edge.data('strength', strength); } // Zusätzliche synaptische Eigenschaften edge.data('conductionVelocity', Math.random() * 0.5 + 0.3); // Leitungsgeschwindigkeit (0.3-0.8) edge.data('latency', Math.random() * 100 + 50); // Signalverzögerung (50-150ms) }); // Neuronales Netzwerk-Stil anwenden applyNeuralNetworkStyle(cy); console.log('Mindmap wurde erfolgreich im neuronalen Netzwerk-Stil aktualisiert'); // Spezielle Effekte für das neuronale Netzwerk hinzufügen startNeuralActivitySimulation(cy); } /** * Wendet detaillierte neuronale Netzwerkstile auf die Mindmap an * @param {Object} cy - Cytoscape-Instanz */ function applyNeuralNetworkStyle(cy) { // Wende erweiterte Stile für Neuronen und Synapsen an cy.style() .selector('node') .style({ 'label': 'data(name)', 'text-valign': 'bottom', 'text-halign': 'center', 'color': '#ffffff', 'text-outline-width': 1.5, 'text-outline-color': '#0a0e19', 'text-outline-opacity': 0.9, 'font-size': 10, 'text-margin-y': 7, 'width': 'mapData(neuronSize, 3, 10, 15, 40)', 'height': 'mapData(neuronSize, 3, 10, 15, 40)', 'background-color': 'data(color)', 'background-opacity': 0.85, 'border-width': 0, 'shape': 'ellipse', 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 5, 15)', 'shadow-color': 'data(color)', 'shadow-opacity': 0.6, 'shadow-offset-x': 0, 'shadow-offset-y': 0 }) .selector('edge') .style({ 'width': 'mapData(strength, 0.2, 0.8, 0.7, 2)', 'curve-style': 'bezier', 'line-color': '#8a8aaa', 'line-opacity': 'mapData(strength, 0.2, 0.8, 0.4, 0.7)', 'line-style': function(ele) { const strength = ele.data('strength'); if (strength <= 0.4) return 'dotted'; if (strength <= 0.6) return 'dashed'; return 'solid'; }, 'target-arrow-shape': 'none', 'source-endpoint': '0% 50%', 'target-endpoint': '100% 50%' }) .selector('node[isRoot]') .style({ 'font-size': 12, 'font-weight': 'bold', 'width': 50, 'height': 50, 'background-color': '#6366f1', 'shadow-blur': 20, 'shadow-color': '#6366f1', 'shadow-opacity': 0.8, 'text-margin-y': 8 }) .update(); } /** * Simuliert neuronale Aktivität in der Mindmap * @param {Object} cy - Cytoscape-Instanz */ function startNeuralActivitySimulation(cy) { if (window.neuralInterval) clearInterval(window.neuralInterval); const nodes = cy.nodes(); const edges = cy.edges(); let currentTime = Date.now(); // Neuronale Aktivität simulieren function simulateNeuralActivity() { currentTime = Date.now(); // Zufällige Neuronen "feuern" lassen nodes.forEach(node => { const data = node.data(); const lastFired = data.lastFired || 0; const timeSinceLastFire = currentTime - lastFired; // Prüfen ob Neuron feuern kann (Refraktionsperiode) if (timeSinceLastFire > data.refractionPeriod) { // Zufälliges Feuern basierend auf Aktivität if (Math.random() < data.neuronActivity * 0.1) { fireNeuron(node, true, currentTime); } } }); } // Neuron feuern lassen function fireNeuron(node, state, currentTime) { const data = node.data(); data.lastFired = currentTime; // Visuelles Feedback node.style({ 'background-opacity': 1, 'shadow-blur': 25, 'shadow-opacity': 0.9 }); // Nach kurzer Zeit zurück zum Normalzustand setTimeout(() => { node.style({ 'background-opacity': 0.85, 'shadow-blur': 18, 'shadow-opacity': 0.6 }); }, 200); // Signal weiterleiten if (state) { propagateSignal(node, currentTime); } } // Signal über Kanten weiterleiten function propagateSignal(sourceNode, currentTime) { const outgoingEdges = sourceNode.connectedEdges('out'); outgoingEdges.forEach(edge => { const targetNode = edge.target(); const edgeData = edge.data(); const latency = edgeData.latency; // Signal mit Verzögerung weiterleiten setTimeout(() => { const targetData = targetNode.data(); const timeSinceLastFire = currentTime - (targetData.lastFired || 0); // Prüfen ob Zielneuron feuern kann if (timeSinceLastFire > targetData.refractionPeriod) { // Signalstärke berechnen const signalStrength = edgeData.strength * edgeData.conductionVelocity * sourceNode.data('neuronActivity'); // Neuron feuern lassen wenn Signal stark genug if (signalStrength > targetData.threshold) { fireNeuron(targetNode, true, currentTime + latency); } } }, latency); }); } // Simulation starten window.neuralInterval = setInterval(simulateNeuralActivity, 100); } // 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 = `