Divs mit Linie verbinden
hmm
- angular
- gui
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.
Hallo hmm,
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
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
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
Hallo Rolf B,
ich denke bei der Beschreibung eher an Ablaufpläne oder Ähnliches.
Bis demnächst
Matthias
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
Hallo,
[...] schreibt man sein eigenes Visio.
Visio auch nicht? 😉
Im Ernst: Ja, das wäre in der Tat eine sehr anspruchsvolle Aufgabe.
*scnr*,
Martin
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
@@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
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
@@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
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
@@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
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