Community
    • Categories
    • Recent
    • Popular
    • Users
    • Search
    • Register
    • Login

    Switch Ports Sortierung

    Scheduled Pinned Locked Moved Betrieb
    13 Posts 2 Posters 527 Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • StefanP74S Offline
      StefanP74 @LFischer
      last edited by

      Hallo @LFischer,

      danke für die Info, ich verstehe es nur nicht ganz ... seitens der Programmierlogik.
      Meine Gedanken zu dem Thema, vielleicht sehe ich das auch zu locker. 😉

      Wenn ich einen Eingang mit einem Ausgang verbunden habe, dann ist nur die Sortierung der Eingänge (also links) nötig, da die beiden mit einander verbunden sind und der Ausgang entsprechend gereiht wird, anhand der Abhängigkeit zum Eingang.

      Hat ein Eingang mehrere Ausgänge, dann werden zusätzlich die Ausgänge mit Abhängigkeit zum jeweiligen Eingang, ebenso sortiert.

      Hat ein Eingang keine Abhängigkeit zu einem Ausgang, dann werden diese zB. unten, aber dennoch sortiert angezeigt, Eingang wie auch Ausgang.

      LG Stefan

      LFischerL 1 Reply Last reply Reply Quote 0
      • LFischerL Offline
        LFischer @StefanP74
        last edited by

        Hallo @StefanP74

        ich glaube genau dieser Fall wird aktuell nicht berücksichtigt 🤔

        Hat ein Eingang mehrere Ausgänge, dann werden zusätzlich die Ausgänge mit Abhängigkeit zum jeweiligen Eingang, ebenso sortiert.

        Ich werde mir das aber noch mal lokal nachbauen und anschauen. Vielleicht lässt es sich ja doch noch irgendwie einbauen ohne etwas anderes kaputt zu machen 😉

        Viele Grüße
        Leo

        StefanP74S 1 Reply Last reply Reply Quote 0
        • StefanP74S Offline
          StefanP74 @LFischer
          last edited by

          Hallo @LFischer,

          ich lege meine Hoffnung in deine Hände 😁
          Danke, wäre toll wenn das klappen würde.

          LG Stefan

          LFischerL 1 Reply Last reply Reply Quote 0
          • LFischerL Offline
            LFischer @StefanP74
            last edited by LFischer

            Hey @StefanP74

            ich glaube ich habe etwas gefunden - könntest du das vielleicht kurz bei dir ausprobieren und schauen ob es ggf. zu unerwünschten Seiteneffekten kommt? Ich habe das mit der Add-on Version 1.4 geprüft.

            Dazu bitte in die folgende Datei navigieren (ausgehend vom i-doit Verzeichnis) src/classes/modules/cabling/assets/js/cabling.js

            Hier auf Zeile 254 steht folgendes:

            // Then sort by "toIndex" to keep internally wired connectors near by each other.
            if (a.data.toIndex && b.data.toIndex) {
                return a.data.toIndex - b.data.toIndex
            }
            

            Das bitte mal mit folgender kleinen Änderung anpassen:

            // Then sort by "toIndex" to keep internally wired connectors near by each other.
            if (a.data.toIndex && b.data.toIndex && a.data.toIndex !== b.data.toIndex) {
                return a.data.toIndex - b.data.toIndex
            }
            

            Das Problem ist nämlich das die Ausgänge alle auf den gleichen Eingang zeigen - bedeutet hier das der a.data.toIndex und b.data.toIndex den identischen Wert beinhalten. Das Ergebnis der Sortierung ist in diesem Fall 0 was so viel heißt wie: "Bleib wo du bist".

            In diesem Fall soll aber die Sortierung nach Namen übernehmen. Aus diesem Grund ergänzen wir die Bedingung um a.data.toIndex ist ungleich b.data.toIndex.

            Wenn das soweit passt würde ich das im Code übernehmen sodass diese Anpassung in der nächsten Version landet 🙂

            Viele Grüße
            Leo

            StefanP74S 1 Reply Last reply Reply Quote 0
            • StefanP74S Offline
              StefanP74 @LFischer
              last edited by

              Hallo @LFischer,

              best support ever! 😄 👍
              Funktioniert hervorragend, sehr fein, danke.

              idoit_port_no_20240930_01.JPG

              Super, danke.
              Ich konnte bei den anderen Verbindungen (bis auf das noch bestehende Problem "chaotische Verkabelung", bei nachträglich angelegten Ports) nichts negatives feststellen.

              Problem chaotische Verkabelung:
              idoit_port_chaos_20240830_01.JPG
              Das ist wohl ein ganz anderes Thema.

              Danke jedenfalls für den super tollen raschen Fix.
              Wenn du heute Abend das Gefühl hast "hääää was war das denn?" ... das war ich, ich habe ein paar Bier auf dich getrunken 😁

              LG Stefan

              LFischerL 1 Reply Last reply Reply Quote 0
              • LFischerL Offline
                LFischer @StefanP74
                last edited by LFischer

                Hey @StefanP74

                freut mich das ich dir damit weiterhelfen konnte 😄 Bzgl. dem "Chaotische Verkabelung" Problem - ist das erst durch den Fix geschehen? Denn genau den zuständigen Code habe ich angepasst...

                Wäre natürlich schön wenn der Fix nur Probleme löst anstatt auch neue zu schaffen 😞

                Ich schaue mal ob ich auch dieses Problem nachvollziehen (und ggf. fixen) kann

                VG Leo

                edit

                3479e8b6-ff8a-4e86-b34a-497faf203a50-image.png

                Okay, ich kann es nachstellen... Mal sehen ob ich das auch noch hinbekomme 😄

                edit 2

                Ich glaube auch hier habe ich das Problem gefunden... Es ist aber etwa schwieriger zu lösen 😕 Es ist nämlich so dass die toIndex Werte vom Backend vorbereitet werden... Die Sortierung passiert dann aber im Frontend und ändert die Indexe, sodass diese dann nicht mehr korrekt sind.
                Mal sehen wie ich das löse 😄

                StefanP74S 1 Reply Last reply Reply Quote 0
                • StefanP74S Offline
                  StefanP74 @LFischer
                  last edited by StefanP74

                  @LFischer

                  nein, das ist nicht neu dazugekommen.

                  Edit: Wäre genial wenn du das lösen könntest. 🖖

                  LG Stefan

                  LFischerL 1 Reply Last reply Reply Quote 0
                  • LFischerL Offline
                    LFischer @StefanP74
                    last edited by LFischer

                    Hey @StefanP74

                    ich war ein wenig fleißig und habe etwas erarbeitet 😉 Dieses mal betrifft es aber ein paar mehr Zeilen - ich glaube es ist einfacher die komplette Datei zu tauschen. Leider ist es im Forum nicht möglich die ganze Datei hochzuladen...

                    /**
                     * i-doit cabling visualization javascript base class.
                     *
                     * @author  Leonard Fischer <lfischer@i-doit.com>
                     */
                    window.Cabling = Class.create({
                        $element:      null,
                        data:          null,
                        cache:         null,
                        svg:           null,
                        vis:           null,
                        zoom:          null,
                        options:       {},
                        indexMapping:  [],
                        rootContainer: {
                            height:   0,
                            matching: []
                        },
                    
                        getOptions: function () {
                            return this.options;
                        },
                    
                        getOption: function (option) {
                            return this.options[option];
                        },
                    
                        setOption: function (option, value) {
                            this.options[option] = value;
                    
                            return this;
                        },
                    
                        getSelectedElements: function () {
                            // This method should be used to get all selected cable paths.
                            // this.svg.selectAll('.selected');
                        },
                    
                        initialize: function ($el, data, options) {
                            var that = this;
                    
                            that.$element = $el;
                            that.data = data || [];
                            that.options = {
                                authEdit:               false, // Defines if the cabling view will allow any editing.
                                minZoomLevel:           0.1,   // Defines the minimal zoom level.
                                maxZoomLevel:           1.5,   // Defines the maximal zoom level.
                                objectTypeData:         {},    // JSON with all necessary object type data (name, color, ...).
                                connectorTypeData:      {},    // JSON with all necessary connector type data (name, color, ...).
                                objectTypeFilter:       [],    // Array pf object types, that shall not be displayed.
                                onAfterProcess:         null,  // 'Complete' event for when the rendering has finished.
                                onObjSelect:            null,  // Click event for a object node.
                                onObjUnselect:          null,  // Event for when a object gets unselected.
                                onCableSelect:          null,  // Click event for a cable.
                                onConnectorSelect:      null,  // Click event for a connector.
                                onConnectorUnselect:    null,  // Event for when a connector gets unselected.
                                onObjAcceptDrag:        null,  // Event for when a object gets unselected.
                                onObjAbortDrag:         null,  // Event for when a object gets unselected.
                                width:                  null,  // This can be used to change the viewpoints width. The SVG element will always remain 100%x100%.
                                height:                 null,  // This can be used to change the viewpoints height. The SVG element will always remain 100%x100%.
                                undefinedConnectorType: {
                                    color: '#fff',
                                    title: '-'
                                },                             // Default 'connector type' object.
                                undefinedObjectType:    {
                                    color: '#fff',
                                    title: '-'
                                },                             // Default 'object type' object.
                                nodeWidth:              150,   // Define the node width.
                                nodeHeight:             20,    // Define the node heigt.
                                nodeMarginX:            25,    // Define the horizontal margin between nodes.
                                nodeMarginY:            25,    // Define the vertical margin between nodes.
                                displayWiring:          false, // Define if the internal wiring shall be displayed (object boxes will get transparent).
                                showCableLabels:        false, // Define if cables shall be displayed.
                                clickableConnectors:    false  // Define if connectors shall be clickable.
                            };
                    
                            that.rootContainer = {
                                height:   0,
                                matching: []
                            };
                    
                            // Setting the default width and height.
                            that.options.width = that.$element.getWidth();
                            that.options.height = that.$element.getHeight() + 16;
                    
                            Object.extend(that.options, options || {});
                    
                            that.svg = d3.select($el).append('svg')
                                         .attr('width', that.options.width)
                                         .attr('height', that.options.height);
                    
                            that
                                .svg.append('rect')
                                .attr('width', that.options.width)
                                .attr('height', that.options.height)
                                .style('fill', 'none')
                                .style('pointer-events', 'all');
                    
                            // Here we set the <g> after the <rect>, this is necessary for dragging and zooming but still clicking elements inside <g>.
                            that.vis = this.svg.append("g");
                    
                            that.zoom = d3.zoom()
                                .scaleExtent([
                                    that.options.minZoomLevel,
                                    that.options.maxZoomLevel
                                ])
                                .on('zoom', function () {
                                    that.vis.attr('transform', d3.event.transform);
                                });
                    
                            that.svg
                                .call(that.zoom)
                                .call(that.zoom.transform, d3.zoomIdentity.translate(that.options.width / 2, that.options.height / 2));
                    
                            this.appendStyle();
                    
                            return this;
                        },
                    
                        appendStyle: function () {
                            // This method is necessary to include the SVG styles - this will be used in the SVG export.
                            var defs   = this.svg.select('defs'),
                                isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
                    
                            if (defs.node() === null) {
                                defs = this.svg.append('defs');
                    
                                defs.append('style').attr('type', 'text/css').text(
                                    ".cabling-object { \
                                        fill: none;\
                                        stroke: #444;\
                                        stroke-width: 1px;\
                                    }\
                                    text {\
                                        font-family: \"Helvetica Neue\", \"Lucida Grande\", \"Tahoma\", Arial, serif;\
                                        font-size: 11px;\
                                        paint-order: stroke;\
                                        stroke: transparent;\
                                        stroke-width: 0;\
                                        fill: #000;\
                                    }\
                                    text.connector-left-title,\
                                    text.connector-right-title {\
                                        stroke-width: 5px;\
                                        stroke: transparent;\
                                    }\
                                    text.connector-left-title.stroked,\
                                    text.connector-right-title.stroked {\
                                        " + (isIE11 ? "stroke-width: 0;" : "stroke-width: 5px;") + "\
                                        stroke: #fff;\
                                    }\
                                    text.title,\
                                    .linkname text,\
                                    .linkname.clicked rect,\
                                    .clicked rect.title {\
                                        fill: #fff;\
                                    }\
                                    text.title {\
                                        font-weight: bold;\
                                    }\
                                    .linkname rect,\
                                    .linkname.clicked text {\
                                        fill: #000;\
                                    }\
                                    rect.title,\
                                    .clicked text.title {\
                                        fill: #222;\
                                    }\
                                    circle.connector {\
                                        stroke: rgba(0, 0, 0, 0.75);\
                                        stroke-width: 1;\
                                    }\
                                    circle.connector-inner {\
                                        fill: rgba(0, 0, 0, 0.75);\
                                        stroke: none;\
                                    }\
                                    path {\
                                        fill: none;\
                                        stroke: #555;\
                                        stroke-width: 2;\
                                    }"
                                );
                            }
                        },
                    
                        textFormat: function (text, width) {
                            var result = text;
                    
                            if (width <= 0) {
                                return '';
                            }
                    
                            d3.select(this).text(result);
                    
                            while (this.getComputedTextLength() > width) {
                                result = result.substring(0, (result.length - 2));
                                d3.select(this).text(result);
                            }
                    
                            if (result !== text && width > 2) {
                                result += '..';
                            }
                    
                            return result;
                        },
                    
                        clearCanvas: function () {
                            this.vis.selectAll('*').remove();
                    
                            this.rootContainer = {
                                height:   0,
                                matching: []
                            };
                        },
                    
                        responsive: function () {
                            this.options.width = this.$element.getWidth();
                            this.options.height = this.$element.getHeight() + 16;
                    
                            return this;
                        },
                    
                        preProcess: function () {
                            return this;
                        },
                    
                        process: function () {
                            this.indexMapping = [];
                    
                            return this.preProcess().processSide('left').processSide('right').postProcess();
                        },
                    
                        processSide: function (dir) {
                            var that    = this,
                                invertX = (dir === 'right'),
                                cache = this.data[dir];
                    
                            // @see CABLING-49 Implement proper calculation for 'separation'.
                            var tree = d3.tree()
                                .separation((a, b) => Math.max(1, (a.children || []).length, (b.children || []).length))
                                .nodeSize([
                                    (that.options.nodeHeight + that.options.nodeMarginY),
                                    (that.options.nodeWidth + that.options.nodeMarginX)
                                ]);
                    
                            var root = d3.stratify()(cache)
                                .sort(function (a, b) {
                                    // First sort by 'connected-index' to keep internally wired connectors near by each other.
                                    if (dir === 'right' && a.data.siblingId && b.data.siblingId && a.data.siblingId !== b.data.siblingId) {
                                        // @see CABLING-58 Use the newly created indexMapping to find the proper index.
                                        return this.indexMapping.findIndex((d) => d == a.data.siblingId) - this.indexMapping.findIndex((d) => d == b.data.siblingId);
                                    }
                    
                                    // @see  CABLING-36  Any "unconnected" connector will be moved down, so that no wires cross each other.
                                    if (a.data.siblingId && !b.data.siblingId) {
                                        return -1;
                                    }
                    
                                    if (!a.data.siblingId && b.data.siblingId) {
                                        return 1;
                                    }
                    
                                    // @see CABLING-19 Following code will try to sort the connectors in a more natural way!
                    
                                    // First we split by "non-word" characters (like dots, slashes etc.).
                                    var aParts = a.data.title.split(/\W/),
                                        bParts = b.data.title.split(/\W/),
                                        minParts = Math.min(aParts.length, bParts.length), comparison, i;
                    
                                    for (i = 0; i < minParts; i++) {
                                        if (isNumeric(aParts[i]) && isNumeric(bParts[i])) {
                                            comparison = aParts[i] - bParts[i];
                                        } else {
                                            comparison = aParts[i].localeCompare(bParts[i]);
                                        }
                    
                                        if (comparison !== 0) {
                                            return comparison;
                                        }
                                    }
                    
                                    // If nothing worked out, use the default:
                                    return a.data.title.localeCompare(b.data.title);
                                }.bind(this));
                    
                            if (dir === 'left') {
                                this.indexMapping = root.children.map((d) => d.data.id);
                            }
                    
                            var connectorTranslate = function (d) {
                                if (that.options.clickableConnectors) {
                                    if (d.parent === null || d.parent && d.parent.id === 'root') {
                                        return 'translate(' + (invertX ? 5 : -5) + ',0)';
                                    }
                    
                                    if (d.data.inner) {
                                        return 'translate(' + (invertX ? -5 : that.options.nodeWidth+5) + ',0)';
                                    } else {
                                        return 'translate(' + (invertX ? that.options.nodeWidth+5 : -(that.options.nodeWidth+5)) + ',0)';
                                    }
                                } else {
                                    if (d.parent === null || d.parent && d.parent.id === 'root') {
                                        return 'translate(0,0)';
                                    }
                    
                                    if (d.data.inner) {
                                        return 'translate(' + (invertX ? 0 : that.options.nodeWidth) + ',0)';
                                    } else {
                                        return 'translate(' + (invertX ? that.options.nodeWidth : -that.options.nodeWidth) + ',0)';
                                    }
                                }
                            };
                    
                            var linkData = tree(root).links();
                    
                            var cable = that.vis
                                .selectAll(".cable.cable-" + dir)
                                .data(linkData);
                    
                            cable
                                .enter().append("path")
                                .style("opacity", 0)
                                .attr("class", "cable cable-" + dir);
                    
                            // After the link data is assigned, we reduce the data to only hold cable information.
                            linkData = linkData.filter(function (d) {
                                return d.source.id !== 'root' && d.source.data.outer;
                            });
                    
                            // @see  CABLING-35  Show internal cabling
                            that.vis
                                .selectAll('.internal-link.internal-link-' + dir)
                                .data((root.children || []).filter((d) => d.data.wiredToItself))
                                .enter()
                                .append("path")
                                .style("opacity", 0)
                                .attr('class', 'internal-link internal-link-' + dir)
                                .attr('d', function (d) {
                                    const connection = (root.children || []).find(function (conn) { return conn.id == d.data.connectorId});
                    
                                    if (!connection) {
                                        return '';
                                    }
                    
                                    d.y -= 20;
                                    var xBetween = d.y + 30;
                                    const yBetween = ((d.x + connection.x) / 2);
                    
                                    // Mirror the coordinates for the left side.
                                    if (dir === 'left') {
                                        d.y *= -1;
                                        xBetween *= -1;
                                    }
                    
                    
                                    return 'M' + d.y + ',' + d.x +
                                           ' C' + xBetween + ',' + d.x + ' ' + xBetween + ',' + yBetween + ' ' + xBetween + ',' + yBetween;
                                })
                                .interrupt()
                                .transition().duration(500)
                                .transition().duration(250)
                                .style("opacity", 1);
                    
                            var cableLabel = that.vis
                                .selectAll(".linkname.linkname-" + dir)
                                .data(linkData)
                                .enter()
                                .append("g")
                                .style("opacity", 0)
                                .attr("class", "linkname linkname-" + dir)
                                .attr('data-id', function (d) {
                                    return d.source.data.cableId;
                                });
                    
                            that.vis
                                .selectAll(".cable.cable-" + dir)
                                .classed('cable-root', function (d) {
                                    return (d.source.id === 'root');
                                })
                                .interrupt().transition().duration(500)
                                .attr("d", function (d) {
                                    var fromX  = (d.source.y + (that.options.showCableLabels ? 50 : 125)),
                                        fromX2 = (fromX+20),
                                        fromX3 = (fromX+40),
                                        fromY  = d.source.x,
                                        toX    = (d.target.y + (that.options.showCableLabels ? 50 : 125)),
                                        toY    = d.target.x;
                    
                                    if (d.target.data.doubling) {
                                        toX += 20;
                                    }
                    
                                    if (!invertX) {
                                        fromX *= -1;
                                        fromX2 *= -1;
                                        fromX3 *= -1;
                                        toX *= -1;
                                    }
                    
                                    return "M" + fromX + "," + fromY +
                                           "C" + fromX2 + "," + fromY + " " + fromX2 + "," + toY + " " + fromX3 + "," + toY +
                                           "L" + toX + "," + toY;
                                })
                                .transition().duration(250)
                                .style("opacity", 1)
                                .style('stroke-dasharray', function (d) {
                                    if (d.target.data.doubling) {
                                        return '2,2';
                                    }
                    
                                    return null;
                                });
                    
                            cable
                                .exit()
                                .interrupt().transition().duration(500)
                                .style("opacity", 0)
                                .remove();
                    
                            cableLabel
                                .append('rect')
                                .attr('class', 'mouse-pointer')
                                .attr('height', 14)
                                .attr('width', 125)
                                .attr('data-id', function (d) {
                                    return d.source.cableId
                                })
                                .on('click', that.selectCableObject.bind(this));
                    
                            cableLabel
                                .append('text')
                                .attr('class', 'mouse-pointer')
                                .attr('dy', 10)
                                .attr('x', 62.5)
                                .style('text-anchor', 'middle')
                                .text(function (d) {
                                    return d.source.data.cableTitle;
                                })
                                .on('click', that.selectCableObject.bind(this));
                    
                            that.vis
                                .selectAll(".linkname.linkname-" + dir)
                                .classed('hide', !that.options.showCableLabels)
                                .interrupt().transition().duration(550)
                                .style('opacity', (that.options.showCableLabels ? 1 : 0))
                                .attr('transform', function (d) {
                                    var translateX = d.source.y,
                                        translateY = d.source.x;
                    
                                    if (invertX) {
                                        translateX = translateX + 85;
                                    } else {
                                        translateX = translateX + that.options.nodeWidth + 65;
                                    }
                    
                                    if (d.source.parent.id === 'root') {
                                        translateX = translateX - 65;
                                    }
                    
                                    return 'translate(' + (invertX ? '' : '-') + translateX + ',' + translateY + ')';
                                });
                    
                            var node = that.vis
                                .selectAll(".node.node-" + dir)
                                .data(root.descendants());
                    
                            var nodeEnter = node
                                .enter().append("g")
                                .style("opacity", 0)
                                .attr("class", "node node-" + dir)
                                .classed('root', function (d) {
                                    return d.parent === null;
                                })
                                .attr('data-id', function (d) {
                                    return d.id;
                                });
                    
                            // This will append newly created and already existing nodes.
                            this.vis
                                .selectAll('.node.node-' + dir)
                                .transition().duration(500)
                                .style("opacity", 1)
                                .attr("transform", function (d) {
                                    var translateX = d.y,
                                        translateY = d.x;
                    
                                    if (d.parent === null) {
                                        return "translate(" + (invertX ? 0 : -that.options.nodeWidth) + "," + translateY + ")";
                                    }
                    
                                    if (d.parent && d.parent.id === 'root') {
                                        return "translate(" + (invertX ? that.options.nodeWidth : -that.options.nodeWidth) + "," + translateY + ")";
                                    }
                    
                                    if (d.data.inner) {
                                        if (!invertX) {
                                            translateX = -(translateX + that.options.nodeWidth);
                                        }
                                    } else {
                                        if (!invertX) {
                                            translateX = -(translateX + that.options.nodeWidth) + (that.options.nodeWidth + that.options.nodeMarginX);
                                        } else {
                                            translateX -= that.options.nodeMarginX;
                                        }
                                    }
                    
                                    return "translate(" + translateX + "," + translateY + ")";
                                });
                    
                            node.exit()
                                .interrupt().transition().duration(500)
                                .style("opacity", 0)
                                .remove();
                    
                            var container = nodeEnter
                                .filter(function (d) {
                                    // Only draw boxes for the "root" element and "left" connectors.
                                    return d.parent === null || d.data.inner;
                                })
                                .each(function (d) {
                                    // Prepare some data for each node.
                                    d.childNum = (d.children ? d.children.length : 1);
                    
                                    d.minX = d.y;
                                    d.maxX = d.y + (that.options.nodeWidth * 2);
                    
                                    if (d.children) {
                                        d.minY = d.children.first().x;
                                        d.maxY = d.children.last().x + that.options.nodeHeight;
                                    } else {
                                        d.minY = d.x;
                                        d.maxY = d.x + that.options.nodeHeight;
                                    }
                    
                                    d.width = d.maxX - d.minX;
                                    d.height = d.maxY - d.minY;
                                    d.translateX = 0;
                                    d.translateY = -(d.height / 2);
                    
                                    if (d.parent === null) {
                                        if (that.rootContainer.height < d.height) {
                                            that.rootContainer.height = d.height;
                                            that.rootContainer.translateX = d.translateX;
                                            that.rootContainer.translateY = d.translateY;
                                        }
                    
                                        d.width = that.options.nodeWidth;
                                    }
                                });
                    
                            container
                                .append('rect')
                                .attr('class', 'title mouse-pointer')
                                .attr('width', function (d) {
                                    return d.width;
                                })
                                .attr('height', function (d) {
                                    return 20;
                                })
                                .attr('data-object-id', function (d) {
                                    return d.data.objectId;
                                })
                                .attr('transform', function (d) {
                                    var translateX = d.translateX,
                                        translateY = d.translateY;
                    
                                    if (d.parent && d.parent !== 'root') {
                                        if (!invertX) {
                                            translateX = -that.options.nodeWidth;
                                        }
                                    }
                    
                                    return 'translate(' + translateX + ',' + (translateY - 20) + ')';
                                })
                                .on('click', that.selectObject.bind(this));
                    
                            container
                                .append('rect')
                                .attr('class', 'body')
                                .attr('width', function (d) {
                                    return d.width;
                                })
                                .attr('height', function (d) {
                                    return d.height;
                                })
                                .attr('data-conn', function (d) {
                                    return d.data.title;
                                })
                                .attr('transform', function (d) {
                                    var translateX = d.translateX,
                                        translateY = d.translateY;
                    
                                    if (d.parent && d.parent !== 'root') {
                                        if (!invertX) {
                                            translateX = -that.options.nodeWidth;
                                        }
                                    }
                    
                                    return 'translate(' + translateX + ',' + translateY + ')';
                                })
                                .attr('fill', function (d) {
                                    if (!that.options.objectTypeData.hasOwnProperty(d.data.objectTypeId)) {
                                        return that.options.undefinedObjectType.color;
                                    }
                    
                                    return that.options.objectTypeData[d.data.objectTypeId].color || that.options.undefinedObjectType.color
                                });
                    
                            nodeEnter
                                .filter(function (d) {
                                    return d.parent !== null;
                                })
                                .append('circle')
                                .attr('data-connector-id', function (d) {
                                    return d.data.id;
                                })
                                .attr('class', 'connector connector-' + dir)
                                .attr('transform', connectorTranslate)
                                .on('click', that.selectConnector.bind(this));
                    
                            nodeEnter
                                .filter(function (d) {
                                    return d.parent !== null;
                                })
                                .append('circle')
                                .attr('data-connector-id', function (d) {
                                    return d.data.id;
                                })
                                .style('opacity', 0)
                                .attr('class', 'connector-inner hide connector-inner-' + dir)
                                .attr('r', 4)
                                .attr('transform', connectorTranslate)
                                .on('click', that.selectConnector.bind(this));
                    
                            that.vis
                                .selectAll('circle.connector.connector-' + dir)
                                .classed('mouse-pointer', that.options.clickableConnectors)
                                .interrupt().transition().duration(500)
                                .attr('r', (that.options.clickableConnectors ? 10: 5))
                                .attr('fill', function (d) {
                                    var connectorType = that.options.connectorTypeData[d.data.connectorType];
                    
                                    return connectorType ? connectorType.color : that.options.undefinedConnectorType.color;
                                })
                                .attr('transform', connectorTranslate)
                                .style('stroke-width', (that.options.clickableConnectors ? 3 : 1));
                    
                            that.vis
                                .selectAll('circle.connector-inner.connector-inner-' + dir)
                                .classed('mouse-pointer', that.options.clickableConnectors)
                                .interrupt().transition().duration(500)
                                .attr('transform', connectorTranslate)
                                .style('opacity', (that.options.clickableConnectors ? 1 : 0));
                    
                            container
                                .filter(function (d) {
                                    return (d.parent !== null || invertX);
                                })
                                .append('text')
                                .attr('class', 'title mouse-pointer')
                                .attr("dy", function (d) {
                                    if (d.id === 'root') {
                                        return -((that.rootContainer.height / 2) + 7);
                                    }
                    
                                    return -((d.height / 2) + 7);
                                })
                                .attr("x", function (d) {
                                    if (d.parent === null) {
                                        return 0
                                    }
                    
                                    return invertX ? that.options.nodeWidth : 0;
                                })
                                .style("text-anchor", 'middle')
                                .text(function (d) {
                                    return d.data.objectTitle;
                                })
                                .on('click', that.selectObject.bind(this));
                    
                            nodeEnter
                                .append("text")
                                .attr('class', 'connector-' + dir + '-title')
                                .attr("dy", 3)
                                .attr("x", function (d) {
                                    if (d.parent !== null && d.parent.id === 'root') {
                                        return invertX ? -25 : 25;
                                    }
                    
                                    if (d.data.outer) {
                                        return invertX ? that.options.nodeWidth-10 : -(that.options.nodeWidth-10);
                                    }
                    
                                    return invertX ? 10 : (that.options.nodeWidth-10);
                                })
                                .style("text-anchor", function (d) {
                                    if (d.parent !== null && d.parent.id === 'root' || d.data.outer) {
                                        return invertX ? 'end' : 'start';
                                    }
                    
                                    return invertX ? "start" : "end";
                                })
                                .text(function (d) {
                                    return that.textFormat.call(this, d.data.title, (that.options.nodeWidth - 15));
                                });
                    
                            // @see CABLING-56 Show the full title when hovering connector.
                            nodeEnter.append('title').text(d => d.data.title);
                    
                            // After all calculations have been done, we set the root height.
                            this.vis.selectAll('g.root rect.title')
                                .attr('transform', function (d) {
                                    return 'translate(' + that.rootContainer.translateX + ',' + (that.rootContainer.translateY - 20) + ')';
                                });
                    
                            this.vis.selectAll('g.root rect.body')
                                .attr('height', function () {
                                    return that.rootContainer.height;
                                })
                                .attr('transform', function (d) {
                                    return 'translate(' + that.rootContainer.translateX + ',' + that.rootContainer.translateY + ')';
                                });
                    
                            this.vis.selectAll('rect.body')
                                .transition().duration(250)
                                .style('opacity', (this.options.displayWiring ? 0.5 : 1));
                    
                            this.vis
                                .selectAll(".cable.cable-root.cable-" + dir)
                                .each(function (d) {
                                    d.fromX = (invertX ? '' : '-') + 100;
                                    d.fromY = d.target.x;
                                    d.toX = (invertX ? '' : '-') + (d.target.y + (that.options.showCableLabels ? 50 : 125));
                                    d.toY = d.target.x;
                    
                                    // If a connector is internally wired, we draw the line to the middle (to visually "connect" them).
                                    if (d.target.data.wired) {
                                        d.fromX = 0; // -25;
                                    }
                    
                                    // If a root connector is not connected, only show a small "stump".
                                    if (!d.target.children) {
                                        d.toX = parseInt((invertX ? '' : '-') + 200);
                                    }
                                })
                                .attr('data-index', (d, i) => i)
                                .interrupt().transition().delay(500).duration(250)
                                .style('opacity', 1)
                                .attr('d', function (d) {
                                    // @see  CABLING-35  Cut the 'self wired' connectors more short
                                    if (d.target.data.wiredToItself || false) {
                                        if (dir === 'right') {
                                            d.toX -= 45;
                                        } else {
                                            d.toX += 45;
                                        }
                                    }
                    
                                    if (invertX && d.target.data.wired) {
                                        const index = this.indexMapping.findIndex((i) => i == d.target.data.siblingId);
                                        const $selection = this.vis.select('[data-index="' + index + '"]');
                    
                                        if (index >= 0 && $selection.size()) {
                                            d.fromY = $selection.data()[0].fromY;
                    
                                            return "M" + d.fromX + "," + d.fromY +
                                                   "C" + (d.fromX+20) + "," + d.fromY + " " + (d.fromX+20) + "," + d.toY + " " + (d.fromX+40) + "," + d.toY +
                                                   "L" + d.toX + "," + d.toY;
                                        }
                                    }
                    
                                    return "M" + d.fromX + "," + d.fromY +
                                           "L" + d.toX + "," + d.toY;
                                }.bind(this));
                    
                            this.vis.selectAll('.connector-' + dir + '-title')
                                .classed('stroked', this.options.displayWiring);
                    
                            return this;
                        },
                    
                        postProcess: function () {
                            if (Object.isFunction(this.options.onAfterProcess)) {
                                this.options.onAfterProcess.call(this);
                            }
                    
                            return this;
                        },
                    
                        setData: function (data) {
                            this.data = data;
                    
                            return this;
                        },
                    
                        selectObject: function (d) {
                            var $object = this.vis.selectAll('[data-id="' + d.id + '"]');
                    
                            if (!$object.classed('clicked')) {
                                this.vis.selectAll('.clicked').classed('clicked', false);
                    
                                $object.classed('clicked', true);
                    
                                if (Object.isFunction(this.options.onObjSelect)) {
                                    this.options.onObjSelect.call(this, d);
                                }
                            }
                    
                            return this;
                        },
                    
                        selectCableObject: function (d) {
                            var $object = this.vis.selectAll('[data-id="' + d.source.data.cableId + '"]');
                    
                            if (!$object.classed('clicked')) {
                                this.vis.selectAll('.clicked').classed('clicked', false);
                    
                                $object.classed('clicked', true);
                    
                                if (Object.isFunction(this.options.onCableSelect)) {
                                    this.options.onCableSelect.call(this, d);
                                }
                            }
                    
                            return this;
                        },
                    
                        selectConnector: function (d) {
                            var $connector = this.vis.select('circle.connector-inner[data-connector-id="' + d.data.id + '"]');
                    
                            if (! this.options.clickableConnectors) {
                                return;
                            }
                    
                            $connector.classed('hide', !$connector.classed('hide'));
                    
                            if (Object.isFunction(this.options.onConnectorSelect)) {
                                this.options.onConnectorSelect.call(this, d);
                            }
                    
                            return this;
                        },
                    
                        unselectConnectors: function (d) {
                            var data = this.vis.selectAll('.connector-inner:not(.hide)').classed('hide', true).data();
                    
                            if (Object.isFunction(this.options.onConnectorUnselect)) {
                                this.options.onConnectorUnselect.call(this, data);
                            }
                    
                            return this;
                        },
                    
                        unselectObject: function (data) {
                            if (Object.isFunction(this.options.onObjUnselect)) {
                                this.options.onObjUnselect.call(this, data);
                            }
                    
                            return this;
                        },
                    
                        center: function () {
                            var translateX = (this.options.width / 2),
                                translateY = (this.options.height / 2);
                    
                            this.vis.attr('transform', "translate(" + translateX + "," + translateY + ")");
                    
                            this.svg.select('rect').call(this.zoom.transform, d3.zoomIdentity.translate(translateX, translateY));
                    
                            return this;
                        }
                    });
                    

                    Die Datei müsste mit diesem neuen Inhalt überschrieben werden 😄

                    Das dürfte weiterhelfen!

                    4b3a1091-f515-4bae-bfc1-f35baeca93b8-image.png

                    VG Leo

                    StefanP74S 1 Reply Last reply Reply Quote 1
                    • StefanP74S Offline
                      StefanP74 @LFischer
                      last edited by

                      Servus @LFischer,

                      fantastico! 👌

                      Vielen Dank, das ist perfekt.
                      Was für ein mächtiger Einsatz. 👍

                      LG Stefan

                      1 Reply Last reply Reply Quote 0
                      • LFischerL Offline
                        LFischer
                        last edited by

                        Kurzes Update: Gelöst in Add-on Version 1.5

                        Die hier beschriebenen Probleme wurden in der Zwischenzeit in Version 1.5 des Add-ons gelöst. Dieses wurde am 26.Februar veröffentlicht 🙂

                        Viele Grüße
                        Leo

                        1 Reply Last reply Reply Quote 0
                        • StefanP74S Offline
                          StefanP74
                          last edited by

                          ... und das erfreute mich ganz besonders 😊 👏

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post