0 votes
in SoSci Survey (dt.) by s287096 (110 points)

Ich habe relativ komplexen Code zur Erstellung einer Mindmap und habe das Problem, dass es sich nicht speichern lässt über eine interne Variable.

In der Mindmap sollen die Probanden neue Begriffe hinzufügen können und diese frei mit Pfeilen verbinden können. Gibt es die Möglichkeit diese neu erstellte Mindmap speichern zu lassen, da es keine festen "Felder" gibt in denen Text eingegeben wird, sondern es relativ frei erstellt wird mit Javascript.

Der Code zu der Mindmap, falls das weiterhilft:


Interaktive Mindmap

    body {
        font-family: Arial, sans-serif;
    }
    #mindmap {
        position: relative;
        width: 100%;
        height: 500px;
        border: 1px solid #ccc;
        overflow: hidden;
    }
    .node {
        position: absolute;
        padding: 10px;
        background-color: #f9f9f9;
        border: 1px solid #ddd;
        cursor: move;
        border-radius: 5px;
        user-select: none;
        z-index: 2; /* Stellen Sie sicher, dass die Knoten über den Pfeilen gerendert werden */
    }
    .node[contenteditable]:focus {
        border-color: #aaa;
    }
    .line {
        position: absolute;
        border: 1px solid #000;
        z-index: 1; /* Stellen Sie sicher, dass die Linien unter den Knoten gerendert werden */
    }
    .arrow {
        position: absolute;
        width: 0;
        height: 0;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        border-bottom: 10px solid #000;
        z-index: 0; /* Stellen Sie sicher, dass die Pfeile unter den Linien und Knoten gerendert werden */
    }


Interaktive Mindmap






    let nodeId = 0;
    let nodes = [];
    let arrows = []; // Array für Pfeile
    let currentNode = null;
    let offsetX = 0;
    let offsetY = 0;
    let startNode = null;
    let endNode = null;

    function initMindmap() {
        const mindmap = document.getElementById('mindmap');
        const initialNode = createNode('Gehalt einer Person');
        initialNode.style.top = (mindmap.offsetHeight / 2 - 25) + 'px';
        initialNode.style.left = (mindmap.offsetWidth / 2 - 50) + 'px';
        mindmap.appendChild(initialNode);
        nodes.push(initialNode);
    }

    function createNode(text) {
        const node = document.createElement('div');
        node.className = 'node';
        node.id = 'node' + nodeId;
        node.draggable = true;
        node.contentEditable = true;
        node.innerText = text;
        node.addEventListener('mousedown', onMouseDown);
        node.addEventListener('contextmenu', onRightClick);
        node.addEventListener('blur', updateLines);
        nodeId++;
        return node;
    }

    function addNode(event) {
        event.preventDefault();
        const mindmap = document.getElementById('mindmap');
        const node = createNode('Begriff ' + nodeId);
        node.style.top = '50px';
        node.style.left = '50px';
        mindmap.appendChild(node);
        nodes.push(node);
    }

    function onMouseDown(event) {
        if (event.button === 0) { // Linksklick
            currentNode = event.target;
            const rect = currentNode.getBoundingClientRect();
            offsetX = event.clientX - rect.left;
            offsetY = event.clientY - rect.top;
            document.addEventListener('mousemove', onMouseMove);
            document.addEventListener('mouseup', onMouseUp);
        }
    }

    function onRightClick(event) {
        event.preventDefault();
        if (!startNode) {
            startNode = event.target;
        } else if (!endNode) {
            endNode = event.target;
        }
    }

    function removeArrow(event) {
        event.preventDefault();
        const arrowToRemove = arrows.find(arrow => {
            return (arrow.startNode === startNode && arrow.endNode === endNode) ||
                   (arrow.startNode === endNode && arrow.endNode === startNode);
        });

        if (arrowToRemove) {
            arrowToRemove.line.remove();
            arrowToRemove.arrow.remove();
            arrows = arrows.filter(arrow => arrow !== arrowToRemove);
        }

        startNode = null;
        endNode = null;
    }

    function onMouseMove(event) {
        if (currentNode) {
            const mindmapRect = document.getElementById
            ('mindmap').getBoundingClientRect();
            currentNode.style.left = (event.clientX - mindmapRect.left - offsetX) + 'px';
            currentNode.style.top = (event.clientY - mindmapRect.top - offsetY) + 'px';
            updateLines();
        }
    }

    function onMouseUp() {
        document.removeEventListener('mousemove', onMouseMove);
        document.removeEventListener('mouseup', onMouseUp);
        currentNode = null;
    }

    function createArrow(event) {
        event.preventDefault();
        if (startNode && endNode) {
            const mindmap = document.getElementById('mindmap');
            const line = document.createElement('div');
            line.className = 'line';

            const rect1 = startNode.getBoundingClientRect();
            const rect2 = endNode.getBoundingClientRect();
            let x1, y1, x2, y2;

            if (rect1.top < rect2.top) {
                // Startpunkt am unteren Rand der ersten Box
                x1 = rect1.left + rect1.width / 2 - mindmap.getBoundingClientRect().left;
                y1 = rect1.top + rect1.height - mindmap.getBoundingClientRect().top;
                // Endpunkt am oberen Rand der zweiten Box
                x2 = rect2.left + rect2.width / 2 - mindmap.getBoundingClientRect().left;
                y2 = rect2.top - mindmap.getBoundingClientRect().top;
            } else {
                // Startpunkt am oberen Rand der ersten Box
                x1 = rect1.left + rect1.width / 2 - mindmap.getBoundingClientRect().left;
                y1 = rect1.top - mindmap.getBoundingClientRect().top;
                // Endpunkt am unteren Rand der zweiten Box
                x2 = rect2.left + rect2.width / 2 - mindmap.getBoundingClientRect().left;
                y2 = rect2.top + rect2.height - mindmap.getBoundingClientRect().top;
            }

            const length = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
            const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;

            line.style.width = length + 'px';
            line.style.transform = `rotate(${angle}deg)`;
            line.style.transformOrigin = '0 0';
            line.style.position = 'absolute';
            line.style.left = x1 + 'px';
            line.style.top = y1 + 'px';

            mindmap.appendChild(line);

            const arrow = document.createElement('div');
            arrow.className = 'arrow';
            arrow.style.left = (x2 - 5) + 'px'; // adjust for arrow width
            arrow.style.top = (y2 - 10) + 'px'; // adjust for arrow height
            arrow.style.transform = `rotate(${angle}deg)`;
            mindmap.appendChild(arrow);

            arrows.push({ line, arrow, startNode, endNode });

            startNode = null;
            endNode = null;
        } else {
            alert('Bitte wählen Sie zwei Boxen aus, indem Sie sie mit der rechten Maustaste anklicken.');
        }
    }

    function updateLines() {
        arrows.forEach(arrow => {
            const rect1 = arrow.startNode.getBoundingClientRect();
            const rect2 = arrow.endNode.getBoundingClientRect();
            let x1, y1, x2, y2;

            if (rect1.top < rect2.top) {
                // Startpunkt am unteren Rand der ersten Box
                x1 = rect1.left + rect1.width / 2 - mindmap.getBoundingClientRect().left;
                y1 = rect1.top + rect1.height - mindmap.getBoundingClientRect().top;
                // Endpunkt am oberen Rand der zweiten Box
                x2 = rect2.left + rect2.width / 2 - mindmap.getBoundingClientRect().left;
                y2 = rect2.top - mindmap.getBoundingClientRect().top;
            } else {
                // Startpunkt am oberen Rand der ersten Box
                x1 = rect1.left + rect1.width / 2 - mindmap.getBoundingClientRect().left;
                y1 = rect1.top - mindmap.getBoundingClientRect().top;
                // Endpunkt am unteren Rand der zweiten Box
                x2 = rect2.left + rect2.width / 2 - mindmap.getBoundingClientRect().left;
                y2 = rect2.top + rect2.height - mindmap.getBoundingClientRect().top;
            }

            const length = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
            const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;

            arrow.line.style.width = length + 'px';
            arrow.line.style.transform = `rotate(${angle}deg)`;
            arrow.line.style.left = x1 + 'px';
            arrow.line.style.top = y1 + 'px';

            arrow.arrow.style.left = (x2 - 5) + 'px'; // adjust for arrow width
            arrow.arrow.style.top = (y2 - 10) + 'px'; // adjust for arrow height
            arrow.arrow.style.transform = `rotate(${angle}deg)`;
        });
    }

    document.getElementById('addNodeButton').addEventListener('click', addNode);
    document.getElementById('addArrowButton').addEventListener('click', createArrow);
    document.getElementById('removeArrowButton').addEventListener('click', removeArrow);

    window.onload = initMindmap;


1 Answer

0 votes
by SoSci Survey (327k points)

Es scheint so, dass die Mindmap in den Variablen nodes und arrows gespeichert wird. Diese beiden Variablen können Sie über JSON.stringify() in einen String umwandeln, den Sie dann in die interne Variable speichern können.

Sie müssten also lediglich nach jeder Zeile im Code, welche eine der beiden Variablen verändert, eine Funktion aufrufen, welche ungefähr das hier macht:

var intVarNodes = document.getElementById("IV01_01");
intVarNodes.value = JSON.stringify(nodes);
var intVarArrows = document.getElementById("IV01_02");
intVarArrows .value = JSON.stringify(nodes);

Willkommen im Online-Support von SoSci Survey.

Hier bekommen Sie schnelle und fundierte Antworten von anderen Projektleitern und direkt von SoSci Survey.

→ Eine Frage stellen


Welcome to the SoSci Survey online support.

Simply ask a question to quickly get answers from other professionals, and directly from SoSci Survey.

→ Ask a Question

...