Files
website/website/templates/mindmap.html

880 lines
26 KiB
HTML

{% extends "base.html" %}
{% block title %}Mindmap{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.css">
<style>
/* Globaler Stil - Hintergrund über die gesamte Seite */
html, body {
background-color: var(--dark-bg) !important;
min-height: 100vh;
width: 100%;
color: #ffffff;
margin: 0;
padding: 0;
overflow-x: hidden;
}
/* Sicherstellen, dass der Hintergrund die gesamte Seite abdeckt */
#app-container, .container, main, .mx-auto, .py-12, body > div, #content-wrapper, #mindmap-container {
background-color: var(--dark-bg) !important;
width: 100%;
}
/* Neuronales Netz / Universum Hintergrund */
.neural-universe-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at center, rgba(30, 20, 60, 0.7) 0%, rgba(10, 10, 25, 0.9) 100%);
z-index: -1;
overflow: hidden;
}
.neural-universe-bg::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image:
radial-gradient(circle at 20% 30%, rgba(179, 143, 255, 0.15) 0%, transparent 25%),
radial-gradient(circle at 80% 20%, rgba(88, 169, 255, 0.1) 0%, transparent 20%),
radial-gradient(circle at 40% 80%, rgba(20, 184, 166, 0.12) 0%, transparent 30%),
radial-gradient(circle at 70% 65%, rgba(139, 92, 246, 0.08) 0%, transparent 25%);
z-index: -1;
}
.neural-universe-bg::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><circle cx="50" cy="50" r="0.5" fill="rgba(255,255,255,0.3)"/></svg>');
background-size: 200px 200px;
opacity: 0.4;
z-index: -1;
animation: twinkling 8s infinite linear;
}
@keyframes twinkling {
from { transform: rotate(0deg) scale(1); }
to { transform: rotate(360deg) scale(1.2); }
}
/* Verbesserte Glasmorphismus-Stile für Karten */
.glass-card, .mindmap-card {
background: rgba(24, 28, 45, 0.75);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 24px;
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
transition: all 0.3s ease;
}
.glass-card:hover, .mindmap-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.45);
border: 1px solid rgba(255, 255, 255, 0.2);
}
/* Feature-Cards-Stil mit besserem Glasmorphismus */
.feature-card {
background: rgba(24, 28, 45, 0.75);
border-radius: 24px;
overflow: hidden;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
transition: all 0.3s ease;
height: 100%;
display: flex;
flex-direction: column;
padding: 1.75rem;
}
.feature-card:hover {
transform: translateY(-5px);
border: 1px solid rgba(255, 255, 255, 0.25);
box-shadow: 0 20px 48px rgba(0, 0, 0, 0.45);
background: rgba(28, 32, 52, 0.9);
}
.feature-card-icon {
font-size: 2.75rem;
margin-bottom: 1.25rem;
background: linear-gradient(135deg, #b38fff, #14b8a6);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
filter: drop-shadow(0 0 10px rgba(179, 143, 255, 0.6));
}
/* Feature-Card-Text besser lesbar machen */
.feature-card h3 {
font-size: 1.75rem;
font-weight: 700;
margin-bottom: 0.9rem;
color: #ffffff;
text-shadow: 0 2px 3px rgba(0, 0, 0, 0.3);
letter-spacing: 0.2px;
}
.feature-card p {
color: rgba(255, 255, 255, 0.95);
font-size: 1.1rem;
line-height: 1.6;
font-weight: 400;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
letter-spacing: 0.3px;
}
/* Visuelle Trennung für den unteren Bereich */
.visual-divider {
position: relative;
height: 6px;
width: 100%;
background: linear-gradient(90deg,
transparent 0%,
rgba(179, 143, 255, 0.8) 20%,
rgba(88, 169, 255, 0.8) 50%,
rgba(179, 143, 255, 0.8) 80%,
transparent 100%);
margin: 2rem 0;
box-shadow: 0 0 15px rgba(179, 143, 255, 0.5);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.visual-divider::before, .visual-divider::after {
content: "";
position: absolute;
height: 1px;
width: 100%;
background: linear-gradient(90deg,
transparent 0%,
rgba(255, 255, 255, 0.3) 20%,
rgba(255, 255, 255, 0.5) 50%,
rgba(255, 255, 255, 0.3) 80%,
transparent 100%);
}
.visual-divider::before {
top: -10px;
}
.visual-divider::after {
bottom: -10px;
}
/* Mindmap-Header */
.mindmap-header {
background: rgba(20, 24, 42, 0.85);
border-radius: 24px;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
}
.gradient-text {
background: linear-gradient(to right, #b38fff, #58a9ff);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
text-shadow: 0 0 25px rgba(179, 143, 255, 0.25);
font-weight: 800;
}
/* D3.js Mindmap spezifische Stile */
.mindmap-svg {
background: rgba(14, 18, 32, 0.3);
width: 100%;
height: 100%;
border-radius: 24px;
}
/* Verbesserte Mindmap-Knoten-Stile */
.node {
cursor: pointer;
transition: all 0.3s ease;
}
.node circle {
stroke: rgba(255, 255, 255, 0.12);
stroke-width: 2px;
fill: rgba(24, 28, 45, 0.85);
filter: url(#glass-effect);
}
.node:hover circle {
filter: url(#hover-glow);
stroke: rgba(255, 255, 255, 0.25);
}
.node.selected circle {
filter: url(#selected-glow);
stroke: rgba(179, 143, 255, 0.6);
stroke-width: 3px;
}
.node-label {
font-family: 'Inter', 'SF Pro Display', system-ui, sans-serif;
font-weight: 600;
pointer-events: none;
user-select: none;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.7);
font-size: 16px;
letter-spacing: 0.3px;
fill: #ffffff;
}
.link {
transition: stroke 0.3s ease, opacity 0.3s ease;
stroke: rgba(255, 255, 255, 0.3);
stroke-width: 2;
opacity: 0.7;
}
.link:hover, .link.highlighted {
stroke: rgba(179, 143, 255, 0.7);
opacity: 0.9;
stroke-width: 3;
}
/* Control Bar mit verbesserten Glasmorphismus und Lesbarkeit */
.controls-bar {
background: rgba(24, 28, 45, 0.85);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 20px 20px 0 0;
}
/* Tooltip Stile */
.tippy-box[data-theme~='mindmap'] {
background-color: rgba(24, 28, 45, 0.95);
color: #ffffff;
border: 1px solid rgba(179, 143, 255, 0.25);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.5), 0 0 15px rgba(179, 143, 255, 0.25);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 16px;
}
.tippy-box[data-theme~='mindmap'] .tippy-arrow {
color: rgba(24, 28, 45, 0.95);
}
.node-tooltip {
font-family: 'Inter', 'SF Pro Display', system-ui, sans-serif;
font-size: 14px;
line-height: 1.6;
padding: 12px 16px;
letter-spacing: 0.3px;
}
.node-tooltip strong {
font-weight: 600;
color: #b38fff;
}
/* Gedanken-Container */
.thought-container {
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 24px;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
background: rgba(24, 28, 45, 0.85);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
}
/* Angepasste Scrollbar für den Gedanken-Container */
.custom-scrollbar::-webkit-scrollbar {
width: 6px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.08);
border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background: rgba(179, 143, 255, 0.5);
border-radius: 3px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background: rgba(179, 143, 255, 0.7);
}
/* Pulse-Animation für leere Gedanken */
.pulse-animation {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
/* Button-Effekte mit verbesserter Lesbarkeit */
.control-btn {
background: rgba(32, 36, 55, 0.85);
color: #ffffff;
border: 1px solid rgba(255, 255, 255, 0.15);
border-radius: 16px;
padding: 0.75rem 1.5rem;
font-weight: 600;
transition: all 0.3s ease;
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
font-size: 1rem;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
letter-spacing: 0.3px;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}
.control-btn:hover {
background: rgba(179, 143, 255, 0.35);
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.35), 0 0 15px rgba(179, 143, 255, 0.25);
border: 1px solid rgba(255, 255, 255, 0.25);
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
}
.control-btn:active {
transform: translateY(1px);
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.2);
}
.control-btn.active {
background: rgba(179, 143, 255, 0.4);
border: 1px solid rgba(179, 143, 255, 0.5);
box-shadow: 0 0 15px rgba(179, 143, 255, 0.3);
}
/* Glow Effect für Buttons */
.btn-glow:hover {
box-shadow: 0 0 15px rgba(179, 143, 255, 0.5);
}
/* Light Mode Anpassungen */
html.light .mindmap-svg {
background: rgba(240, 244, 248, 0.3);
}
html.light .node circle {
fill: rgba(255, 255, 255, 0.9);
stroke: rgba(0, 0, 0, 0.1);
}
html.light .node-label {
fill: #1a202c;
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7);
}
html.light .link {
stroke: rgba(0, 0, 0, 0.2);
}
html.light .glass-card,
html.light .mindmap-card,
html.light .feature-card,
html.light .thought-container,
html.light .mindmap-header,
html.light .controls-bar {
background: rgba(255, 255, 255, 0.85);
border: 1px solid rgba(0, 0, 0, 0.08);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
}
html.light .control-btn {
background: rgba(255, 255, 255, 0.9);
color: #1a202c;
border: 1px solid rgba(0, 0, 0, 0.08);
text-shadow: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
font-weight: 600;
}
html.light .control-btn:hover {
background: rgba(179, 143, 255, 0.15);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.12);
color: #7e3ff2;
font-weight: 700;
}
html.light .control-btn.active {
background: rgba(179, 143, 255, 0.2);
border: 1px solid rgba(126, 63, 242, 0.3);
color: #7e3ff2;
font-weight: 700;
}
html.light .feature-card h3 {
color: #1a202c;
text-shadow: none;
}
html.light .feature-card p {
color: #4a5568;
text-shadow: none;
}
html.light .node-tooltip strong {
color: #7e3ff2;
}
/* Karten in der Mindmap mit verbesserten Styles */
.mindmap-card {
background: rgba(24, 28, 45, 0.75);
border-radius: 24px;
overflow: hidden;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.12);
box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
transition: all 0.3s ease;
}
.mindmap-card:hover {
transform: translateY(-5px);
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45);
background: rgba(28, 32, 52, 0.8);
}
.mindmap-card-header {
padding: 1.25rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
display: flex;
align-items: center;
justify-content: space-between;
}
.mindmap-card-body {
padding: 1.5rem;
}
.mindmap-card-footer {
padding: 1.25rem 1.5rem;
border-top: 1px solid rgba(255, 255, 255, 0.06);
display: flex;
align-items: center;
justify-content: space-between;
}
html.light .mindmap-card-header,
html.light .mindmap-card-footer {
border-color: rgba(0, 0, 0, 0.06);
}
/* Animation für die Verbindungen im Mindmap */
.link {
stroke-dasharray: 5;
animation: dash 30s linear infinite;
stroke-width: 2.5px;
}
@keyframes dash {
to {
stroke-dashoffset: 1000;
}
}
/* Move the selection panel more to the left */
.thoughts-panel {
left: 20px !important; /* Changed from right: 20px */
width: 350px !important; /* Increased from 300px for better visibility */
background: rgba(24, 28, 45, 0.85) !important; /* More visible background */
border: 1px solid rgba(179, 143, 255, 0.3) !important; /* Accent colored border */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5) !important; /* Stronger shadow */
}
/* Mindmap container with network background */
#mindmap-container::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: url('/static/network-bg.jpg');
background-size: cover;
background-position: center;
opacity: 0.2;
z-index: -1;
animation: pulse 10s ease-in-out infinite alternate;
pointer-events: none;
}
@keyframes pulse {
0% { opacity: 0.1; transform: scale(1); }
100% { opacity: 0.3; transform: scale(1.05); }
}
/* Enhance node visibility */
.node circle {
stroke-width: 3px !important;
filter: drop-shadow(0 0 8px rgba(179, 143, 255, 0.5)) !important;
}
.node.selected circle {
stroke: rgba(179, 143, 255, 0.9) !important;
stroke-width: 4px !important;
filter: drop-shadow(0 0 15px rgba(179, 143, 255, 0.8)) !important;
}
/* Improve visibility of node labels */
.node-label {
font-weight: 700 !important;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.9) !important;
filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.8)) !important;
}
/* Make connections more visible */
.link {
stroke: rgba(179, 143, 255, 0.6) !important;
stroke-width: 2.5px !important;
filter: drop-shadow(0 0 5px rgba(179, 143, 255, 0.4)) !important;
}
.link.highlighted {
stroke: rgba(88, 169, 255, 0.8) !important;
stroke-width: 4px !important;
filter: drop-shadow(0 0 8px rgba(88, 169, 255, 0.6)) !important;
}
</style>
{% endblock %}
{% block content %}
<div class="relative overflow-hidden">
<!-- Neuronales Netz / Universum Hintergrund -->
<div class="neural-universe-bg"></div>
<div class="container mx-auto px-4 py-8">
<!-- Mindmap-Visualisierung Header -->
<div class="mindmap-header p-6 mb-6">
<h2 class="text-3xl font-bold gradient-text">Wissenslandschaft erkunden</h2>
<p class="text-gray-300 mb-0">Interagiere mit der Mindmap, um Verbindungen zu entdecken und neue Ideen hinzuzufügen</p>
</div>
<!-- Mindmap-Container - Jetzt größer -->
<div class="glass-card overflow-hidden mb-12">
<div id="mindmap-container" class="relative" style="height: 80vh; min-height: 700px;">
<!-- Lade-Overlay -->
<div class="mindmap-loading absolute inset-0 flex items-center justify-center z-10" style="background: rgba(14, 18, 32, 0.7); backdrop-filter: blur(5px);">
<div class="text-center">
<div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-purple-500 mb-4"></div>
<p class="text-white text-lg">Wissenslandschaft wird geladen...</p>
<div class="w-64 h-2 bg-gray-700 rounded-full mt-4 overflow-hidden">
<div class="loading-progress h-full bg-gradient-to-r from-purple-500 to-blue-500 rounded-full" style="width: 0%"></div>
</div>
</div>
</div>
</div>
<!-- Steuerungsleiste -->
<div class="controls-bar p-4 flex flex-wrap items-center justify-between gap-3">
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="zoom-in-btn">
<i class="fas fa-search-plus mr-1"></i> Vergrößern
</button>
<button class="control-btn" id="zoom-out-btn">
<i class="fas fa-search-minus mr-1"></i> Verkleinern
</button>
<button class="control-btn" id="center-btn">
<i class="fas fa-bullseye mr-1"></i> Zentrieren
</button>
</div>
<div class="flex flex-wrap gap-2">
<button class="control-btn" id="add-thought-btn">
<i class="fas fa-plus-circle mr-1"></i> Gedanke hinzufügen
</button>
<button class="control-btn" id="connect-btn">
<i class="fas fa-link mr-1"></i> Verbinden
</button>
</div>
</div>
</div>
<!-- Visuelle Trennung -->
<div class="visual-divider"></div>
<!-- Unterer Bereich: KI-Assistenz, Suche und Lernpfade -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- KI-Assistenz -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-robot"></i>
</div>
<h3>KI-Assistenz</h3>
<p>Lass dir von künstlicher Intelligenz helfen, neue Zusammenhänge zu entdecken, Inhalte zusammenzufassen und Fragen zu beantworten.</p>
</div>
<!-- Intelligente Suche -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-search"></i>
</div>
<h3>Intelligente Suche</h3>
<p>Finde genau die Informationen, die du suchst, mit fortschrittlichen Such- und Filterfunktionen für eine präzise Navigation durch das Wissen.</p>
</div>
<!-- Geführte Pfade -->
<div class="feature-card">
<div class="feature-card-icon">
<i class="fas fa-map-signs"></i>
</div>
<h3>Geführte Pfade</h3>
<p>Folge kuratierten Lernpfaden durch komplexe Themen oder erschaffe selbst Routen für andere, die deinen Gedankengängen folgen möchten.</p>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<!-- D3.js für die Mindmap-Visualisierung -->
<script src="https://d3js.org/d3.v7.min.js"></script>
<!-- Tippy.js für verbesserte Tooltips -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tippy.js@6.3.7/dist/tippy.umd.min.js"></script>
<!-- D3-Erweiterungen für spezifische Effekte -->
<script src="{{ url_for('static', filename='d3-extensions.js') }}"></script>
<!-- Mindmap JS -->
<script src="{{ url_for('static', filename='mindmap.js') }}"></script>
<script src="{{ url_for('static', filename='network-animation.js') }}"></script>
<script>
// Dynamische Neuronen-Netz-Animation im Hintergrund
document.addEventListener('DOMContentLoaded', function() {
// Animation des neuronalen Netzwerks hinzufügen
const neuralBg = document.querySelector('.neural-universe-bg');
// Neuronenpunkte erstellen
const neuronCount = 100;
for (let i = 0; i < neuronCount; i++) {
const neuron = document.createElement('div');
neuron.className = 'neuron-point';
// Zufällige Position
const posX = Math.random() * 100;
const posY = Math.random() * 100;
const size = Math.random() * 3 + 1;
const animDuration = Math.random() * 50 + 20;
// Styling mit Glasmorphismus
neuron.style.cssText = `
position: absolute;
left: ${posX}%;
top: ${posY}%;
width: ${size}px;
height: ${size}px;
background: rgba(255, 255, 255, ${Math.random() * 0.3 + 0.1});
border-radius: 50%;
filter: blur(${Math.random() * 1}px);
box-shadow: 0 0 ${Math.random() * 10 + 5}px rgba(179, 143, 255, 0.5);
animation: pulse ${animDuration}s infinite alternate ease-in-out;
`;
neuralBg.appendChild(neuron);
}
// Verbindungen zwischen Neuronen erstellen
const connectionCount = 40;
for (let i = 0; i < connectionCount; i++) {
const connection = document.createElement('div');
connection.className = 'neuron-connection';
// Zufällige Position und Rotation für Verbindungen
const posX = Math.random() * 100;
const posY = Math.random() * 100;
const width = Math.random() * 150 + 50;
const height = Math.random() * 1 + 0.5;
const rotation = Math.random() * 360;
const opacity = Math.random() * 0.2 + 0.05;
const animDuration = Math.random() * 20 + 10;
connection.style.cssText = `
position: absolute;
left: ${posX}%;
top: ${posY}%;
width: ${width}px;
height: ${height}px;
background: linear-gradient(90deg, transparent, rgba(179, 143, 255, ${opacity}), transparent);
transform: rotate(${rotation}deg);
animation: flash ${animDuration}s infinite alternate ease-in-out;
opacity: ${opacity};
`;
neuralBg.appendChild(connection);
}
// Initialisiere die Mindmap-Visualisierung
const mindmapContainer = document.getElementById('mindmap-container');
const containerWidth = mindmapContainer.clientWidth;
const containerHeight = mindmapContainer.clientHeight;
const mindmap = new MindMapVisualization('#mindmap-container', {
width: containerWidth,
height: containerHeight,
nodeRadius: 22,
selectedNodeRadius: 28,
linkDistance: 160,
chargeStrength: -1200,
centerForce: 0.1,
tooltipEnabled: true,
onNodeClick: function(node) {
console.log('Node clicked:', node);
// Hier können spezifische Aktionen für Knotenklicks definiert werden
}
});
// Event-Listener für Steuerungsbuttons
document.getElementById('zoom-in-btn').addEventListener('click', function() {
// Zoom-In-Funktionalität
const svg = d3.select('#mindmap-container svg');
const currentZoom = d3.zoomTransform(svg.node());
const newScale = currentZoom.k * 1.3;
svg.transition().duration(300).call(
d3.zoom().transform,
d3.zoomIdentity.translate(currentZoom.x, currentZoom.y).scale(newScale)
);
});
document.getElementById('zoom-out-btn').addEventListener('click', function() {
// Zoom-Out-Funktionalität
const svg = d3.select('#mindmap-container svg');
const currentZoom = d3.zoomTransform(svg.node());
const newScale = currentZoom.k / 1.3;
svg.transition().duration(300).call(
d3.zoom().transform,
d3.zoomIdentity.translate(currentZoom.x, currentZoom.y).scale(newScale)
);
});
document.getElementById('center-btn').addEventListener('click', function() {
// Zentrieren-Funktionalität
const svg = d3.select('#mindmap-container svg');
svg.transition().duration(500).call(
d3.zoom().transform,
d3.zoomIdentity.scale(1)
);
});
// Add Thought Button
document.getElementById('add-thought-btn').addEventListener('click', function() {
// Implementierung für das Hinzufügen eines neuen Gedankens
if (mindmap.selectedNode) {
const newNodeName = prompt('Gedanke eingeben:');
if (newNodeName && newNodeName.trim() !== '') {
const newNodeId = 'node_' + Date.now();
const newNode = {
id: newNodeId,
name: newNodeName,
description: 'Neuer Gedanke',
thought_count: 0
};
// Node zur Mindmap hinzufügen
mindmap.nodes.push(newNode);
// Link zum ausgewählten Knoten erstellen
mindmap.links.push({
source: mindmap.selectedNode.id,
target: newNodeId
});
// Mindmap aktualisieren
mindmap.updateVisualization();
}
} else {
alert('Bitte zuerst einen Knoten auswählen, um einen Gedanken hinzuzufügen.');
}
});
// Connect Button
document.getElementById('connect-btn').addEventListener('click', function() {
// Implementierung für das Verbinden von Knoten
if (mindmap.selectedNode && mindmap.mouseoverNode && mindmap.selectedNode !== mindmap.mouseoverNode) {
// Prüfen, ob Verbindung bereits existiert
const existingLink = mindmap.links.find(link =>
(link.source.id === mindmap.selectedNode.id && link.target.id === mindmap.mouseoverNode.id) ||
(link.source.id === mindmap.mouseoverNode.id && link.target.id === mindmap.selectedNode.id)
);
if (!existingLink) {
// Link erstellen
mindmap.links.push({
source: mindmap.selectedNode.id,
target: mindmap.mouseoverNode.id
});
// Mindmap aktualisieren
mindmap.updateVisualization();
} else {
alert('Diese Verbindung existiert bereits.');
}
} else {
alert('Bitte wähle zwei verschiedene Knoten aus, um sie zu verbinden.');
}
});
// Responsive Anpassung bei Fenstergrößenänderung
window.addEventListener('resize', function() {
const newWidth = mindmapContainer.clientWidth;
const newHeight = mindmapContainer.clientHeight;
if (mindmap.svg) {
mindmap.svg
.attr('width', newWidth)
.attr('height', newHeight);
mindmap.width = newWidth;
mindmap.height = newHeight;
// Force-Simulation aktualisieren
if (mindmap.simulation) {
mindmap.simulation
.force('center', d3.forceCenter(newWidth / 2, newHeight / 2))
.restart();
}
}
});
});
// Animationen für die Hintergrundeffekte
document.head.insertAdjacentHTML('beforeend', `
<style>
@keyframes pulse {
0% { transform: scale(1); opacity: 0.5; }
100% { transform: scale(1.5); opacity: 0.2; }
}
@keyframes flash {
0% { opacity: 0.02; }
50% { opacity: 0.2; }
100% { opacity: 0.08; }
}
</style>
`);
</script>
{% endblock %}