219 lines
5.5 KiB
JavaScript
219 lines
5.5 KiB
JavaScript
/**
|
|
* Mindmap Interaction Enhancement
|
|
* Verbessert die Interaktion mit der Mindmap und steuert die Seitenleisten-Anzeige
|
|
*/
|
|
|
|
// Globale Variablen
|
|
let selectedNode = null;
|
|
let isLegendVisible = true;
|
|
|
|
// Initialisierung der Mindmap
|
|
document.addEventListener('mindmap-loaded', function() {
|
|
const cy = window.cy;
|
|
if (!cy) return;
|
|
|
|
// Event-Listener für Knoten-Klicks
|
|
cy.on('tap', 'node', function(evt) {
|
|
const node = evt.target;
|
|
|
|
// Alle vorherigen Hervorhebungen zurücksetzen
|
|
cy.nodes().forEach(n => {
|
|
n.removeStyle();
|
|
n.connectedEdges().removeStyle();
|
|
});
|
|
|
|
// Speichere ausgewählten Knoten
|
|
selectedNode = node;
|
|
|
|
// Aktiviere leuchtenden Effekt statt Umkreisung
|
|
node.style({
|
|
'background-opacity': 1,
|
|
'background-color': node.data('color'),
|
|
'shadow-color': node.data('color'),
|
|
'shadow-opacity': 1,
|
|
'shadow-blur': 15,
|
|
'shadow-offset-x': 0,
|
|
'shadow-offset-y': 0
|
|
});
|
|
|
|
// Verbundene Kanten und Knoten hervorheben
|
|
const connectedEdges = node.connectedEdges();
|
|
const connectedNodes = node.neighborhood('node');
|
|
|
|
connectedEdges.style({
|
|
'line-color': '#a78bfa',
|
|
'target-arrow-color': '#a78bfa',
|
|
'source-arrow-color': '#a78bfa',
|
|
'line-opacity': 0.8,
|
|
'width': 2
|
|
});
|
|
|
|
connectedNodes.style({
|
|
'shadow-opacity': 0.7,
|
|
'shadow-blur': 10,
|
|
'shadow-color': '#a78bfa'
|
|
});
|
|
|
|
// Info-Panel aktualisieren
|
|
updateInfoPanel(node);
|
|
|
|
// Seitenleiste aktualisieren
|
|
updateSidebar(node);
|
|
});
|
|
|
|
// Klick auf Hintergrund - Auswahl zurücksetzen
|
|
cy.on('tap', function(evt) {
|
|
if (evt.target === cy) {
|
|
resetSelection(cy);
|
|
}
|
|
});
|
|
|
|
// Zoom-Controls
|
|
document.getElementById('zoomIn')?.addEventListener('click', () => {
|
|
cy.zoom({
|
|
level: cy.zoom() * 1.2,
|
|
renderedPosition: { x: cy.width() / 2, y: cy.height() / 2 }
|
|
});
|
|
});
|
|
|
|
document.getElementById('zoomOut')?.addEventListener('click', () => {
|
|
cy.zoom({
|
|
level: cy.zoom() / 1.2,
|
|
renderedPosition: { x: cy.width() / 2, y: cy.height() / 2 }
|
|
});
|
|
});
|
|
|
|
document.getElementById('resetView')?.addEventListener('click', () => {
|
|
cy.fit();
|
|
resetSelection(cy);
|
|
});
|
|
|
|
// Legend-Toggle
|
|
document.getElementById('toggleLegend')?.addEventListener('click', () => {
|
|
const legend = document.getElementById('categoryLegend');
|
|
if (legend) {
|
|
isLegendVisible = !isLegendVisible;
|
|
legend.style.display = isLegendVisible ? 'block' : 'none';
|
|
}
|
|
});
|
|
|
|
// Keyboard-Controls
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === '+' || e.key === '=') {
|
|
cy.zoom({
|
|
level: cy.zoom() * 1.2,
|
|
renderedPosition: { x: cy.width() / 2, y: cy.height() / 2 }
|
|
});
|
|
} else if (e.key === '-' || e.key === '_') {
|
|
cy.zoom({
|
|
level: cy.zoom() / 1.2,
|
|
renderedPosition: { x: cy.width() / 2, y: cy.height() / 2 }
|
|
});
|
|
} else if (e.key === 'Escape') {
|
|
resetSelection(cy);
|
|
}
|
|
});
|
|
});
|
|
|
|
/**
|
|
* Aktualisiert das Info-Panel mit Knoteninformationen
|
|
* @param {Object} node - Der ausgewählte Knoten
|
|
*/
|
|
function updateInfoPanel(node) {
|
|
const infoPanel = document.getElementById('infoPanel');
|
|
if (!infoPanel) return;
|
|
|
|
const data = node.data();
|
|
const connectedNodes = node.neighborhood('node');
|
|
|
|
let html = `
|
|
<h3>${data.label || data.name}</h3>
|
|
<p class="category">${data.category || 'Keine Kategorie'}</p>
|
|
${data.description ? `<p class="description">${data.description}</p>` : ''}
|
|
<div class="connections">
|
|
<h4>Verbindungen (${connectedNodes.length})</h4>
|
|
<ul>
|
|
`;
|
|
|
|
connectedNodes.forEach(connectedNode => {
|
|
const connectedData = connectedNode.data();
|
|
html += `
|
|
<li style="color: ${connectedData.color || '#60a5fa'}">
|
|
${connectedData.label || connectedData.name}
|
|
</li>
|
|
`;
|
|
});
|
|
|
|
html += `
|
|
</ul>
|
|
</div>
|
|
`;
|
|
|
|
infoPanel.innerHTML = html;
|
|
infoPanel.style.display = 'block';
|
|
}
|
|
|
|
/**
|
|
* Aktualisiert die Seitenleiste mit Knoteninformationen
|
|
* @param {Object} node - Der ausgewählte Knoten
|
|
*/
|
|
function updateSidebar(node) {
|
|
const sidebar = document.getElementById('sidebar');
|
|
if (!sidebar) return;
|
|
|
|
const data = node.data();
|
|
const connectedNodes = node.neighborhood('node');
|
|
|
|
let html = `
|
|
<div class="node-details">
|
|
<h3>${data.label || data.name}</h3>
|
|
<p class="category">${data.category || 'Keine Kategorie'}</p>
|
|
${data.description ? `<p class="description">${data.description}</p>` : ''}
|
|
<div class="connections">
|
|
<h4>Verbindungen (${connectedNodes.length})</h4>
|
|
<ul>
|
|
`;
|
|
|
|
connectedNodes.forEach(connectedNode => {
|
|
const connectedData = connectedNode.data();
|
|
html += `
|
|
<li style="color: ${connectedData.color || '#60a5fa'}">
|
|
${connectedData.label || connectedData.name}
|
|
</li>
|
|
`;
|
|
});
|
|
|
|
html += `
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
sidebar.innerHTML = html;
|
|
}
|
|
|
|
/**
|
|
* Setzt die Auswahl zurück
|
|
* @param {Object} cy - Cytoscape-Instanz
|
|
*/
|
|
function resetSelection(cy) {
|
|
selectedNode = null;
|
|
|
|
// Alle Hervorhebungen zurücksetzen
|
|
cy.nodes().forEach(node => {
|
|
node.removeStyle();
|
|
node.connectedEdges().removeStyle();
|
|
});
|
|
|
|
// Info-Panel ausblenden
|
|
const infoPanel = document.getElementById('infoPanel');
|
|
if (infoPanel) {
|
|
infoPanel.style.display = 'none';
|
|
}
|
|
|
|
// Seitenleiste leeren
|
|
const sidebar = document.getElementById('sidebar');
|
|
if (sidebar) {
|
|
sidebar.innerHTML = '';
|
|
}
|
|
}
|