Berechnung der Position von Kinderelemente von einem Elternknoten

Diskutiere Berechnung der Position von Kinderelemente von einem Elternknoten im Java Basics - Anfänger-Themen Bereich.
B

beta20

Hallo,

ich möchte gerne einen Entscheidungsbaum in einer Web-GUI erstellen. Hierfür habe ich einen Elternknoten und eben die Kinder davon...
Ich stehe nun gerade vor dem Problem, wie ich die Kinder anordnen kann, sodass es korrekt aussieht.

Ich habe dabei folgende Informationen von den Elementen:
- width
- x (Position der X-Achse)
- y
- height

Ich denke folgende Infos sind noch notwendig für die Kinder:
- definierte Breite (bspw. 60px)
- definierter Space zwischen den Kinder (bspw. 20px).

Was ich nun benötige, ist eine Funktion, die mir die Positionen (X-Achse) der Kinder ermittelt, abhängig von der Anzahl an Kindern, sodass alles schön zentriert ist und nicht mehr Elemente auf der rechten oder linken Seite sind...

Im Endeffekte, will ich die grünen generieren:


Folgenden Code habe ich bisher, aber es ist nicht korrekt - die Elemente fangen links an, passen aber nicht wirklich.
Kurze Info: am Anfang erstelle ich immer einen "Else" - Zweig, anschließend dann die "If / Else" - Zweige...

Java:
/**
     * Erstellt dem Tree
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {
       
        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size() + 1;
        int widthBranchElement = 100; // in Pixel
        int spaceBetweenElement = 20;
        int widthTotalAllBranches = ((widthBranchElement + spaceBetweenElement) * numberOfBranch);
        int widthToLeft = (widthTotalAllBranches / 2) - (diagramElementBefore.getWidth() / 2);

        // Else Tree als erstes erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore, diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft, widthBranchElement);
               
        // If Tree erstellen
        for(DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }
       
    }
    
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore, DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
   
        newDiagramElement.setHeight(20); // definierte Höhe
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(diagramElementBefore.getX() - x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30); // definierter Abstand zum Elternknoten
               
        return newDiagramElement;
    }

Irgendwas stimmt nicht mit meiner Logik....
 
mihe7

mihe7

Ich denke folgende Infos sind noch notwendig für die Kinder:
- definierte Breite (bspw. 60px)
- definierter Space zwischen den Kinder (bspw. 20px).
Gesamtbreite = n*(definierterSpace+definierteBreite) - definierteBreite;
Vom Mittelpunkt Gesamtbreite/2 abziehen, fertig.
 
B

beta20

Danke... Es kommt dem ganzen sehr nahe, aber ich glaube es passt noch nicht 100%, wenn man sich den mittleren Knoten ansieht:

Java:
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {
        
        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size() + 1;
        int widthBranchElement = 250; // in Pixel
        int spaceBetweenElement = 20;
        
        int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - widthBranchElement;
        int widthToLeft = (diagramElementBefore.getWidth() / 2) - (width/2);

        // Else Tree erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore, diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft, widthBranchElement);
                
        // If Tree erstellen
        for(DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }
        
        // Andere erstellen
        return diagramElementBefore;
    }

    /**
     * Create Branch for Decision Tree
     *
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore, DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
        newDiagramElement.setHeight(20);
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(diagramElementBefore.getX() - x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30);

        return newDiagramElement;
    }

 
mihe7

mihe7

Oops, ich habe mich verschrieben: am Ende muss das Space abgezogen werden und nicht die Breite.

Gesamtbreite = n*(definierterSpace+definierteBreite) - definierterSpace;
 
B

beta20

Ne, das passt noch weniger...


Ich habe diese Zeile bei mir geändert:

int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - spaceBetweenElement;
 
mihe7

mihe7

Ja, das ist korrekt: bei 3 Elementen hast Du 3 x die Breite der Elemente und 2 x den Abstand dazwischen. Das wäre die Gesamtbreite für 3 Elemente.


Die x-Koordinate der Mitte des Elements ganz links ist centerX-width/2, wobei centerX die x-Koordinate der Mitte des "Graphen" (bzw. des Elternelements) ist.
 
B

beta20

hm, das mache ich doch hier?
int widthToLeft = (diagramElementBefore.getWidth() / 2) - (width / 2);

Oder wie sollte man die " x-Koordinate der Mitte des "Graphen" (bzw. des Elternelements) ist." berechnen?
 
mihe7

mihe7

Wenn diagramElementBefore das Elternelement ist, und es eine getX()-Methode gibt, die die x-Koordinate der linken Seite der BoundingBox des Elements angibt, dann wäre centerX=diagramElementBefore.getX() + diagramElementBefore.getWidth()/2
 
B

beta20

Also das passt immer noch nicht, habe die Änderung hier vorgenommen

Code:
    private DiagramElement createDiagramBranchTree(DiagramElement diagramElementBefore) {

        int numberOfBranch = diagramElementBefore.getAutomationElement().getDecisionComponent().getIfBranchList().size()
                + 1;
        int widthBranchElement = 250; // in Pixel
        int spaceBetweenElement = 20;

        int width = numberOfBranch * (spaceBetweenElement + widthBranchElement) - spaceBetweenElement;
        int centerXParent = diagramElementBefore.getX() + diagramElementBefore.getWidth()/2;
        int widthToLeft = centerXParent - (width / 2);

    // Else Tree erstellen
        diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch();
        createDiagramBranchElement(diagramElementBefore,
                diagramElementBefore.getAutomationElement().getDecisionComponent().getElseBranch(), widthToLeft,
                widthBranchElement);

        // If Tree erstellen
        for (DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent()
                .getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }

    }

    /**
     * Create Branch for Decision Tree
     *
     * @param diagramElementBefore
     * @return
     */
    private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore,
            DecisionBranch decisionBranch, int x, int widthBranchElement) {

        DiagramElement newDiagramElement = new DiagramElement();
        newDiagramElement.setDiagramElementBefore(diagramElementBefore);

        newDiagramElement.setHeight(20);
        newDiagramElement.setWidth(widthBranchElement);
        newDiagramElement.setX(x);
        newDiagramElement.setY(diagramElementBefore.getY() + diagramElementBefore.getHeight() + 30);

        return newDiagramElement;
    }
 
mihe7

mihe7

widthToLeft deutet auf eine andere Bedeutung hin. Es geht um die absolute x-Koordinate. Das kann man ausrechnen: sagen wir mal das Elternelement befindet sich bei x=400 (linke Kante) und jedes Element hat eine Breite von 100. Dann ist centerX = 400 + 100/2 = 450.

Jetzt hast Du drei Kindelemente mit einem Abstand von 20. Macht eine Gesamtbreite von 3*(100+20)-20 = 340.

Dann fängt die Mitte(!) des linken Kindelements bei x = 450 - 340/2, also bei 280 an. Das zweite Element befindet sich bei 280+120 = 400 (== centerX) und das dritte bei 400+120=520. Jeweils Mitte!
 
B

beta20

also, ich habe das jetzt mal mit den gleichen Zahlen durchgespielt....Das passt und sieht korrekt aus...
Wenn die Kinderelemente nun aber eine Breite von 150 bekommen (int widthBranchElement = 150;) dann passt es nicht mehr...
Das zweite Element sieht nicht korrekt aus...
Der Elternknoten hat immer noch eine Breite von 400...

Passt das hier in der Schleife?
widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;

Java:
        // If Tree erstellen
        for (DecisionBranch decisionBranch : diagramElementBefore.getAutomationElement().getDecisionComponent()
                .getIfBranchList()) {
            widthToLeft = widthToLeft + widthBranchElement + spaceBetweenElement;
            createDiagramBranchElement(diagramElementBefore, decisionBranch, widthToLeft, widthBranchElement);
        }
Und in der createDiagramBranchElement() - Methode setze ich eben den Wert von Paramater

Java:
private DiagramElement createDiagramBranchElement(DiagramElement diagramElementBefore,
            DecisionBranch decisionBranch, int x, int widthBranchElement) {
...
newDiagramElement.setX(x);
 
mihe7

mihe7

Wenn die Kinderelemente nun aber eine Breite von 150 bekommen (int widthBranchElement = 150;) dann passt es nicht mehr...
Das spielt keine Rolle, da Du die Kindelemente komplett unter dem Parent zentrierst.

Was macht denn createDiagramBranchElement? Setzt das das Element oder nur den Strich? Wenn das Element, dann musst Du natürlich berücksichtigen, dass das x die Mitte ist.
 
B

beta20

Was macht denn createDiagramBranchElement? Setzt das das Element oder nur den Strich? Wenn das Element, dann musst Du natürlich berücksichtigen, dass das x die Mitte ist.
Das erstellt das Element mit den Koordinaten... Die Verbindung wird automatisch generiert...
Das heißt was muss ich dann noch machen?
 
B

beta20

du meinst also? Oder welche Breite meinst du?
newDiagramElement.setX(x -(widthBranchElement/2));
 
mihe7

mihe7

Ja, wenn widthBranchElement die Breite des hinzuzufügenden Elements ist.
 
B

beta20

Ja, das sind die 250px:
int widthBranchElement = 250; // in Pixel

Es passt jedoch nicht
 
Thema: 

Berechnung der Position von Kinderelemente von einem Elternknoten

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben