Remove deprecated files and templates: Delete unused files including deployment scripts, environment configurations, and various HTML templates to streamline the project structure. This cleanup enhances maintainability and reduces clutter in the codebase.
This commit is contained in:
456
static/d3-extensions.js
vendored
Normal file
456
static/d3-extensions.js
vendored
Normal file
@@ -0,0 +1,456 @@
|
||||
/**
|
||||
* D3.js Erweiterungen für verbesserte Mindmap-Funktionalität
|
||||
* Diese Datei enthält zusätzliche Hilfsfunktionen und Erweiterungen für D3.js
|
||||
*/
|
||||
|
||||
class D3Extensions {
|
||||
/**
|
||||
* Erstellt einen verbesserten radialen Farbverlauf
|
||||
* @param {Object} defs - Das D3 defs Element
|
||||
* @param {string} id - ID für den Gradienten
|
||||
* @param {string} baseColor - Grundfarbe in hexadezimal oder RGB
|
||||
* @returns {Object} - Das erstellte Gradient-Element
|
||||
*/
|
||||
static createEnhancedRadialGradient(defs, id, baseColor) {
|
||||
// Farben berechnen
|
||||
const d3Color = d3.color(baseColor);
|
||||
const lightColor = d3Color.brighter(0.7);
|
||||
const darkColor = d3Color.darker(0.3);
|
||||
const midColor = d3Color;
|
||||
|
||||
// Gradient erstellen
|
||||
const gradient = defs.append('radialGradient')
|
||||
.attr('id', id)
|
||||
.attr('cx', '30%')
|
||||
.attr('cy', '30%')
|
||||
.attr('r', '70%');
|
||||
|
||||
// Farbstops hinzufügen für realistischeren Verlauf
|
||||
gradient.append('stop')
|
||||
.attr('offset', '0%')
|
||||
.attr('stop-color', lightColor.formatHex());
|
||||
|
||||
gradient.append('stop')
|
||||
.attr('offset', '50%')
|
||||
.attr('stop-color', midColor.formatHex());
|
||||
|
||||
gradient.append('stop')
|
||||
.attr('offset', '100%')
|
||||
.attr('stop-color', darkColor.formatHex());
|
||||
|
||||
return gradient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen Glüheffekt-Filter
|
||||
* @param {Object} defs - D3-Referenz auf den defs-Bereich
|
||||
* @param {String} id - ID des Filters
|
||||
* @param {String} color - Farbe des Glüheffekts (Hex-Code)
|
||||
* @param {Number} strength - Stärke des Glüheffekts
|
||||
* @returns {Object} D3-Referenz auf den erstellten Filter
|
||||
*/
|
||||
static createGlowFilter(defs, id, color = '#b38fff', strength = 5) {
|
||||
const filter = defs.append('filter')
|
||||
.attr('id', id)
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '200%')
|
||||
.attr('height', '200%');
|
||||
|
||||
// Unschärfe-Effekt
|
||||
filter.append('feGaussianBlur')
|
||||
.attr('in', 'SourceGraphic')
|
||||
.attr('stdDeviation', strength)
|
||||
.attr('result', 'blur');
|
||||
|
||||
// Farbverstärkung für den Glüheffekt
|
||||
filter.append('feColorMatrix')
|
||||
.attr('in', 'blur')
|
||||
.attr('type', 'matrix')
|
||||
.attr('values', '0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 18 -7')
|
||||
.attr('result', 'glow');
|
||||
|
||||
// Farbflut mit der angegebenen Farbe
|
||||
filter.append('feFlood')
|
||||
.attr('flood-color', color)
|
||||
.attr('flood-opacity', '0.7')
|
||||
.attr('result', 'color');
|
||||
|
||||
// Zusammensetzen des Glüheffekts mit der Farbe
|
||||
filter.append('feComposite')
|
||||
.attr('in', 'color')
|
||||
.attr('in2', 'glow')
|
||||
.attr('operator', 'in')
|
||||
.attr('result', 'glow-color');
|
||||
|
||||
// Zusammenfügen aller Ebenen
|
||||
const feMerge = filter.append('feMerge');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'glow-color');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'SourceGraphic');
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet eine konsistente Farbe aus einem String
|
||||
* @param {string} str - Eingabestring
|
||||
* @returns {string} - Generierte Farbe als Hex-String
|
||||
*/
|
||||
static stringToColor(str) {
|
||||
let hash = 0;
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||
}
|
||||
|
||||
// Basis-Farbpalette für konsistente Farben
|
||||
const colorPalette = [
|
||||
"#4299E1", // Blau
|
||||
"#9F7AEA", // Lila
|
||||
"#ED64A6", // Pink
|
||||
"#48BB78", // Grün
|
||||
"#ECC94B", // Gelb
|
||||
"#F56565", // Rot
|
||||
"#38B2AC", // Türkis
|
||||
"#ED8936", // Orange
|
||||
"#667EEA", // Indigo
|
||||
];
|
||||
|
||||
// Farbe aus der Palette wählen basierend auf dem Hash
|
||||
const colorIndex = Math.abs(hash) % colorPalette.length;
|
||||
return colorPalette[colorIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen Schatteneffekt-Filter
|
||||
* @param {Object} defs - D3-Referenz auf den defs-Bereich
|
||||
* @param {String} id - ID des Filters
|
||||
* @returns {Object} D3-Referenz auf den erstellten Filter
|
||||
*/
|
||||
static createShadowFilter(defs, id) {
|
||||
const filter = defs.append('filter')
|
||||
.attr('id', id)
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '200%')
|
||||
.attr('height', '200%');
|
||||
|
||||
// Einfacher Schlagschatten
|
||||
filter.append('feDropShadow')
|
||||
.attr('dx', 0)
|
||||
.attr('dy', 4)
|
||||
.attr('stdDeviation', 4)
|
||||
.attr('flood-color', 'rgba(0, 0, 0, 0.3)');
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen Glasmorphismus-Effekt-Filter
|
||||
* @param {Object} defs - D3-Referenz auf den defs-Bereich
|
||||
* @param {String} id - ID des Filters
|
||||
* @returns {Object} D3-Referenz auf den erstellten Filter
|
||||
*/
|
||||
static createGlassMorphismFilter(defs, id) {
|
||||
const filter = defs.append('filter')
|
||||
.attr('id', id)
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '200%')
|
||||
.attr('height', '200%');
|
||||
|
||||
// Hintergrund-Unschärfe für den Glaseffekt
|
||||
filter.append('feGaussianBlur')
|
||||
.attr('in', 'SourceGraphic')
|
||||
.attr('stdDeviation', 8)
|
||||
.attr('result', 'blur');
|
||||
|
||||
// Hellere Farbe für den Glaseffekt
|
||||
filter.append('feColorMatrix')
|
||||
.attr('in', 'blur')
|
||||
.attr('type', 'matrix')
|
||||
.attr('values', '1 0 0 0 0.1 0 1 0 0 0.1 0 0 1 0 0.1 0 0 0 0.6 0')
|
||||
.attr('result', 'glass');
|
||||
|
||||
// Überlagerung mit dem Original
|
||||
const feMerge = filter.append('feMerge');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'glass');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'SourceGraphic');
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen verstärkten Glasmorphismus-Effekt mit Farbverlauf
|
||||
* @param {Object} defs - D3-Referenz auf den defs-Bereich
|
||||
* @param {String} id - ID des Filters
|
||||
* @param {String} color1 - Erste Farbe des Verlaufs (Hex-Code)
|
||||
* @param {String} color2 - Zweite Farbe des Verlaufs (Hex-Code)
|
||||
* @returns {Object} D3-Referenz auf den erstellten Filter
|
||||
*/
|
||||
static createEnhancedGlassMorphismFilter(defs, id, color1 = '#b38fff', color2 = '#58a9ff') {
|
||||
// Farbverlauf für den Glaseffekt definieren
|
||||
const gradientId = `gradient-${id}`;
|
||||
const gradient = defs.append('linearGradient')
|
||||
.attr('id', gradientId)
|
||||
.attr('x1', '0%')
|
||||
.attr('y1', '0%')
|
||||
.attr('x2', '100%')
|
||||
.attr('y2', '100%');
|
||||
|
||||
gradient.append('stop')
|
||||
.attr('offset', '0%')
|
||||
.attr('stop-color', color1)
|
||||
.attr('stop-opacity', '0.3');
|
||||
|
||||
gradient.append('stop')
|
||||
.attr('offset', '100%')
|
||||
.attr('stop-color', color2)
|
||||
.attr('stop-opacity', '0.3');
|
||||
|
||||
// Filter erstellen
|
||||
const filter = defs.append('filter')
|
||||
.attr('id', id)
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '200%')
|
||||
.attr('height', '200%');
|
||||
|
||||
// Hintergrund-Unschärfe
|
||||
filter.append('feGaussianBlur')
|
||||
.attr('in', 'SourceGraphic')
|
||||
.attr('stdDeviation', 6)
|
||||
.attr('result', 'blur');
|
||||
|
||||
// Farbverlauf einfügen
|
||||
const feImage = filter.append('feImage')
|
||||
.attr('xlink:href', `#${gradientId}`)
|
||||
.attr('result', 'gradient')
|
||||
.attr('x', '0%')
|
||||
.attr('y', '0%')
|
||||
.attr('width', '100%')
|
||||
.attr('height', '100%')
|
||||
.attr('preserveAspectRatio', 'none');
|
||||
|
||||
// Zusammenfügen aller Ebenen
|
||||
const feMerge = filter.append('feMerge');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'blur');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'gradient');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'SourceGraphic');
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen 3D-Glaseffekt mit verbesserter Tiefe und Reflexionen
|
||||
* @param {Object} defs - D3-Referenz auf den defs-Bereich
|
||||
* @param {String} id - ID des Filters
|
||||
* @returns {Object} D3-Referenz auf den erstellten Filter
|
||||
*/
|
||||
static create3DGlassEffect(defs, id) {
|
||||
const filter = defs.append('filter')
|
||||
.attr('id', id)
|
||||
.attr('x', '-50%')
|
||||
.attr('y', '-50%')
|
||||
.attr('width', '200%')
|
||||
.attr('height', '200%');
|
||||
|
||||
// Farbmatrix für Transparenz
|
||||
filter.append('feColorMatrix')
|
||||
.attr('type', 'matrix')
|
||||
.attr('in', 'SourceGraphic')
|
||||
.attr('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.7 0')
|
||||
.attr('result', 'transparent');
|
||||
|
||||
// Hintergrund-Unschärfe für Tiefe
|
||||
filter.append('feGaussianBlur')
|
||||
.attr('in', 'transparent')
|
||||
.attr('stdDeviation', '4')
|
||||
.attr('result', 'blurred');
|
||||
|
||||
// Lichtquelle und Schattierung hinzufügen
|
||||
const lightSource = filter.append('feSpecularLighting')
|
||||
.attr('in', 'blurred')
|
||||
.attr('surfaceScale', '6')
|
||||
.attr('specularConstant', '1')
|
||||
.attr('specularExponent', '30')
|
||||
.attr('lighting-color', '#ffffff')
|
||||
.attr('result', 'specular');
|
||||
|
||||
lightSource.append('fePointLight')
|
||||
.attr('x', '100')
|
||||
.attr('y', '100')
|
||||
.attr('z', '200');
|
||||
|
||||
// Lichtreflexion verstärken
|
||||
filter.append('feComposite')
|
||||
.attr('in', 'specular')
|
||||
.attr('in2', 'SourceGraphic')
|
||||
.attr('operator', 'in')
|
||||
.attr('result', 'specularHighlight');
|
||||
|
||||
// Inneren Schatten erzeugen
|
||||
const innerShadow = filter.append('feOffset')
|
||||
.attr('in', 'SourceAlpha')
|
||||
.attr('dx', '0')
|
||||
.attr('dy', '1')
|
||||
.attr('result', 'offsetblur');
|
||||
|
||||
innerShadow.append('feGaussianBlur')
|
||||
.attr('in', 'offsetblur')
|
||||
.attr('stdDeviation', '2')
|
||||
.attr('result', 'innerShadow');
|
||||
|
||||
filter.append('feComposite')
|
||||
.attr('in', 'innerShadow')
|
||||
.attr('in2', 'SourceGraphic')
|
||||
.attr('operator', 'out')
|
||||
.attr('result', 'innerShadowEffect');
|
||||
|
||||
// Schichten kombinieren
|
||||
const feMerge = filter.append('feMerge');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'blurred');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'innerShadowEffect');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'specularHighlight');
|
||||
feMerge.append('feMergeNode')
|
||||
.attr('in', 'SourceGraphic');
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt einen Partikelsystem-Effekt für interaktive Knoten hinzu
|
||||
* @param {Object} parent - Das übergeordnete SVG-Element
|
||||
* @param {number} x - X-Koordinate des Zentrums
|
||||
* @param {number} y - Y-Koordinate des Zentrums
|
||||
* @param {string} color - Partikelfarbe (Hex-Code)
|
||||
* @param {number} count - Anzahl der Partikel
|
||||
*/
|
||||
static createParticleEffect(parent, x, y, color = '#b38fff', count = 5) {
|
||||
const particles = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const particle = parent.append('circle')
|
||||
.attr('cx', x)
|
||||
.attr('cy', y)
|
||||
.attr('r', 0)
|
||||
.attr('fill', color)
|
||||
.style('opacity', 0.8);
|
||||
|
||||
particles.push(particle);
|
||||
|
||||
// Partikel animieren
|
||||
animateParticle(particle);
|
||||
}
|
||||
|
||||
function animateParticle(particle) {
|
||||
// Zufällige Richtung und Geschwindigkeit
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const speed = 1 + Math.random() * 2;
|
||||
const distance = 20 + Math.random() * 30;
|
||||
|
||||
// Zielposition berechnen
|
||||
const targetX = x + Math.cos(angle) * distance;
|
||||
const targetY = y + Math.sin(angle) * distance;
|
||||
|
||||
// Animation mit zufälliger Dauer
|
||||
const duration = 1000 + Math.random() * 500;
|
||||
|
||||
particle
|
||||
.attr('r', 0)
|
||||
.style('opacity', 0.8)
|
||||
.transition()
|
||||
.duration(duration)
|
||||
.attr('cx', targetX)
|
||||
.attr('cy', targetY)
|
||||
.attr('r', 2 + Math.random() * 3)
|
||||
.style('opacity', 0)
|
||||
.on('end', function() {
|
||||
// Partikel entfernen
|
||||
particle.remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt eine Pulsanimation auf einem Knoten durch
|
||||
* @param {Object} node - D3-Knoten-Selektion
|
||||
* @returns {void}
|
||||
*/
|
||||
static pulseAnimation(node) {
|
||||
if (!node) return;
|
||||
|
||||
const circle = node.select('circle');
|
||||
const originalRadius = parseFloat(circle.attr('r'));
|
||||
const originalFill = circle.attr('fill');
|
||||
|
||||
// Pulsanimation
|
||||
circle
|
||||
.transition()
|
||||
.duration(400)
|
||||
.attr('r', originalRadius * 1.3)
|
||||
.attr('fill', '#b38fff')
|
||||
.transition()
|
||||
.duration(400)
|
||||
.attr('r', originalRadius)
|
||||
.attr('fill', originalFill);
|
||||
}
|
||||
|
||||
/**
|
||||
* Berechnet eine adaptive Schriftgröße basierend auf der Textlänge
|
||||
* @param {string} text - Der anzuzeigende Text
|
||||
* @param {number} maxSize - Maximale Schriftgröße in Pixel
|
||||
* @param {number} minSize - Minimale Schriftgröße in Pixel
|
||||
* @returns {number} - Die berechnete Schriftgröße
|
||||
*/
|
||||
static getAdaptiveFontSize(text, maxSize = 14, minSize = 10) {
|
||||
if (!text) return maxSize;
|
||||
|
||||
// Linear die Schriftgröße basierend auf der Textlänge anpassen
|
||||
const length = text.length;
|
||||
if (length <= 6) return maxSize;
|
||||
if (length >= 20) return minSize;
|
||||
|
||||
// Lineare Interpolation
|
||||
const factor = (length - 6) / (20 - 6);
|
||||
return maxSize - factor * (maxSize - minSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt einen Pulsierenden Effekt zu einer Selektion hinzu
|
||||
* @param {Object} selection - D3-Selektion
|
||||
* @param {number} duration - Dauer eines Puls-Zyklus in ms
|
||||
* @param {number} minOpacity - Minimale Opazität
|
||||
* @param {number} maxOpacity - Maximale Opazität
|
||||
*/
|
||||
static addPulseEffect(selection, duration = 1500, minOpacity = 0.4, maxOpacity = 0.9) {
|
||||
function pulse() {
|
||||
selection
|
||||
.transition()
|
||||
.duration(duration / 2)
|
||||
.style('opacity', minOpacity)
|
||||
.transition()
|
||||
.duration(duration / 2)
|
||||
.style('opacity', maxOpacity)
|
||||
.on('end', pulse);
|
||||
}
|
||||
|
||||
// Initialen Stil setzen
|
||||
selection.style('opacity', maxOpacity);
|
||||
|
||||
// Pulsanimation starten
|
||||
pulse();
|
||||
}
|
||||
}
|
||||
|
||||
// Globale Verfügbarkeit sicherstellen
|
||||
window.D3Extensions = D3Extensions;
|
||||
Reference in New Issue
Block a user