hmm: Divs mit Linie verbinden

Hi,

ich habe folgendes Beispiel zusammengeklickert:

https://stackblitz.com/edit/processui

Drücke ich auf den Button bekomme ich ein verschiebbares Element, drücke ich nochmal drauf bekomme ich noch eins usw. Jetzt möchte ich diese Elemente mit Linien verbinden. Habt ihr einen Ratschalg wie ich das umsetzen kann?

Das Drag und Drop der Elemente habe ich mit Angular Material realisiert.

  1. Hallo hmm,

    https://stackblitz.com/edit/processui

    Dort sind Drittanbieter-Cookies Pflicht. Also nichts zu sehen:

    ERROR: Cross-origin localStorage blocked by browser but required for devserver. Please enable 3rd party cookies or add an exception for stackblitz.io to resolve.

    Gruss
    Henry

    --
    Meine Meinung zu DSGVO & Co:
    „Principiis obsta. Sero medicina parata, cum mala per longas convaluere moras.“
  2. Hallo,

    Das Drag und Drop der Elemente habe ich mit Angular Material realisiert.

    verschiebbare Boxen sind ja mit html und Javascript noch einfach machbar, aber bei den Verbindungslinien wird es schon schwieriger. Man könnte gedrehte flache Divs nehmen, aber ich würde es nicht tun. Schon mal über SVG nachgedacht?

    Gruß
    Jürgen

    1. Hallo JürgenB,

      dann müsste man aber alles mit SVG machen, in einem großen SVG Element.

      Eine SVG Box mit einer Diagonalen drin, die man mit width und height passend zur benötigten Verbindungsstrecke skaliert, dürfte nicht gut ausehen; die Linienstärken schwanken mit der Skalierung. Man müsste diese Diagonale bei jeder Re-Skalierung anpassen. Ob man das mit custom properties tun kann?

      Rolf

      --
      sumpsi - posui - obstruxi
      1. Hallo Rolf B,

        ich denke bei der Beschreibung eher an Ablaufpläne oder Ähnliches.

        Zwei Rechtecke durch eine gewinkelte Linie verbunden

        Bis demnächst
        Matthias

        --
        Du kannst das Projekt SELFHTML unterstützen,
        indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
        1. Hallo Matthias,

          ja, oder an ein UML Diagramm oder sonst was.

          Ein Linienrouting, so wie Du es gezeichnet hast, setzt aber eine eigene Berechnung des Linienverlaufs voraus, d.h. man müsste nach jeder Verschiebung eines Elements den Path neu ermitteln, der für den Verbinder zu zeichnen ist.

          Sowas geht, aber sobald man die Verbinder auch noch so gestalten will, dass sie den Boxen ausweichen, oder man sie von Hand nachjustieren kann, schreibt man sein eigenes Visio.

          Nicht, dass das unmöglich wäre. Aber es ist sehr aufwändig.

          Rolf

          --
          sumpsi - posui - obstruxi
          1. Hallo,

            [...] schreibt man sein eigenes Visio.

            Visio auch nicht? 😉

            Im Ernst: Ja, das wäre in der Tat eine sehr anspruchsvolle Aufgabe.

            *scnr*,
             Martin

            --
            Früher war ich klein und dumm. Inzwischen hat sich so manches geändert. Ich bin größer geworden.
      2. Hallo Rolf,

        dann müsste man aber alles mit SVG machen, in einem großen SVG Element.

        so würde ich es machen.

        Gruß
        Jürgen

      3. @@Rolf B

        Eine SVG Box mit einer Diagonalen drin, die man mit width und height passend zur benötigten Verbindungsstrecke skaliert, dürfte nicht gut ausehen; die Linienstärken schwanken mit der Skalierung. Man müsste diese Diagonale bei jeder Re-Skalierung anpassen.

        Nö. Man müsste vector-effect="non-scaling-stroke" verwenden. Beispiel

        😷 LLAP

        --
        “When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy.’ They told me I didn’t understand the assignment, and I told them they didn’t understand life.” —John Lennon
        1. Hallo Gunnar,

          das ist, wenn ich MDN richtig deute, ein Attribut aus SVG 2. In welchem Brauser funktioniert das? In Chrome dem Anschein nach nicht. In diesem SVG variiert die Linenstärke, wenn man die width oder height ändert.

          <svg class="connector" viewbox="0 0 100 100"
               preserveAspectRatio="none" vector-effect="non-scaling-stroke"
               style="top:200px; left: 100px; width:300px; height:200px">
             <line x1="0" y1="0" x2="100" y2="100" stroke="red" />
          </svg>
          

          (Die connector class liefert position:absolute, stroke und stroke-width).

          Was bei mir in Chrome geklappt hat, ist preserveAspectRatio="none" und Prozentangaben für die Endpunkte der line:

          <svg class="connector" preserveAspectRatio="none"
               style="top:200px; left: 100px; width:300px; height:200px">
             <line x1="0" y1="0" x2="100%" y2="100%" />
          </svg>
          

          Lästig ist hier aber immer noch, dass man die Line je nach Lage der Endpunkte unterschiedlich zeichnen muss, und dass man bei Linien mit einem Verlauf nahe an 0° oder 90° Gefahr läuft, dass sich die Box auf Breite oder Höhe 0 reduziert.

          Die Idee einer reinen SVG Implementierung scheint deutlich besser - aber ob das dann mit Angular umsetzbar ist?!

          Rolf

          --
          sumpsi - posui - obstruxi
          1. @@Rolf B

            Hallo Gunnar,

            das ist, wenn ich MDN richtig deute, ein Attribut aus SVG 2. In welchem Brauser funktioniert das? In Chrome dem Anschein nach nicht. In diesem SVG variiert die Linenstärke, wenn man die width oder height ändert.

            Du musst MDN richtig deuten. Auch den Satz “As a presentation attribute, it can be applied to any element but it has effect only on the following ten elements: <circle>, <ellipse>, <foreignObject>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <textPath> <tspan>, and <use>”

            Die Idee einer reinen SVG Implementierung scheint deutlich besser - aber ob das dann mit Angular umsetzbar ist?!

            Angular dürfte es schnurzpiepegal sein, was für Elementtypen da generiert werden.

            😷 LLAP

            --
            “When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy.’ They told me I didn’t understand the assignment, and I told them they didn’t understand life.” —John Lennon
            1. Hallo alle,

              das ist, wenn ich MDN richtig deute, ein Attribut aus SVG 2. In welchem Brauser funktioniert das? In Chrome dem Anschein nach nicht. In diesem SVG variiert die Linenstärke, wenn man die width oder height ändert.

              Du musst MDN richtig deuten. Auch den Satz “As a presentation attribute, it can be applied to any element but it has effect only on the following ten elements: <circle>, <ellipse>, <foreignObject>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <textPath> <tspan>, and <use>”

              Also sorry, wenn in der Doku was von zehn Elementen steht und dann aber dreizehn aufgezählt werden, würde ich auch meinen Deutungen nur soweit trauen, wie ich einen Elefanten werfen kann...

              SCNR

              mbr

              1. @@mbr

                Du musst MDN richtig deuten. Auch den Satz “As a presentation attribute, it can be applied to any element but it has effect only on the following ten elements: <circle>, <ellipse>, <foreignObject>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <textPath> <tspan>, and <use>”

                Also sorry, wenn in der Doku was von zehn Elementen steht und dann aber dreizehn aufgezählt werden, würde ich auch meinen Deutungen nur soweit trauen, wie ich einen Elefanten werfen kann...

                Jo, Schreibfehler. Es sollte heißen: “on the following teen elements.”

                😷 LLAP

                --
                “When I was 5 years old, my mother always told me that happiness was the key to life. When I went to school, they asked me what I wanted to be when I grew up. I wrote down ‘happy.’ They told me I didn’t understand the assignment, and I told them they didn’t understand life.” —John Lennon
  3. Hallo hmm,

    ich habe bei Stackoverflow eine Idee gefunden, wie man eine diagonale Linie durch ein div ziehen kann. Das Beispiel "durchkreuzt" die Box, du müsstest es aufteilen in .diagonalUp und .diagonalDown. Damit kannst Du ein div erzeugen, dessen gegenüberliegende Ecken an den Verbindungspunkt-Ankern deiner Elemente positioniert sind. Das ist aber aufwändig.

    Mal angenommen, du möchtest (x1,y1) mit (x2,y2) verbinden. Dann musst Du zunächst feststellen, ob die Diagonale auf- oder absteigend ist, um den richtigen Gradienten auszuwählen.

    x1<x2 und y1<y2 - absteigend
    x1<x2 und y1>y2 - aufsteigend
    x1>x2 und y1<y2 - aufsteigend
    x1>x2 und y1>y2 - absteigend

    Sobald x1 und x2, oder y1 und y2, nahe beieinander liegen, brauchst Du einen Plan B, weil dann die vom Gradienten gezeichnete Linie zu dünn wird.

    .diagonalUp {
         background: 
             linear-gradient(to top right,
                 rgba(0,0,0,0) 0%,
                 rgba(0,0,0,0) calc(50% - 0.8px),
                 rgba(0,0,0,1) 50%,
                 rgba(0,0,0,0) calc(50% + 0.8px),
                 rgba(0,0,0,0) 100%);
    }
    .diagonalDown {
         background: 
             linear-gradient(to top left,
                 rgba(0,0,0,0) 0%,
                 rgba(0,0,0,0) calc(50% - 0.8px),
                 rgba(0,0,0,1) 50%,
                 rgba(0,0,0,0) calc(50% + 0.8px),
                 rgba(0,0,0,0) 100%);
    }
    

    Das solltest Du nicht verfolgen.

    Rolf

    --
    sumpsi - posui - obstruxi