Refactor node relationship handling in app.py and introduce new routes for thoughts association with nodes.
This commit is contained in:
Binary file not shown.
Binary file not shown.
33
app.py
33
app.py
@@ -22,7 +22,7 @@ from dotenv import load_dotenv
|
|||||||
from models import (
|
from models import (
|
||||||
db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating,
|
db, User, Thought, Comment, MindMapNode, ThoughtRelation, ThoughtRating,
|
||||||
RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote,
|
RelationType, Category, UserMindmap, UserMindmapNode, MindmapNote,
|
||||||
node_thought_association, user_thought_bookmark
|
node_thought_association, user_thought_bookmark, node_relationship
|
||||||
)
|
)
|
||||||
|
|
||||||
# Lade .env-Datei
|
# Lade .env-Datei
|
||||||
@@ -903,45 +903,30 @@ def delete_note(note_id):
|
|||||||
@app.route('/api/mindmap')
|
@app.route('/api/mindmap')
|
||||||
def get_mindmap():
|
def get_mindmap():
|
||||||
"""API-Endpunkt zur Bereitstellung der Mindmap-Daten in hierarchischer Form."""
|
"""API-Endpunkt zur Bereitstellung der Mindmap-Daten in hierarchischer Form."""
|
||||||
# Alle root-Nodes (ohne parent) abrufen
|
# Root-Knoten: Knoten ohne Eltern
|
||||||
root_nodes = MindMapNode.query.filter_by(parent_id=None).all()
|
root_nodes = MindMapNode.query.\
|
||||||
|
outerjoin(node_relationship, MindMapNode.id == node_relationship.c.child_id).\
|
||||||
|
filter(node_relationship.c.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
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
for node in root_nodes:
|
for node in root_nodes:
|
||||||
node_data = build_node_tree(node)
|
node_data = build_node_tree(node)
|
||||||
result.append(node_data)
|
result.append(node_data)
|
||||||
|
|
||||||
return jsonify({"nodes": result})
|
return jsonify({"nodes": result})
|
||||||
|
|
||||||
def build_node_tree(node):
|
def build_node_tree(node):
|
||||||
"""Erzeugt eine hierarchische Darstellung eines Knotens inkl. seiner Kindknoten."""
|
"""Erzeugt eine hierarchische Darstellung eines Knotens inkl. seiner Kindknoten."""
|
||||||
# Gedankenzähler abrufen von der many-to-many Beziehung
|
|
||||||
thought_count = len(node.thoughts)
|
thought_count = len(node.thoughts)
|
||||||
|
|
||||||
# Daten für aktuellen Knoten
|
|
||||||
node_data = {
|
node_data = {
|
||||||
"id": node.id,
|
"id": node.id,
|
||||||
"name": node.name,
|
"name": node.name,
|
||||||
"description": f"Knoten mit {thought_count} Gedanken",
|
"description": node.description or "",
|
||||||
"thought_count": thought_count,
|
"thought_count": thought_count,
|
||||||
"children": []
|
"children": []
|
||||||
}
|
}
|
||||||
|
for child in node.children:
|
||||||
# Rekursiv Kinder hinzufügen
|
child_data = build_node_tree(child)
|
||||||
child_nodes = MindMapNode.query.filter_by(parent_id=node.id).all()
|
|
||||||
for child_node in child_nodes:
|
|
||||||
child_data = build_node_tree(child_node)
|
|
||||||
node_data["children"].append(child_data)
|
node_data["children"].append(child_data)
|
||||||
|
|
||||||
return node_data
|
return node_data
|
||||||
|
|
||||||
@app.route('/api/nodes/<int:node_id>/thoughts')
|
@app.route('/api/nodes/<int:node_id>/thoughts')
|
||||||
@@ -1250,7 +1235,7 @@ def chat_with_assistant():
|
|||||||
|
|
||||||
# Zusammenfassen mehrerer Gedanken oder Analyse anfordern
|
# Zusammenfassen mehrerer Gedanken oder Analyse anfordern
|
||||||
system_message = (
|
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. "
|
"Du kannst Informationen zu Gedanken, Kategorien und Mindmaps liefern. "
|
||||||
"Antworte informativ, sachlich und gut strukturiert auf Deutsch."
|
"Antworte informativ, sachlich und gut strukturiert auf Deutsch."
|
||||||
)
|
)
|
||||||
|
|||||||
BIN
database/__pycache__/models.cpython-313.pyc
Normal file
BIN
database/__pycache__/models.cpython-313.pyc
Normal file
Binary file not shown.
0
instance/systades.db
Normal file
0
instance/systades.db
Normal file
@@ -7,15 +7,6 @@
|
|||||||
* Verwaltet die globale Anwendungslogik
|
* 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
|
* Hauptobjekt der MindMap-Anwendung
|
||||||
*/
|
*/
|
||||||
@@ -24,7 +15,7 @@ const MindMap = {
|
|||||||
initialized: false,
|
initialized: false,
|
||||||
darkMode: document.documentElement.classList.contains('dark'),
|
darkMode: document.documentElement.classList.contains('dark'),
|
||||||
pageInitializers: {},
|
pageInitializers: {},
|
||||||
currentPage: document.body.dataset.page,
|
currentPage: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialisiert die MindMap-Anwendung
|
* Initialisiert die MindMap-Anwendung
|
||||||
@@ -32,6 +23,9 @@ const MindMap = {
|
|||||||
init() {
|
init() {
|
||||||
if (this.initialized) return;
|
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...');
|
console.log('MindMap-Anwendung wird initialisiert...');
|
||||||
|
|
||||||
// Initialisiere den ChatGPT-Assistenten
|
// Initialisiere den ChatGPT-Assistenten
|
||||||
@@ -229,6 +223,13 @@ const MindMap = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Globale Export für andere Module
|
|
||||||
window.MindMap = MindMap;
|
window.MindMap = MindMap;
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
@@ -14,9 +14,18 @@ if (window.MindMap) {
|
|||||||
window.MindMap.pageInitializers.mindmap = initMindmapPage;
|
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() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Prüfe, ob wir auf der Mindmap-Seite sind und initialisiere
|
// 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();
|
initMindmapPage();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -818,6 +818,26 @@ class MindMapVisualization {
|
|||||||
this.updateNodeAppearance(d.id, isBookmarked);
|
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
|
// Exportiere die Klasse für die Verwendung in anderen Modulen
|
||||||
|
|||||||
@@ -68,18 +68,18 @@ class NeuralNetworkBackground {
|
|||||||
|
|
||||||
// Config - Drastisch verstärkt für strahlende Animationen und neuronale Vernetzung
|
// Config - Drastisch verstärkt für strahlende Animationen und neuronale Vernetzung
|
||||||
this.config = {
|
this.config = {
|
||||||
nodeCount: 120, // Viel mehr Knoten für ein dichtes Netzwerk
|
nodeCount: 120, // Anzahl der Knoten bleibt hoch für Netzwerkstruktur
|
||||||
nodeSize: 1.4, // Größere Knoten für mehr Sichtbarkeit
|
nodeSize: 1.1, // Dezenter: kleinere Knoten
|
||||||
nodeVariation: 0.6, // Mehr Variation für organisches Aussehen
|
nodeVariation: 0.4, // Weniger Variation für ruhigeres Bild
|
||||||
connectionDistance: 220, // Deutlich längere Verbindungen für mehr Vernetzung
|
connectionDistance: 220, // Unverändert: gute Vernetzung
|
||||||
connectionOpacity: 0.4, // Wesentlich stärkere Verbindungen
|
connectionOpacity: 0.18, // Deutlich dezentere Verbindungen
|
||||||
animationSpeed: 0.08, // Schnellere Bewegung
|
animationSpeed: 0.05, // Ruhigere Bewegung
|
||||||
pulseSpeed: 0.006, // Schnelleres Pulsieren für lebendiges Aussehen
|
pulseSpeed: 0.004, // Ruhigeres Pulsieren
|
||||||
flowSpeed: 0.8, // Schnellere Flussanimationen
|
flowSpeed: 1.2, // Flows schneller für flüssigere Aktivität
|
||||||
flowDensity: 0.005, // Viel mehr Flussanimationen
|
flowDensity: 0.012, // Mehr Flows für sichtbare Aktivität
|
||||||
flowLength: 0.25, // Längere Flussanimationen
|
flowLength: 0.32, // Flows länger sichtbar
|
||||||
maxConnections: 6, // NEW: Neue Eigenschaft für mehr neuronale Verbindungen pro Knoten
|
maxConnections: 5, // Weniger Überlagerung
|
||||||
clusteringFactor: 0.3 // NEW: Erzeugt Cluster wie in einem neuronalen Netzwerk
|
clusteringFactor: 0.35 // Mehr Cluster für neuronalen Effekt
|
||||||
};
|
};
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
@@ -335,17 +335,17 @@ class NeuralNetworkBackground {
|
|||||||
if (!this.connections.some(conn =>
|
if (!this.connections.some(conn =>
|
||||||
(conn.from === i && conn.to === j) || (conn.from === j && conn.to === i)
|
(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({
|
this.connections.push({
|
||||||
from: i,
|
from: i,
|
||||||
to: j,
|
to: j,
|
||||||
distance: distance,
|
distance: distance,
|
||||||
opacity: connOpacity,
|
opacity: connOpacity,
|
||||||
strength: connectionStrength,
|
strength: connectionStrength,
|
||||||
hasFlow: false, // Each connection can have a flow
|
hasFlow: false,
|
||||||
lastActivated: 0 // For neural firing animation
|
lastActivated: 0,
|
||||||
|
progress: 0 // Animationsfortschritt für Verbindungsaufbau
|
||||||
});
|
});
|
||||||
|
|
||||||
nodeA.connections.push(j);
|
nodeA.connections.push(j);
|
||||||
nodeB.connections.push(i);
|
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
|
// Update flows
|
||||||
this.updateFlows();
|
this.updateFlows();
|
||||||
|
|
||||||
@@ -515,21 +524,8 @@ class NeuralNetworkBackground {
|
|||||||
positions[i * 2] = node.x;
|
positions[i * 2] = node.x;
|
||||||
positions[i * 2 + 1] = node.y;
|
positions[i * 2 + 1] = node.y;
|
||||||
|
|
||||||
// Enhanced pulse effect with additional boost for active nodes
|
// Sichtbarkeit der Neuronen erhöhen
|
||||||
let pulse = Math.sin(node.pulsePhase) * 0.4 + 1;
|
let pulse = Math.sin(node.pulsePhase) * 0.22 + 1.08;
|
||||||
|
|
||||||
// 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)
|
|
||||||
const connectivityFactor = 1 + (node.connections.length / this.config.maxConnections) * 0.8;
|
const connectivityFactor = 1 + (node.connections.length / this.config.maxConnections) * 0.8;
|
||||||
sizes[i] = node.size * pulse * connectivityFactor;
|
sizes[i] = node.size * pulse * connectivityFactor;
|
||||||
}
|
}
|
||||||
@@ -585,10 +581,11 @@ class NeuralNetworkBackground {
|
|||||||
b = (b + nodePulseColor.b / 255) / 2;
|
b = (b + nodePulseColor.b / 255) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sehr sichtbare Knoten
|
||||||
this.gl.uniform4f(
|
this.gl.uniform4f(
|
||||||
this.programInfo.uniformLocations.color,
|
this.programInfo.uniformLocations.color,
|
||||||
r, g, b,
|
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
|
// Draw each node individually for better control
|
||||||
@@ -598,50 +595,40 @@ class NeuralNetworkBackground {
|
|||||||
|
|
||||||
renderConnectionsWebGL() {
|
renderConnectionsWebGL() {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
// For each connection, draw a line
|
|
||||||
for (const connection of this.connections) {
|
for (const connection of this.connections) {
|
||||||
const fromNode = this.nodes[connection.from];
|
const fromNode = this.nodes[connection.from];
|
||||||
const toNode = this.nodes[connection.to];
|
const toNode = this.nodes[connection.to];
|
||||||
|
// Animierter Verbindungsaufbau: nur Teil der Linie zeichnen
|
||||||
// Line positions
|
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([
|
const positions = new Float32Array([
|
||||||
fromNode.x, fromNode.y,
|
x1, y1,
|
||||||
toNode.x, toNode.y
|
x2, y2
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Bind position buffer
|
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
|
||||||
this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, positions, this.gl.STATIC_DRAW);
|
||||||
this.gl.vertexAttribPointer(
|
this.gl.vertexAttribPointer(
|
||||||
this.programInfo.attribLocations.vertexPosition,
|
this.programInfo.attribLocations.vertexPosition,
|
||||||
2, // components per vertex
|
2,
|
||||||
this.gl.FLOAT, // data type
|
this.gl.FLOAT,
|
||||||
false, // normalize
|
false,
|
||||||
0, // stride
|
0,
|
||||||
0 // offset
|
0
|
||||||
);
|
);
|
||||||
this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition);
|
this.gl.enableVertexAttribArray(this.programInfo.attribLocations.vertexPosition);
|
||||||
|
|
||||||
// Disable point size attribute for lines
|
|
||||||
this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize);
|
this.gl.disableVertexAttribArray(this.programInfo.attribLocations.pointSize);
|
||||||
|
|
||||||
// Set line color with connection opacity
|
|
||||||
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
|
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
|
||||||
let lineColor = this.hexToRgb(colorObj.connectionColor);
|
let lineColor = this.hexToRgb(colorObj.connectionColor);
|
||||||
|
// Sehr dezente Grundopazität
|
||||||
// Highlight recently activated connections for neural pathway effect
|
let opacity = connection.opacity * 0.7;
|
||||||
let opacity = connection.opacity * 1.4; // Base increased visibility
|
|
||||||
|
|
||||||
if (now - connection.lastActivated < 800) {
|
if (now - connection.lastActivated < 800) {
|
||||||
// Make recently activated connections brighter
|
|
||||||
lineColor = this.hexToRgb(colorObj.flowColor);
|
lineColor = this.hexToRgb(colorObj.flowColor);
|
||||||
|
|
||||||
// Fade out effect
|
|
||||||
const timeFactor = 1 - ((now - connection.lastActivated) / 800);
|
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.gl.uniform4f(
|
||||||
this.programInfo.uniformLocations.color,
|
this.programInfo.uniformLocations.color,
|
||||||
lineColor.r / 255,
|
lineColor.r / 255,
|
||||||
@@ -649,11 +636,8 @@ class NeuralNetworkBackground {
|
|||||||
lineColor.b / 255,
|
lineColor.b / 255,
|
||||||
opacity
|
opacity
|
||||||
);
|
);
|
||||||
|
// Sehr dünne Linien
|
||||||
// Draw the line
|
this.gl.lineWidth(0.5);
|
||||||
this.gl.enable(this.gl.BLEND);
|
|
||||||
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
|
|
||||||
this.gl.lineWidth(1);
|
|
||||||
this.gl.drawArrays(this.gl.LINES, 0, 2);
|
this.gl.drawArrays(this.gl.LINES, 0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,18 +714,18 @@ class NeuralNetworkBackground {
|
|||||||
// Flow color - much stronger glow
|
// Flow color - much stronger glow
|
||||||
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
|
const colorObj = this.isDarkMode ? this.darkModeColors : this.lightModeColors;
|
||||||
const flowColor = this.hexToRgb(colorObj.flowColor);
|
const flowColor = this.hexToRgb(colorObj.flowColor);
|
||||||
|
|
||||||
|
// Flows mit sanftem, aber sichtbarem Glow und höherer Opazität
|
||||||
this.gl.uniform4f(
|
this.gl.uniform4f(
|
||||||
this.programInfo.uniformLocations.color,
|
this.programInfo.uniformLocations.color,
|
||||||
flowColor.r / 255,
|
flowColor.r / 255,
|
||||||
flowColor.g / 255,
|
flowColor.g / 255,
|
||||||
flowColor.b / 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
|
// Dünnere Flows für subtilen Effekt
|
||||||
this.gl.enable(this.gl.BLEND);
|
this.gl.lineWidth(1.2);
|
||||||
this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE);
|
|
||||||
this.gl.lineWidth(2.5); // Even thicker for dramatic visibility
|
|
||||||
this.gl.drawArrays(this.gl.LINES, 0, 2);
|
this.gl.drawArrays(this.gl.LINES, 0, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -769,13 +753,19 @@ class NeuralNetworkBackground {
|
|||||||
for (const connection of this.connections) {
|
for (const connection of this.connections) {
|
||||||
const fromNode = this.nodes[connection.from];
|
const fromNode = this.nodes[connection.from];
|
||||||
const toNode = this.nodes[connection.to];
|
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.beginPath();
|
||||||
this.ctx.moveTo(fromNode.x, fromNode.y);
|
this.ctx.moveTo(x1, y1);
|
||||||
this.ctx.lineTo(toNode.x, toNode.y);
|
this.ctx.lineTo(x2, y2);
|
||||||
|
|
||||||
const rgbColor = this.hexToRgb(connectionColor);
|
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();
|
this.ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -792,33 +782,22 @@ class NeuralNetworkBackground {
|
|||||||
: this.lightModeColors.nodePulse;
|
: this.lightModeColors.nodePulse;
|
||||||
|
|
||||||
for (const node of this.nodes) {
|
for (const node of this.nodes) {
|
||||||
// Node with subtle glow effect
|
// Sichtbarkeit der Neuronen erhöhen
|
||||||
const pulse = Math.sin(node.pulsePhase) * 0.2 + 1;
|
const pulse = Math.sin(node.pulsePhase) * 0.18 + 1.08; // Leicht erhöhte Amplitude
|
||||||
const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.3 : 1);
|
const nodeSize = node.size * pulse * (node.connections.length > 3 ? 1.22 : 1);
|
||||||
|
|
||||||
// Glow effect
|
|
||||||
const glow = this.ctx.createRadialGradient(
|
const glow = this.ctx.createRadialGradient(
|
||||||
node.x, node.y, 0,
|
node.x, node.y, 0,
|
||||||
node.x, node.y, nodeSize * 2
|
node.x, node.y, nodeSize * 2.2
|
||||||
);
|
);
|
||||||
|
glow.addColorStop(0, `rgba(${nodePulse.r}, ${nodePulse.g}, ${nodePulse.b}, 0.52)`);
|
||||||
const rgbNodeColor = this.hexToRgb(nodeColor);
|
glow.addColorStop(0.5, `rgba(${nodeColor.r}, ${nodeColor.g}, ${nodeColor.b}, 0.22)`);
|
||||||
const rgbPulseColor = this.hexToRgb(nodePulse);
|
glow.addColorStop(1, `rgba(${nodeColor.r}, ${nodeColor.g}, ${nodeColor.b}, 0)`);
|
||||||
|
|
||||||
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
|
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.arc(node.x, node.y, nodeSize, 0, Math.PI * 2);
|
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.fill();
|
||||||
|
this.ctx.globalAlpha = 1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,12 +855,12 @@ class NeuralNetworkBackground {
|
|||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
// Draw flow
|
// Dezente Flows mit sanftem Fade-Out
|
||||||
this.ctx.beginPath();
|
this.ctx.beginPath();
|
||||||
this.ctx.moveTo(p1.x, p1.y);
|
this.ctx.moveTo(p1.x, p1.y);
|
||||||
this.ctx.lineTo(p2.x, p2.y);
|
this.ctx.lineTo(p2.x, p2.y);
|
||||||
this.ctx.strokeStyle = `rgba(${rgbFlowColor.r}, ${rgbFlowColor.g}, ${rgbFlowColor.b}, ${0.4 * fadeOpacity})`;
|
this.ctx.strokeStyle = `rgba(${rgbFlowColor.r}, ${rgbFlowColor.g}, ${rgbFlowColor.b}, ${0.28 * fadeOpacity})`;
|
||||||
this.ctx.lineWidth = 1.5;
|
this.ctx.lineWidth = 1.1;
|
||||||
this.ctx.stroke();
|
this.ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
systades.db
Normal file
0
systades.db
Normal file
@@ -14,11 +14,12 @@
|
|||||||
<meta name="keywords" content="systades, wissen, visualisierung, lernen, gedanken, theorie">
|
<meta name="keywords" content="systades, wissen, visualisierung, lernen, gedanken, theorie">
|
||||||
<meta name="author" content="Systades-Team">
|
<meta name="author" content="Systades-Team">
|
||||||
|
|
||||||
<!-- Tailwind CSS - Beide Optionen verfügbar -->
|
<!-- Tailwind CSS - CDN für Entwicklung und Produktion (laut Vorgabe) -->
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<!-- Alternative lokale Version, falls die CDN-Version blockiert wird -->
|
<!-- Alternative lokale Version, falls die CDN-Version blockiert wird -->
|
||||||
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
<link href="{{ url_for('static', filename='css/tailwind.min.css') }}" rel="stylesheet">
|
||||||
<script>
|
<script>
|
||||||
|
tailwind = window.tailwind || {};
|
||||||
tailwind.config = {
|
tailwind.config = {
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
@@ -113,32 +114,33 @@
|
|||||||
|
|
||||||
<!-- Custom dark mode styles -->
|
<!-- Custom dark mode styles -->
|
||||||
<style>
|
<style>
|
||||||
/* Dark mystical theme */
|
/* Dezenter Hintergrund für beide Modi */
|
||||||
.dark {
|
.dark {
|
||||||
--bg-primary: #0a0e19;
|
--bg-primary: #181c24;
|
||||||
--bg-secondary: #111827;
|
--bg-secondary: #232837;
|
||||||
--text-primary: #f9fafb;
|
--text-primary: #f9fafb;
|
||||||
--text-secondary: #e5e7eb;
|
--text-secondary: #e5e7eb;
|
||||||
--accent-primary: #6d28d9;
|
--accent-primary: #6d28d9;
|
||||||
--accent-secondary: #8b5cf6;
|
--accent-secondary: #8b5cf6;
|
||||||
--glow-effect: 0 0 15px rgba(124, 58, 237, 0.5);
|
--glow-effect: 0 0 8px rgba(124, 58, 237, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light theme with mystical tones */
|
|
||||||
:root {
|
:root {
|
||||||
--bg-primary: #f8fafc;
|
--bg-primary: #f4f6fa;
|
||||||
--bg-secondary: #f1f5f9;
|
--bg-secondary: #e9ecf3;
|
||||||
--text-primary: #1e293b;
|
--text-primary: #232837;
|
||||||
--text-secondary: #475569;
|
--text-secondary: #475569;
|
||||||
--accent-primary: #7c3aed;
|
--accent-primary: #7c3aed;
|
||||||
--accent-secondary: #8b5cf6;
|
--accent-secondary: #8b5cf6;
|
||||||
--glow-effect: 0 0 15px rgba(139, 92, 246, 0.3);
|
--glow-effect: 0 0 8px rgba(139, 92, 246, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.dark {
|
body.dark {
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
body {
|
||||||
|
background-color: var(--bg-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
/* Mystical glowing effects */
|
/* Mystical glowing effects */
|
||||||
.mystical-glow {
|
.mystical-glow {
|
||||||
@@ -611,5 +613,38 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<!-- Dark/Light-Mode persistent und robust -->
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
function applyMode(mode) {
|
||||||
|
if (mode === 'dark') {
|
||||||
|
document.documentElement.classList.add('dark');
|
||||||
|
localStorage.setItem('colorMode', 'dark');
|
||||||
|
} else {
|
||||||
|
document.documentElement.classList.remove('dark');
|
||||||
|
localStorage.setItem('colorMode', 'light');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Beim Laden: Präferenz aus localStorage oder System übernehmen
|
||||||
|
const stored = localStorage.getItem('colorMode');
|
||||||
|
if (stored === 'dark' || stored === 'light') {
|
||||||
|
applyMode(stored);
|
||||||
|
} else {
|
||||||
|
// Systempräferenz als Fallback
|
||||||
|
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
applyMode(prefersDark ? 'dark' : 'light');
|
||||||
|
}
|
||||||
|
// Umschalter für alle Mode-Toggles
|
||||||
|
window.toggleColorMode = function() {
|
||||||
|
const isDark = document.documentElement.classList.contains('dark');
|
||||||
|
applyMode(isDark ? 'light' : 'dark');
|
||||||
|
};
|
||||||
|
// Optional: globales Event für andere Skripte
|
||||||
|
window.addEventListener('storage', function(e) {
|
||||||
|
if (e.key === 'colorMode') applyMode(e.newValue);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -391,7 +391,7 @@
|
|||||||
<div id="mindmap-canvas"></div>
|
<div id="mindmap-canvas"></div>
|
||||||
|
|
||||||
<!-- Control Panel -->
|
<!-- Control Panel -->
|
||||||
<div class="control-panel p-4 w-64">
|
<div class="control-panel p-4 w-64" x-data="{ isExpanded: true }">
|
||||||
<div class="panel-toggle" @click="isExpanded = !isExpanded">
|
<div class="panel-toggle" @click="isExpanded = !isExpanded">
|
||||||
<i class="fa-solid" :class="isExpanded ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
<i class="fa-solid" :class="isExpanded ? 'fa-chevron-left' : 'fa-chevron-right'"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
home = /usr/bin
|
home = C:\Program Files\Python313
|
||||||
include-system-site-packages = false
|
include-system-site-packages = false
|
||||||
version = 3.11.2
|
version = 3.13.3
|
||||||
executable = /usr/bin/python3.11
|
executable = C:\Program Files\Python313\python.exe
|
||||||
command = /usr/bin/python3.11 -m venv /home/core/dev/website/venv
|
command = C:\Program Files\Python313\python.exe -m venv C:\Users\TTOMCZA.EMEA\Dev\website\venv
|
||||||
|
|||||||
Reference in New Issue
Block a user