From ed1d41d316b4d179f7b20cfaf5fad0ba02325ff3 Mon Sep 17 00:00:00 2001 From: marwin Date: Sat, 10 May 2025 18:18:34 +0100 Subject: [PATCH 1/6] chore: automatic commit 2025-05-10 18:18 --- database/systades.db | Bin 147456 -> 147456 bytes utils/__pycache__/db_rebuild.cpython-313.pyc | Bin 3799 -> 3809 bytes utils/__pycache__/db_test.cpython-313.pyc | Bin 5839 -> 5849 bytes utils/__pycache__/server.cpython-313.pyc | Bin 1891 -> 1901 bytes .../__pycache__/user_manager.cpython-313.pyc | Bin 8296 -> 8306 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/database/systades.db b/database/systades.db index 1d9c4d5eb3dc19a530cc8b65812931220868c400..5898a63da63b33a77b62782e902ed9f8e636ba9d 100644 GIT binary patch delta 112 zcmZo@;B08%oFL7pGf~EwQDr NCWSTy#$^gj3IMln95w&| diff --git a/utils/__pycache__/db_rebuild.cpython-313.pyc b/utils/__pycache__/db_rebuild.cpython-313.pyc index e52baf08ef2903bb40aab4b74c20e1211f276eec..49f37054111e1788dca86af12cdae8911bf267e9 100644 GIT binary patch delta 62 zcmcaE`%sqqGcPX}0}vQw2yNuv%B5oOY!wq)oLW>Ila^VOnj7PiTAW>yUl3zxXc!Y* QSzMBsl3Kj^7S~^90ABMIUjP6A delta 52 zcmaDTdtH|MGcPX}0}yQdBe;=!E0>h1vsFxJacWUi$Z QEG|h*NiE)N#yV3F071wT!~g&Q delta 52 zcmcbqdtR6OGcPX}0}yQdBe;=UkX6da*(xTqIJKxaCM3k)*Ez~j&(+t}F~%jeY_kLF GOhEvjDG$v6 diff --git a/utils/__pycache__/server.cpython-313.pyc b/utils/__pycache__/server.cpython-313.pyc index 96ce9cd916b3a236b1dd64ee274eff7fd5013cb9..ccc45a03a0d111df197cc79d6e388671917badc0 100644 GIT binary patch delta 62 zcmaFN_m+?QGcPX}0}vQw2yNv4%dBGUY!wq)oLW>Ila^VOnj7PiTAW>yUl3zxXc!Y* QSzMBsl3Ki3iN%o_0At7$8~^|S delta 52 zcmaFM_n43SGcPX}0}yQdBe;?KFSC@PvsFxJacWUkuUX diff --git a/utils/__pycache__/user_manager.cpython-313.pyc b/utils/__pycache__/user_manager.cpython-313.pyc index d77e2b1817483ccd2d9215201ebf97d1c3f70434..f8c0dccdab928b999de25b80524531e5de0a29ba 100644 GIT binary patch delta 62 zcmaFi@X3MuGcPX}0}wDXh;8H!;8byRwu%WYPAw{qNy{us&5dzMEzT~i$Z QEG|h*NiE)7%K2Fg07*v_bpQYW delta 52 zcmez5@WO%nGcPX}0}!nKAhMA=fK$rc*(xTqIJKxaCM3k)*Ez~j&(+t}F~%jeY;!&5 GXE6Y|h7kY& From 7cb2bf1ed0a6d1f3fdf4af9802e7be457af1bf99 Mon Sep 17 00:00:00 2001 From: marwin Date: Sat, 10 May 2025 20:40:13 +0100 Subject: [PATCH 2/6] =?UTF-8?q?=E2=9C=A8=20feat:=20enhance=20mindmap=20and?= =?UTF-8?q?=20neural=20network=20background=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/update_mindmap.js | 261 +++++++++++++---------- static/neural-network-background-full.js | 62 +++++- 2 files changed, 210 insertions(+), 113 deletions(-) diff --git a/static/js/update_mindmap.js b/static/js/update_mindmap.js index 08e6063..b589e45 100644 --- a/static/js/update_mindmap.js +++ b/static/js/update_mindmap.js @@ -547,17 +547,20 @@ function enhanceMindmap() { cy.layout({ name: 'cose', animate: true, - animationDuration: 1800, + animationDuration: 2000, nodeDimensionsIncludeLabels: true, padding: 100, - spacingFactor: 1.8, - randomize: false, + spacingFactor: 2, + randomize: true, fit: true, - componentSpacing: 100, - nodeRepulsion: 8000, - edgeElasticity: 100, - nestingFactor: 1.2, - gravity: 80 + componentSpacing: 150, + nodeRepulsion: 10000, + edgeElasticity: 150, + nestingFactor: 1.5, + gravity: 100, + initialTemp: 1000, + coolingFactor: 0.95, + minTemp: 1 }).run(); // Neuronen-Namen mit besserer Lesbarkeit umgestalten @@ -621,33 +624,43 @@ function applyNeuralNetworkStyle(cy) { cy.style() .selector('node') .style({ - 'label': 'data(name)', - 'text-valign': 'bottom', + 'label': 'data(label)', + 'text-valign': 'center', 'text-halign': 'center', 'color': '#ffffff', - 'text-outline-width': 1.5, - 'text-outline-color': '#0a0e19', + 'text-outline-width': 2, + 'text-outline-color': 'rgba(0,0,0,0.8)', '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)', + 'font-size': 14, + 'font-weight': '500', + 'text-margin-y': 8, + 'width': 'mapData(neuronSize, 3, 10, 40, 80)', + 'height': 'mapData(neuronSize, 3, 10, 40, 80)', 'background-color': 'data(color)', - 'background-opacity': 0.85, - 'border-width': 0, + 'background-opacity': 0.9, + 'border-width': 2, + 'border-color': '#ffffff', + 'border-opacity': 0.8, 'shape': 'ellipse', - 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 5, 15)', + 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 15, 30)', 'shadow-color': 'data(color)', - 'shadow-opacity': 0.6, + 'shadow-opacity': 0.8, 'shadow-offset-x': 0, - 'shadow-offset-y': 0 + 'shadow-offset-y': 0, + 'transition-property': 'background-color, shadow-blur, shadow-opacity, background-opacity', + 'transition-duration': '0.3s', + 'transition-timing-function': 'ease-in-out' }) .selector('edge') .style({ - 'width': 'mapData(strength, 0.2, 0.8, 0.7, 2)', + 'width': 'mapData(strength, 0.2, 0.8, 1, 3)', 'curve-style': 'bezier', - 'line-color': '#8a8aaa', - 'line-opacity': 'mapData(strength, 0.2, 0.8, 0.4, 0.7)', + 'line-color': function(ele) { + const sourceColor = ele.source().data('color'); + const targetColor = ele.target().data('color'); + return `linear-gradient(to right, ${sourceColor}, ${targetColor})`; + }, + 'line-opacity': 'mapData(strength, 0.2, 0.8, 0.4, 0.8)', 'line-style': function(ele) { const strength = ele.data('strength'); if (strength <= 0.4) return 'dotted'; @@ -656,19 +669,23 @@ function applyNeuralNetworkStyle(cy) { }, 'target-arrow-shape': 'none', 'source-endpoint': '0% 50%', - 'target-endpoint': '100% 50%' + 'target-endpoint': '100% 50%', + 'transition-property': 'line-opacity, width', + 'transition-duration': '0.3s', + 'transition-timing-function': 'ease-in-out' }) .selector('node[isRoot]') .style({ - 'font-size': 12, + 'font-size': 18, 'font-weight': 'bold', - 'width': 50, - 'height': 50, + 'width': 100, + 'height': 100, 'background-color': '#6366f1', - 'shadow-blur': 20, + 'shadow-blur': 30, 'shadow-color': '#6366f1', - 'shadow-opacity': 0.8, - 'text-margin-y': 8 + 'shadow-opacity': 0.9, + 'text-margin-y': 10, + 'border-width': 3 }) .update(); } @@ -678,91 +695,111 @@ function applyNeuralNetworkStyle(cy) { * @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(); + if (window.neuralInterval) clearInterval(window.neuralInterval); - // 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; + const nodes = cy.nodes(); + const edges = cy.edges(); + let currentTime = Date.now(); - // 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); + function simulateNeuralActivity() { + currentTime = Date.now(); - // 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); - } + nodes.forEach(node => { + const data = node.data(); + const lastFired = data.lastFired || 0; + const timeSinceLastFire = currentTime - lastFired; + + if (timeSinceLastFire > data.refractionPeriod) { + if (Math.random() < data.neuronActivity * 0.15) { + fireNeuron(node, true, currentTime); + } + } + }); + } + + function fireNeuron(node, state, currentTime) { + const data = node.data(); + data.lastFired = currentTime; + + // Verbesserte visuelle Effekte + node.animate({ + style: { + 'background-opacity': 1, + 'shadow-blur': 35, + 'shadow-opacity': 1, + 'border-width': 3, + 'border-color': '#ffffff' + }, + duration: 200, + easing: 'ease-in-out-cubic' + }); + + setTimeout(() => { + node.animate({ + style: { + 'background-opacity': 0.9, + 'shadow-blur': 20, + 'shadow-opacity': 0.8, + 'border-width': 2, + 'border-color': 'rgba(255,255,255,0.8)' + }, + duration: 300, + easing: 'ease-out-cubic' + }); + }, 200); + + if (state) { + propagateSignal(node, currentTime); } - }, latency); - }); - } - - // Simulation starten - window.neuralInterval = setInterval(simulateNeuralActivity, 100); + } + + function propagateSignal(sourceNode, currentTime) { + const outgoingEdges = sourceNode.connectedEdges('out'); + + outgoingEdges.forEach(edge => { + const targetNode = edge.target(); + const edgeData = edge.data(); + const latency = edgeData.latency; + + // Verbesserte Kanten-Animation + edge.animate({ + style: { + 'line-opacity': 1, + 'width': edgeData.strength * 4 + }, + duration: 200, + easing: 'ease-in-out-cubic' + }); + + setTimeout(() => { + edge.animate({ + style: { + 'line-opacity': edgeData.strength * 0.8, + 'width': edgeData.strength * 2 + }, + duration: 300, + easing: 'ease-out-cubic' + }); + }, 200); + + setTimeout(() => { + const targetData = targetNode.data(); + const timeSinceLastFire = currentTime - (targetData.lastFired || 0); + + if (timeSinceLastFire > targetData.refractionPeriod) { + const signalStrength = edgeData.strength * + edgeData.conductionVelocity * + sourceNode.data('neuronActivity'); + + if (signalStrength > targetData.threshold) { + fireNeuron(targetNode, true, currentTime + latency); + } + } + }, latency); + }); + } + + window.neuralInterval = setInterval(simulateNeuralActivity, 100); } // Hilfe-Funktion zum Hinzufügen eines Flash-Hinweises diff --git a/static/neural-network-background-full.js b/static/neural-network-background-full.js index 7c7ecab..bc0fedb 100644 --- a/static/neural-network-background-full.js +++ b/static/neural-network-background-full.js @@ -1106,4 +1106,64 @@ window.addEventListener('beforeunload', () => { if (window.neuralNetworkBackground) { window.neuralNetworkBackground.destroy(); } -}); \ No newline at end of file +}); + +function applyNeuralNetworkStyle(cy) { + cy.style() + .selector('node') + .style({ + 'label': 'data(label)', + 'text-valign': 'center', + 'text-halign': 'center', + 'color': '#ffffff', + 'text-outline-width': 2, + 'text-outline-color': 'rgba(0,0,0,0.8)', + 'text-outline-opacity': 0.9, + 'font-size': 14, + 'font-weight': '500', + 'text-margin-y': 8, + 'width': function(ele) { + return ele.data('neuronSize') ? ele.data('neuronSize') * 8 : 60; + }, + 'height': function(ele) { + return ele.data('neuronSize') ? ele.data('neuronSize') * 8 : 60; + }, + 'background-color': 'data(color)', + 'background-opacity': 0.9, + 'border-width': 2, + 'border-color': '#ffffff', + 'border-opacity': 0.8, + 'shape': 'ellipse', + 'transition-property': 'background-color, background-opacity, border-width', + 'transition-duration': '0.3s', + 'transition-timing-function': 'ease-in-out' + }) + .selector('edge') + .style({ + 'width': function(ele) { + return ele.data('strength') ? ele.data('strength') * 3 : 1; + }, + 'curve-style': 'bezier', + 'line-color': function(ele) { + const sourceColor = ele.source().data('color'); + return sourceColor || '#8a8aaa'; + }, + 'line-opacity': function(ele) { + return ele.data('strength') ? ele.data('strength') * 0.8 : 0.4; + }, + 'line-style': function(ele) { + const strength = ele.data('strength'); + if (!strength) return 'solid'; + 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%', + 'transition-property': 'line-opacity, width', + 'transition-duration': '0.3s', + 'transition-timing-function': 'ease-in-out' + }) + .update(); +} \ No newline at end of file From 6a3b3a81c179a91efb184c1dd3d77e1eba51c7fc Mon Sep 17 00:00:00 2001 From: marwin Date: Sat, 10 May 2025 21:19:54 +0100 Subject: [PATCH 3/6] =?UTF-8?q?=E2=9C=A8=20feat:=20verbessere=20neuronale?= =?UTF-8?q?=20Netzwerkdarstellung=20und=20Mindmap-Layout=20durch=20Anpassu?= =?UTF-8?q?ngen=20an=20Farben,=20Gr=C3=B6=C3=9Fen=20und=20Animationen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/update_mindmap.js | 261 +++++++++++------------ static/neural-network-background-full.js | 10 +- 2 files changed, 126 insertions(+), 145 deletions(-) diff --git a/static/js/update_mindmap.js b/static/js/update_mindmap.js index b589e45..aabc533 100644 --- a/static/js/update_mindmap.js +++ b/static/js/update_mindmap.js @@ -129,7 +129,9 @@ const mindmapData = { color: '#f5f5f5', icon: 'fa-solid fa-circle', fontColor: '#222', - fontSize: 22 + fontSize: 22, + neuronSize: 12, + neuronActivity: 1.0 }, { id: 'philosophy', @@ -248,7 +250,7 @@ document.addEventListener('DOMContentLoaded', function() { console.log('Initialisiere Cytoscape...'); - // Initialisiere Cytoscape mit concentric/circle Layout und Icon-Overlay + // Initialisiere Cytoscape mit einem schlichten, modernen Design window.cy = cytoscape({ container: cyContainer, elements: elements, @@ -262,62 +264,66 @@ document.addEventListener('DOMContentLoaded', function() { 'text-valign': 'center', 'text-halign': 'center', 'font-size': 'data(fontSize)', - 'width': 'mapData(neuronSize, 3, 10, 60, 110)', - 'height': 'mapData(neuronSize, 3, 10, 60, 110)', - 'border-width': 4, - 'border-color': '#fff', - 'border-opacity': 0.9, - 'overlay-padding': 4, - 'z-index': 10, + 'width': function(ele) { + return ele.data('isCenter') ? 100 : 80; + }, + 'height': function(ele) { + return ele.data('isCenter') ? 100 : 80; + }, + 'border-width': 2, + 'border-color': '#ffffff', + 'border-opacity': 0.8, 'shape': 'ellipse', - 'background-opacity': 0.95, - 'shadow-blur': 20, - 'shadow-color': 'data(color)', - 'shadow-opacity': 0.7, - 'shadow-offset-x': 0, - 'shadow-offset-y': 0, + 'background-opacity': 0.9, 'text-wrap': 'wrap', - 'text-max-width': 90 + 'text-max-width': 80, + 'transition-property': 'background-color, border-width', + 'transition-duration': '0.2s' } }, { - selector: 'node[isCenter]','style': { + selector: 'node[isCenter]', + style: { 'background-color': '#f5f5f5', 'color': '#222', - 'font-size': 22, - 'border-width': 0, - 'width': 120, - 'height': 120 + 'font-size': 20, + 'border-width': 3, + 'width': 100, + 'height': 100 } }, { selector: 'node:selected', style: { 'border-color': '#f59e42', - 'border-width': 6, - 'shadow-blur': 30, - 'shadow-opacity': 0.9 + 'border-width': 3, + 'background-opacity': 1 } }, { selector: 'edge', style: { - 'width': 'mapData(strength, 0.2, 1, 3, 7)', - 'line-color': '#bdbdbd', - 'line-opacity': 0.7, + 'width': function(ele) { + return ele.data('strength') ? ele.data('strength') * 2 : 1; + }, + 'line-color': function(ele) { + const sourceColor = ele.source().data('color'); + return sourceColor || '#8a8aaa'; + }, + 'line-opacity': function(ele) { + return ele.data('strength') ? ele.data('strength') * 0.6 : 0.4; + }, 'curve-style': 'bezier', 'target-arrow-shape': 'none', - 'control-point-distances': [40, -40], - 'control-point-weights': [0.5, 0.5], - 'edge-distances': 'intersection', - 'line-style': 'solid' + 'control-point-distances': [30, -30], + 'control-point-weights': [0.5, 0.5] } } ], layout: { name: 'concentric', fit: true, - padding: 60, + padding: 50, animate: true, concentric: function(node) { return node.data('isCenter') ? 2 : 1; @@ -373,20 +379,11 @@ document.addEventListener('DOMContentLoaded', function() { } }); - // Nach dem Rendern: Icons als HTML-Overlay einfügen + // Entferne den Icon-Overlay-Code setTimeout(() => { - cy.nodes().forEach(node => { - const icon = node.data('icon'); - if (icon) { - const dom = cy.getElementById(node.id()).popperRef(); - const iconDiv = document.createElement('div'); - iconDiv.className = 'cy-node-icon'; - iconDiv.innerHTML = ``; - document.body.appendChild(iconDiv); - // Positionierung mit Popper.js oder absolut über node.position() - } - }); - }, 500); + // Entferne alle existierenden Icon-Overlays + document.querySelectorAll('.cy-node-icon').forEach(icon => icon.remove()); + }, 0); }); // Funktion zum Initialisieren des neuronalen Designs @@ -620,49 +617,53 @@ function enhanceMindmap() { * @param {Object} cy - Cytoscape-Instanz */ function applyNeuralNetworkStyle(cy) { - // Wende erweiterte Stile für Neuronen und Synapsen an cy.style() .selector('node') .style({ 'label': 'data(label)', 'text-valign': 'center', 'text-halign': 'center', - 'color': '#ffffff', + 'color': 'data(fontColor)', 'text-outline-width': 2, 'text-outline-color': 'rgba(0,0,0,0.8)', 'text-outline-opacity': 0.9, - 'font-size': 14, + 'font-size': 'data(fontSize)', 'font-weight': '500', 'text-margin-y': 8, - 'width': 'mapData(neuronSize, 3, 10, 40, 80)', - 'height': 'mapData(neuronSize, 3, 10, 40, 80)', + 'width': function(ele) { + if (ele.data('isCenter')) return 120; + return ele.data('neuronSize') ? ele.data('neuronSize') * 10 : 80; + }, + 'height': function(ele) { + if (ele.data('isCenter')) return 120; + return ele.data('neuronSize') ? ele.data('neuronSize') * 10 : 80; + }, 'background-color': 'data(color)', 'background-opacity': 0.9, 'border-width': 2, 'border-color': '#ffffff', 'border-opacity': 0.8, 'shape': 'ellipse', - 'shadow-blur': 'mapData(neuronActivity, 0.3, 1, 15, 30)', - 'shadow-color': 'data(color)', - 'shadow-opacity': 0.8, - 'shadow-offset-x': 0, - 'shadow-offset-y': 0, - 'transition-property': 'background-color, shadow-blur, shadow-opacity, background-opacity', + 'transition-property': 'background-color, background-opacity, border-width', 'transition-duration': '0.3s', 'transition-timing-function': 'ease-in-out' }) .selector('edge') .style({ - 'width': 'mapData(strength, 0.2, 0.8, 1, 3)', + 'width': function(ele) { + return ele.data('strength') ? ele.data('strength') * 3 : 1; + }, 'curve-style': 'bezier', 'line-color': function(ele) { const sourceColor = ele.source().data('color'); - const targetColor = ele.target().data('color'); - return `linear-gradient(to right, ${sourceColor}, ${targetColor})`; + return sourceColor || '#8a8aaa'; + }, + 'line-opacity': function(ele) { + return ele.data('strength') ? ele.data('strength') * 0.8 : 0.4; }, - 'line-opacity': 'mapData(strength, 0.2, 0.8, 0.4, 0.8)', 'line-style': function(ele) { const strength = ele.data('strength'); + if (!strength) return 'solid'; if (strength <= 0.4) return 'dotted'; if (strength <= 0.6) return 'dashed'; return 'solid'; @@ -674,31 +675,14 @@ function applyNeuralNetworkStyle(cy) { 'transition-duration': '0.3s', 'transition-timing-function': 'ease-in-out' }) - .selector('node[isRoot]') - .style({ - 'font-size': 18, - 'font-weight': 'bold', - 'width': 100, - 'height': 100, - 'background-color': '#6366f1', - 'shadow-blur': 30, - 'shadow-color': '#6366f1', - 'shadow-opacity': 0.9, - 'text-margin-y': 10, - 'border-width': 3 - }) .update(); } -/** - * Simuliert neuronale Aktivität in der Mindmap - * @param {Object} cy - Cytoscape-Instanz - */ +// Vereinfachte neuronale Aktivitätssimulation function startNeuralActivitySimulation(cy) { if (window.neuralInterval) clearInterval(window.neuralInterval); const nodes = cy.nodes(); - const edges = cy.edges(); let currentTime = Date.now(); function simulateNeuralActivity() { @@ -710,7 +694,7 @@ function startNeuralActivitySimulation(cy) { const timeSinceLastFire = currentTime - lastFired; if (timeSinceLastFire > data.refractionPeriod) { - if (Math.random() < data.neuronActivity * 0.15) { + if (Math.random() < data.neuronActivity * 0.1) { fireNeuron(node, true, currentTime); } } @@ -721,30 +705,15 @@ function startNeuralActivitySimulation(cy) { const data = node.data(); data.lastFired = currentTime; - // Verbesserte visuelle Effekte - node.animate({ - style: { - 'background-opacity': 1, - 'shadow-blur': 35, - 'shadow-opacity': 1, - 'border-width': 3, - 'border-color': '#ffffff' - }, - duration: 200, - easing: 'ease-in-out-cubic' + node.style({ + 'background-opacity': 1, + 'border-width': 3 }); setTimeout(() => { - node.animate({ - style: { - 'background-opacity': 0.9, - 'shadow-blur': 20, - 'shadow-opacity': 0.8, - 'border-width': 2, - 'border-color': 'rgba(255,255,255,0.8)' - }, - duration: 300, - easing: 'ease-out-cubic' + node.style({ + 'background-opacity': 0.9, + 'border-width': 2 }); }, 200); @@ -754,31 +723,22 @@ function startNeuralActivitySimulation(cy) { } function propagateSignal(sourceNode, currentTime) { - const outgoingEdges = sourceNode.connectedEdges('out'); + const outgoingEdges = sourceNode.connectedEdges(); outgoingEdges.forEach(edge => { const targetNode = edge.target(); const edgeData = edge.data(); const latency = edgeData.latency; - // Verbesserte Kanten-Animation - edge.animate({ - style: { - 'line-opacity': 1, - 'width': edgeData.strength * 4 - }, - duration: 200, - easing: 'ease-in-out-cubic' + edge.style({ + 'line-opacity': 0.8, + 'width': edgeData.strength * 3 }); setTimeout(() => { - edge.animate({ - style: { - 'line-opacity': edgeData.strength * 0.8, - 'width': edgeData.strength * 2 - }, - duration: 300, - easing: 'ease-out-cubic' + edge.style({ + 'line-opacity': edgeData.strength * 0.6, + 'width': edgeData.strength * 2 }); }, 200); @@ -845,7 +805,6 @@ async function loadSubthemes(node) { try { console.log('Loading subthemes for node:', node.id()); - // Simuliere Datenbankabfrage const subthemes = subthemesDatabase[node.id()]; if (!subthemes) { @@ -853,16 +812,13 @@ async function loadSubthemes(node) { return; } - // Animation starten showFlash('Lade Subthemen...', 'info'); - // Neue Seite erstellen const mindmapContainer = document.querySelector('.mindmap-container'); const newPage = document.createElement('div'); newPage.className = 'mindmap-page'; newPage.style.display = 'none'; - // Kopfzeile erstellen const header = document.createElement('div'); header.className = 'mindmap-header'; header.innerHTML = ` @@ -874,17 +830,14 @@ async function loadSubthemes(node) {

${node.data('label')}

`; - // Container für die neue Mindmap const newContainer = document.createElement('div'); newContainer.id = `cy-${node.id()}`; newContainer.className = 'mindmap-view'; - // Elemente zur Seite hinzufügen newPage.appendChild(header); newPage.appendChild(newContainer); mindmapContainer.appendChild(newPage); - // Neue Cytoscape-Instanz erstellen const newCy = cytoscape({ container: newContainer, elements: [], @@ -898,7 +851,14 @@ async function loadSubthemes(node) { padding: 30, nodeRepulsion: 4500, idealEdgeLength: 50, - edgeElasticity: 0.45 + edgeElasticity: 0.45, + randomize: true, + componentSpacing: 100, + nodeOverlap: 20, + gravity: 0.25, + initialTemp: 1000, + coolingFactor: 0.95, + minTemp: 1 } }); @@ -914,11 +874,28 @@ async function loadSubthemes(node) { hasChildren: subtheme.hasChildren, expanded: false, neuronSize: 6, - neuronActivity: 0.7 + neuronActivity: 0.7, + color: categoryColors[subtheme.category] || '#60a5fa', + fontColor: '#ffffff', + fontSize: 14 } }); }); + // Kanten zwischen den Subthemen erstellen + for (let i = 0; i < subthemes.length; i++) { + for (let j = i + 1; j < subthemes.length; j++) { + newCy.add({ + group: 'edges', + data: { + source: subthemes[i].id, + target: subthemes[j].id, + strength: Math.random() * 0.5 + 0.3 + } + }); + } + } + // Neuronales Design für die neue Mindmap initialisieren initializeNeuralDesign(newCy); @@ -935,25 +912,27 @@ async function loadSubthemes(node) { newPage.style.display = 'block'; // Layout ausführen - newCy.layout().run(); + newCy.layout({ + name: 'cose', + animate: true, + animationDuration: 500, + refresh: 20, + fit: true, + padding: 30, + nodeRepulsion: 4500, + idealEdgeLength: 50, + edgeElasticity: 0.45, + randomize: true, + componentSpacing: 100, + nodeOverlap: 20, + gravity: 0.25, + initialTemp: 1000, + coolingFactor: 0.95, + minTemp: 1 + }).run(); - // Erfolgsmeldung anzeigen showFlash('Subthemen erfolgreich geladen', 'success'); - // Icons für Subthemen wie oben einfügen - setTimeout(() => { - newCy.nodes().forEach(node => { - const icon = node.data('icon'); - if (icon) { - const dom = newCy.getElementById(node.id()).popperRef(); - const iconDiv = document.createElement('div'); - iconDiv.className = 'cy-node-icon'; - iconDiv.innerHTML = ``; - document.body.appendChild(iconDiv); - } - }); - }, 500); - } catch (error) { console.error('Fehler beim Laden der Subthemen:', error); showFlash('Fehler beim Laden der Subthemen', 'error'); diff --git a/static/neural-network-background-full.js b/static/neural-network-background-full.js index bc0fedb..009eda6 100644 --- a/static/neural-network-background-full.js +++ b/static/neural-network-background-full.js @@ -1115,18 +1115,20 @@ function applyNeuralNetworkStyle(cy) { 'label': 'data(label)', 'text-valign': 'center', 'text-halign': 'center', - 'color': '#ffffff', + 'color': 'data(fontColor)', 'text-outline-width': 2, 'text-outline-color': 'rgba(0,0,0,0.8)', 'text-outline-opacity': 0.9, - 'font-size': 14, + 'font-size': 'data(fontSize)', 'font-weight': '500', 'text-margin-y': 8, 'width': function(ele) { - return ele.data('neuronSize') ? ele.data('neuronSize') * 8 : 60; + if (ele.data('isCenter')) return 120; + return ele.data('neuronSize') ? ele.data('neuronSize') * 10 : 80; }, 'height': function(ele) { - return ele.data('neuronSize') ? ele.data('neuronSize') * 8 : 60; + if (ele.data('isCenter')) return 120; + return ele.data('neuronSize') ? ele.data('neuronSize') * 10 : 80; }, 'background-color': 'data(color)', 'background-opacity': 0.9, From dec4a57b89f69a75dc3e4ff0091af0e73e0a4680 Mon Sep 17 00:00:00 2001 From: marwin Date: Sat, 10 May 2025 21:27:57 +0100 Subject: [PATCH 4/6] =?UTF-8?q?=E2=9C=A8=20feat:=20enhance=20mindmap=20upd?= =?UTF-8?q?ate=20functionality=20in=20app.py=20and=20update=5Fmindmap.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 71 ++++++++++- static/js/update_mindmap.js | 228 +++++++++++++++++++++++++----------- 2 files changed, 231 insertions(+), 68 deletions(-) diff --git a/app.py b/app.py index cb16aca..6a7a92f 100644 --- a/app.py +++ b/app.py @@ -1879,4 +1879,73 @@ def admin_update_database(): message = f"Fehler: {str(e)}" success = False - return render_template('admin/update_database.html', message=message, success=success) \ No newline at end of file + return render_template('admin/update_database.html', message=message, success=success) + +@app.route('/api/mindmap/') +def get_mindmap_node(node_id): + """Liefert die Mindmap-Daten für einen bestimmten Knoten und seine Subthemen.""" + try: + if node_id == 'root': + # Hauptknoten (Wissen) abrufen + wissen_node = MindMapNode.query.filter_by(name="Wissen").first() + if not wissen_node: + wissen_node = MindMapNode( + name="Wissen", + description="Zentrale Wissensbasis", + color_code="#4299E1", + is_public=True + ) + db.session.add(wissen_node) + db.session.commit() + + # Alle direkten Kinder des Wissen-Knotens holen + nodes = wissen_node.children.all() + else: + # Bestimmten Knoten und seine Kinder abrufen + parent_node = MindMapNode.query.get_or_404(node_id) + nodes = parent_node.children.all() + wissen_node = parent_node + + # Ergebnisdaten vorbereiten + nodes_data = [] + edges_data = [] + + # Hauptknoten hinzufügen + nodes_data.append({ + 'id': wissen_node.id, + 'name': wissen_node.name, + 'description': wissen_node.description or '', + 'color_code': wissen_node.color_code or '#4299E1', + 'is_center': True, + 'has_children': len(nodes) > 0 + }) + + # Kinder 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', + 'is_center': False, + 'has_children': len(node.children.all()) > 0 + }) + + # Verbindung zum Elternknoten hinzufügen + edges_data.append({ + 'source_id': wissen_node.id, + 'target_id': node.id, + 'strength': 0.8 + }) + + return jsonify({ + 'nodes': nodes_data, + 'edges': edges_data + }) + + except Exception as e: + print(f"Fehler beim Abrufen der Mindmap-Daten: {str(e)}") + return jsonify({ + 'success': False, + 'error': 'Mindmap-Daten konnten nicht geladen werden' + }), 500 \ No newline at end of file diff --git a/static/js/update_mindmap.js b/static/js/update_mindmap.js index aabc533..4145129 100644 --- a/static/js/update_mindmap.js +++ b/static/js/update_mindmap.js @@ -800,17 +800,144 @@ function createFlashContainer() { return container; } +// Funktion zum Laden der Mindmap-Daten aus der Datenbank +async function loadMindmapData(nodeId = null) { + try { + const response = await fetch(`/api/mindmap/${nodeId || 'root'}`); + if (!response.ok) throw new Error('Fehler beim Laden der Mindmap-Daten'); + return await response.json(); + } catch (error) { + console.error('Fehler beim Laden der Mindmap-Daten:', error); + showFlash('Fehler beim Laden der Mindmap-Daten', 'error'); + return null; + } +} + +// Funktion zum Initialisieren der Mindmap +async function initializeMindmap() { + const mindmapData = await loadMindmapData(); + if (!mindmapData) return; + + const elements = [ + // Knoten + ...mindmapData.nodes.map(node => ({ + data: { + id: node.id, + label: node.name, + category: node.category, + description: node.description, + hasChildren: node.has_children, + expanded: false, + color: node.color_code, + fontColor: '#ffffff', + fontSize: node.is_center ? 20 : 16 + } + })), + // Kanten + ...mindmapData.edges.map(edge => ({ + data: { + source: edge.source_id, + target: edge.target_id, + strength: edge.strength || 0.5 + } + })) + ]; + + window.cy = cytoscape({ + container: document.getElementById('cy'), + elements: elements, + style: [ + { + selector: 'node', + style: { + 'background-color': 'data(color)', + 'label': 'data(label)', + 'color': 'data(fontColor)', + 'text-valign': 'center', + 'text-halign': 'center', + 'font-size': 'data(fontSize)', + 'width': function(ele) { + return ele.data('isCenter') ? 100 : 80; + }, + 'height': function(ele) { + return ele.data('isCenter') ? 100 : 80; + }, + 'border-width': 2, + 'border-color': '#ffffff', + 'border-opacity': 0.8, + 'shape': 'ellipse', + 'background-opacity': 0.9, + 'text-wrap': 'wrap', + 'text-max-width': 80, + 'transition-property': 'background-color, border-width', + 'transition-duration': '0.2s' + } + }, + { + selector: 'node[isCenter]', + style: { + 'background-color': '#f5f5f5', + 'color': '#222', + 'font-size': 20, + 'border-width': 3, + 'width': 100, + 'height': 100 + } + }, + { + selector: 'node:selected', + style: { + 'border-color': '#f59e42', + 'border-width': 3, + 'background-opacity': 1 + } + }, + { + selector: 'edge', + style: { + 'width': function(ele) { + return ele.data('strength') ? ele.data('strength') * 2 : 1; + }, + 'line-color': function(ele) { + const sourceColor = ele.source().data('color'); + return sourceColor || '#8a8aaa'; + }, + 'line-opacity': function(ele) { + return ele.data('strength') ? ele.data('strength') * 0.6 : 0.4; + }, + 'curve-style': 'bezier', + 'target-arrow-shape': 'none', + 'control-point-distances': [30, -30], + 'control-point-weights': [0.5, 0.5] + } + } + ], + layout: { + name: 'concentric', + fit: true, + padding: 50, + animate: true, + concentric: function(node) { + return node.data('isCenter') ? 2 : 1; + }, + levelWidth: function() { return 1; } + } + }); + + // Event-Listener für Knoten-Klicks + cy.on('tap', 'node', async function(evt) { + const node = evt.target; + if (node.data('hasChildren') && !node.data('expanded')) { + await loadSubthemes(node); + } + }); +} + // Funktion zum Laden der Subthemen async function loadSubthemes(node) { try { - console.log('Loading subthemes for node:', node.id()); - - const subthemes = subthemesDatabase[node.id()]; - - if (!subthemes) { - console.log('No subthemes found for node:', node.id()); - return; - } + const mindmapData = await loadMindmapData(node.id()); + if (!mindmapData) return; showFlash('Lade Subthemen...', 'info'); @@ -840,7 +967,28 @@ async function loadSubthemes(node) { const newCy = cytoscape({ container: newContainer, - elements: [], + elements: [ + ...mindmapData.nodes.map(node => ({ + data: { + id: node.id, + label: node.name, + category: node.category, + description: node.description, + hasChildren: node.has_children, + expanded: false, + color: node.color_code, + fontColor: '#ffffff', + fontSize: 16 + } + })), + ...mindmapData.edges.map(edge => ({ + data: { + source: edge.source_id, + target: edge.target_id, + strength: edge.strength || 0.5 + } + })) + ], style: cy.style(), layout: { name: 'cose', @@ -862,43 +1010,6 @@ async function loadSubthemes(node) { } }); - // Neue Knoten hinzufügen - subthemes.forEach(subtheme => { - newCy.add({ - group: 'nodes', - data: { - id: subtheme.id, - label: subtheme.label, - category: subtheme.category, - description: subtheme.description, - hasChildren: subtheme.hasChildren, - expanded: false, - neuronSize: 6, - neuronActivity: 0.7, - color: categoryColors[subtheme.category] || '#60a5fa', - fontColor: '#ffffff', - fontSize: 14 - } - }); - }); - - // Kanten zwischen den Subthemen erstellen - for (let i = 0; i < subthemes.length; i++) { - for (let j = i + 1; j < subthemes.length; j++) { - newCy.add({ - group: 'edges', - data: { - source: subthemes[i].id, - target: subthemes[j].id, - strength: Math.random() * 0.5 + 0.3 - } - }); - } - } - - // Neuronales Design für die neue Mindmap initialisieren - initializeNeuralDesign(newCy); - // Event-Listener für die neue Mindmap newCy.on('tap', 'node', async function(evt) { const clickedNode = evt.target; @@ -911,26 +1022,6 @@ async function loadSubthemes(node) { cy.container().style.display = 'none'; newPage.style.display = 'block'; - // Layout ausführen - newCy.layout({ - name: 'cose', - animate: true, - animationDuration: 500, - refresh: 20, - fit: true, - padding: 30, - nodeRepulsion: 4500, - idealEdgeLength: 50, - edgeElasticity: 0.45, - randomize: true, - componentSpacing: 100, - nodeOverlap: 20, - gravity: 0.25, - initialTemp: 1000, - coolingFactor: 0.95, - minTemp: 1 - }).run(); - showFlash('Subthemen erfolgreich geladen', 'success'); } catch (error) { @@ -1017,4 +1108,7 @@ style.textContent = ` text-shadow: 0 2px 8px rgba(0,0,0,0.25); } `; -document.head.appendChild(style); \ No newline at end of file +document.head.appendChild(style); + +// Initialisiere die Mindmap beim Laden der Seite +document.addEventListener('DOMContentLoaded', initializeMindmap); \ No newline at end of file From c0bd7a39866cdd8c2f3488d895531bbc35ade364 Mon Sep 17 00:00:00 2001 From: marwin Date: Sat, 10 May 2025 21:58:29 +0100 Subject: [PATCH 5/6] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20systades.db=20and?= =?UTF-8?q?=20update=20=5F=5Fpycache=5F=5F=20for=20improved=20performance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/app.cpython-313.pyc | Bin 82379 -> 83246 bytes systades.db | Bin 0 -> 131072 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 systades.db diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 1615f6ab3dcddf8ea907455760537957176257c5..173742f1627b17b1814008e88f96231cc21f22b5 100644 GIT binary patch delta 17428 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 z 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 r$yb(f*5(_e|T`FMWEsqLnu_b+deHRa5uN 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 Date: Sat, 10 May 2025 21:59:18 +0100 Subject: [PATCH 6/6] =?UTF-8?q?=E2=9C=A8=20chore:=20aktualisiere=20kompili?= =?UTF-8?q?erte=20Python-Bytecode-Datei=20in=20=5F=5Fpycache=5F=5F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/app.cpython-313.pyc | Bin 83246 -> 84690 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 173742f1627b17b1814008e88f96231cc21f22b5..38609f0d34a9023b4e650f9a9b168e39d152a026 100644 GIT binary patch delta 18345 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 delta 16777 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