Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
企业架构师->;如何使用.eap文件(.mdb)上的SQL查询获取结束节点的边缘_Sql_Ms Access_Enterprise Architect - Fatal编程技术网

企业架构师->;如何使用.eap文件(.mdb)上的SQL查询获取结束节点的边缘

企业架构师->;如何使用.eap文件(.mdb)上的SQL查询获取结束节点的边缘,sql,ms-access,enterprise-architect,Sql,Ms Access,Enterprise Architect,我必须只使用.eap文件绘制一些EA图,而不在服务器上安装EA。所以我通过ODBC将其作为MDB文件打开 我知道有属性t\u diagramlinks.Geometry(带边={1,2,3,4})和属性t\u connector.Start\u edge和属性t\u connector.End\u edge 带有属性Geometry的表t\u diagramlinks依赖于图表。 具有属性.Start\u Edge和.End\u Edge的表t\u connector与图表无关-->可能存在未在

我必须只使用.eap文件绘制一些EA图,而不在服务器上安装EA。所以我通过ODBC将其作为MDB文件打开

我知道有属性
t\u diagramlinks.Geometry
(带边={1,2,3,4})和属性
t\u connector.Start\u edge
和属性
t\u connector.End\u edge

带有属性
Geometry
的表
t\u diagramlinks
依赖于图表。 具有属性
.Start\u Edge
.End\u Edge
的表
t\u connector
与图表无关-->可能存在未在图表上绘制的连接

我知道
t\u diagramlinks
的SX、SY、EX、EY是相对于图上绘制的每个节点原点的坐标


问题:EX/EY有时为零,并且没有将端点绘制到节点的边缘。我想这与鼠标释放位置有关。

下面的“我的解释”是我的渲染器根据我的假设生成的

“EA解释”是EA实际渲染的内容,我也希望在渲染器中看到它

问题

  • 我在
    t\u diagramlinks.Geometry
    中使用csv值边-但是在哪里 我是否为结束节点找到了这个

  • 属性“开始边”和“结束边”在 表
    t\u连接器
    是否与图表无关

我在t_diagramlinks.Geometry中使用csv值边-但是在哪里 我是否为结束节点找到了这个

你需要使用欧几里德。SX、SY/EX、EY是起始元件和结束元件之间最短中心连接的相对位移

属性“开始边”和“结束边”在 表“t_连接器”是否与图表无关

它们用于合格的属性

编辑:详细阐述您的基本问题<代码>t_diagramlinks.路径用于保存接头的弯曲点(如果指定了弯曲点)。因此,为了找到连接件实际连接某个图元的点,必须找到距该图元最近的折弯。现在,在该弯曲和图元中间之间将有一个自然附着点。相对于此,添加了SX-Y(/EX-Y)以生成手动移动的渲染附着点

以上的说法是有道理的。我从来没有核实过细节,但看到数字后,我用了肚子。我可能会详细研究这一点,以更新我的内部书籍,但不能保证

第二次编辑:现在我知道“我的解释”是渲染器根据您的假设生成的,下面是(最有可能的;见上文)故事。为了渲染连接器,EA将使用以下信息:

  • 两个连接元素的框架坐标
  • 从元素中点的坐标计算
  • 连接器的路径属性(如果不为空)
  • 与相关元件最近的弯曲点(如果不是空的)
  • 接头的换档系数SX-Y和EX-Y
从起点图元的中点开始,绘制一条虚拟线,该虚拟线指向最近的弯曲点或终点图元的中点(除非参见下文)。通过这种方式,您可以计算元素矩形框架处的虚拟附着点(即使用例具有矩形框架)。现在,通过SX-Y移动该点,该点将(/应该?)始终沿元素框架的边缘移动。现在您有了开始元素的虚拟附着点

另一方面(end元素;上面的“除非”),您可以执行类似的操作来计算end的虚拟附件。我不知道EA这样做的真正顺序(我没有代码洞察力)。因此,如果两侧都有手动偏移,计算将根据绘制到另一侧的虚拟连接的顺序给出不同的结果(因此:是否考虑另一侧的偏移)。基本上,我认为你可以忽略99.9%的情况,剩下的只是无关的噪音

因此,现在您知道了虚拟端点,您可以直接连接它们,或者,如果给定了路径,您可以通过弯曲点连接它们

再说一次:一切都有一点道理。这只是从外面观察,但可能不会太远。还有一个事实是,您有不同的线条样式,有圆形边缘(这里不考虑)和贝塞尔线(甚至更多的是龙地)

我在t_diagramlinks.Geometry中使用csv值边-但是在哪里 我是否为结束节点找到了这个

你需要使用欧几里德。SX、SY/EX、EY是起始元件和结束元件之间最短中心连接的相对位移

属性“开始边”和“结束边”在 表“t_连接器”是否与图表无关

它们用于合格的属性

编辑:详细阐述您的基本问题<代码>t_diagramlinks.路径用于保存接头的弯曲点(如果指定了弯曲点)。因此,为了找到连接件实际连接某个图元的点,必须找到距该图元最近的折弯。现在,在该弯曲和图元中间之间将有一个自然附着点。相对于此,添加了SX-Y(/EX-Y)以生成手动移动的渲染附着点

以上的说法是有道理的。我从来没有核实过细节,但看到数字后,我用了肚子。我可能会详细研究这一点,以更新我的内部书籍,但不能保证

第二次编辑:现在我知道“我的解释”是渲染器根据您的假设生成的,下面是(m
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Erzeuge eine eigene Link-Klasse für das Routing der Pfeile, die von Hand gezogen wurden
// und über spezielle Attribute in der EAP-Datei definiert werden
// Ruft die Superklasse von go.Link im Konstruktor auf
function MultiNodePathLink() {
    go.Link.call(this);
}
go.Diagram.inherit(MultiNodePathLink, go.Link); // Erben von go.Link

// ignores this.routing, this.adjusting, this.corner, this.smoothness, this.curviness
/** @override */
MultiNodePathLink.prototype.computePoints = function () {

    // Die this Referenz ist hier ist ein geerbter ein go.Link. der bei Links
    var startNode = this.fromNode;
    var startNodeX = startNode.location.M;  // X-Koordinate vom Startknoten
    var startNodeY = startNode.location.N; // Y-Koordinate vom Startknoten

    var endNode = this.toNode;
    var endNodeX = endNode.location.M;  // X-Koordinate vom Startknoten
    var endNodeY = endNode.location.N; // Y-Koordinate vom Startknoten

    var startNodeData = startNode.data; // Das sind die Daten
    var endNodeData = endNode.data; // Das sind die Daten

    // Die Link-Daten
    var linkProperties = this.data;
    //** Das Feld Style in [t_diagramlink] bestimmt die Connector-Darstellung  **/
    // http://www.capri-soft.de/blog/?p=2904
    /*
     *  1 = Direct                    Mode=1
     *  2 = Auto Routing              Mode=2
     *  3 = Custom Line               Mode=3
     *  4 = Tree Vertical             Mode=3;TREE=V
     *  5 = Tree Horizontal           Mode=3;TREE=H
     *  6 = Lateral Vertical          Mode=3;TREE=LV
     *  7 = Lateral Horizontal        Mode=3;TREE=LH
     *  8 = Orthogonal Square         Mode=3;TREE=OS
     *  9 = Orthogonal Rounded        Mode=3;TREE=OR
     */
    var styleStringArray = linkProperties.style.split(";");
    var mode = -1;
    var tree = '';
    for (var i = 0; i < styleStringArray.length; i++) {
        if (styleStringArray[i].trim().indexOf('Mode=') > -1) {
            mode = styleStringArray[i].replace('Mode=', '');
        }

        if (styleStringArray[i].trim().indexOf('TREE=') > -1) {
            tree = styleStringArray[i].replace('TREE=', '');
        }
    }



    // In der Tabelle t_diagramlinks in der Freitextspalte "Geometry" wird in einem CSV-String
    // gespeichert, wie der Link letztendlich auf dem Diagram gezogen wurde
    var geometryString = linkProperties.geometry.split(";");
    // SX and SY are relative to the centre of the start object
    var sx = geometryString[0].replace("SX=", "");
    var sy = geometryString[1].replace("SY=", "");
    // EX and EY are relative to the centre of the end object
    var ex = geometryString[2].replace("EX=", "");
    var ey = geometryString[3].replace("EY=", "");

    // SX=-67;SY=-43;EX=-12;EY=-40;EDGE=3;$LLB=;
    // LLT=;LMT=;LMB=CX=30:CY=13:OX=11:OY=-2:HDN=0:BLD=0:ITA=0:UND=0:CLR=-1:ALN=1:DIR=0:ROT=0;
    // LRT=;LRB=;IRHS=;ILHS=;

    // EDGE ranges in value from 1-4, with 1=Top, 2=Right, 3=Bottom, 4=Left (Outgoing Point of the Start Object)
    var edge = geometryString[4].replace("EDGE=", "");

    // Hier beginnt das Custom-Routing
    this.clearPoints();
    if (linkProperties.start_object_name == 'System Verification Test Reports' && linkProperties.end_object_name == 'System test specifications') {
        var test = 'irrsinn';
    }
    // Hier werden die Wege definiert für das gecustomizte Link Routing
    // Geht der Link nach oben oder unten wird die Y-Koordinate des Startknotens genutzt (Weil Orthogonales Routing)
    var startConnX = null;
    var startConnY = null;
    if (edge == 1) { // Ecke oben
        startConnX = Math.abs(startNodeX) + Math.abs((startNode.actualBounds.width / 2) + new Number(sx));
        startConnY = Math.abs(startNodeY);
    }
    else if (edge == 3) { // Ecke unten
        startConnX = Math.abs(startNodeX) + Math.abs((startNode.actualBounds.width / 2) + new Number(sx));
        startConnY = Math.abs(startNodeY) + new Number(startNode.actualBounds.height);
    }
    else if (edge == 2) { // Ecke rechts
        startConnX = Math.abs(startNodeX) + startNode.actualBounds.width;
        startConnY = Math.abs(startNodeY) + Math.abs((startNode.actualBounds.height / 2) - new Number(sy));
    }
    else if (edge == 4) { // Ecke links
        startConnX = new Number(Math.abs(startNodeX));
        startConnY = Math.round(startNodeY) + Math.round((startNode.actualBounds.height / 2) - new Number(sy));
    }
    else {
        alert('Die Edge konnte nicht entdeckt werden! Ist der Geometry String in der EAP Datei richtig?');
    }

    this.addPoint(new go.Point(Math.round(startConnX), Math.round(startConnY)));

    // Abfrage: Gibt es einen letzten Path Punkt?
    var lastPathPunkt=false;
    var lastPathPunktX, lastPathPunktY;

    if (mode != 1)
    {
        // Routing über die Zwischenwege
        if (typeof linkProperties.conn_path !== "undefined" && linkProperties.conn_path !== "") {
            var splittedArray = linkProperties.conn_path.split(";");
            if (splittedArray.length > 1) {
                // Hier ist mindestens ein Wert vorhanden da auch der erste mit Semikolon abgeschlossen wird im Path vom EA
                for (var i = 0; i < splittedArray.length - 1; i++) {
                    var einMittelPunkt = splittedArray[i];
                    var mittelPunktArray = einMittelPunkt.split(":");
                    this.addPoint(new go.Point(Math.abs(new Number(mittelPunktArray[0])), Math.abs(new Number(mittelPunktArray[1]))))
                    lastPathPunktX = Math.abs(new Number(mittelPunktArray[0]));
                    lastPathPunktY = Math.abs(new Number(mittelPunktArray[1]));
                    lastPathPunkt = true;
                }
            }
        }
    }

    // Wenn es keinen Pfad gab,muss der letzte Punkt mit dem Startknoten identisch sein
    if (lastPathPunkt == false) {
        lastPathPunktX = Math.abs(Math.round(startConnX));
        lastPathPunktY = Math.abs(Math.round(startConnY));
    }

    // End-Routing
    // Der Endpunkt in EA in Document Coordinates
    var endConnX = Math.abs(endNodeX) + Math.abs((endNode.actualBounds.width / 2) + new Number(ex));
    var endConnY = Math.abs(endNodeY) + Math.abs((endNode.actualBounds.height / 2) - new Number(ey));

    // Spezialfälle bei horizontalen und vertikalen Linien:
    if (endConnX == lastPathPunktX) {
        // Es liegt eine vertikale Gerade (z.B. von oben nach unten) vor
        this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
        this.addPoint(new go.Point(Math.round(endConnX), Math.round(endConnY)));

    } else if (endConnY == lastPathPunktY) {
        // Es liegt eine horizontale Gerade (z.B. von rechts nach links) vor
        this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
        this.addPoint(new go.Point(Math.round(endConnX), Math.round(endConnY)));
    } else {
        // Es ist keine Gerade sondern ein Gerade, die mit y=m*x+b beschrieben werden kann

        // 1.) Gerade zwischen Start- und Endpunkt ermittelnhn
        //      Ye-Ys
        //  m = -----    b=Ys-m*Xs oder b=Ye-m*Xe
        //      Xe-Xs
        var m = (endConnY - lastPathPunktY) / (endConnX - lastPathPunktX);
        var b = lastPathPunktY - m * lastPathPunktX

        // 2.) Ermittlung der horizontalen und vertikalen Geraden des Rechteckes und dem Schnittpunkten
        // Die Geraden, die das Rechteck definieren:
        var rY1 = endNodeY;
        var rY2 = endNodeY + endNode.actualBounds.height;
        var rX1 = endNodeX;
        var rX2 = endNodeX + endNode.actualBounds.width;
        // (rX1, rY1) -zu-> (rX2, rY2)

        // Horizontale Geraden:
        //     y - b
        // x = -----
        //       m


        var lengthToPoint = [];

        var sX1 = (rY1 - b) / m; // S1(sX1|rY1)
        if (sX1 >= rX1 && sX1 <= rX2) {
            // Der Schnittpunkt sX1 ist am Rechteck
            // Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
            var dS1 = Math.sqrt(Math.pow(rY1 - lastPathPunktY, 2) + Math.pow(sX1 - lastPathPunktX, 2));

            lengthToPoint.push({
                "distanz": dS1,
                "x": sX1,
                "y": rY1
            });

        }

        var sX2 = (rY2 - b) / m; // S2(sX2|rY2)
        if (sX2 >= rX1 && sX2 <= rX2) {
            // Der Schnittpunkt sX2 ist am Rechteck
            // Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
            var dS2 = Math.sqrt(Math.pow(rY2 - lastPathPunktY, 2) + Math.pow(sX2 - lastPathPunktX, 2));

            lengthToPoint.push({
                "distanz": dS2,
                "x": sX2,
                "y": rY2
            });
        }

        // Vertikale Geraden:
        //
        // y = m*x + b

        var sY1 = m * rX1 + b; // S3(rX1|sY1)
        if (sY1 >= rY1 && sY1 <= rY2) {
            // Der Schnittpunkt sY1 ist am Rechteck
            // Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
            var dS3 = Math.sqrt(Math.pow(sY1 - lastPathPunktY, 2) + Math.pow(rX1 - lastPathPunktX, 2));

            lengthToPoint.push({
                "distanz": dS3,
                "x": rX1,
                "y": sY1
            });
        }

        var sY2 = m * rX2 + b; // S4(rX2|sY2)
        if (sY2 >= rY1 && sY2 <= rY2) {
            // Der Schnittpunkt sY2 ist am Rechteck
            // Distanz: d=SQRT((y2-y1)^2+(x2-x1)^2)
            var dS4 = Math.sqrt(Math.pow(sY2 - lastPathPunktY, 2) + Math.pow(rX2 - lastPathPunktX, 2));

            lengthToPoint.push({
                "distanz": dS4,
                "x": rX2,
                "y": sY2
            });
        }

        // Sortiere alle Punkte nach Distanz - der mit der kleinsten Entfernung isses
        lengthToPoint.sort(function (a, b) { return a.distanz - b.distanz });

        if (lengthToPoint.length > 0)
        {
            this.addPoint(new go.Point(Math.round(lengthToPoint[0].x), Math.round(lengthToPoint[0].y)));
        }
        else
        {
            this.addPoint(new go.Point(Math.round(lastPathPunktX), Math.round(lastPathPunktY)));
        }


    }

    return true;
};
// end MultiNodePathLink class