Zeichnen einer Verbindungslinie zwischen zwei Elementen [geschlossen]


105

Wie kann ich eine Linie zwischen zwei oder mehr Elementen zeichnen, um sie zu verbinden? Jede Kombination von HTML / CSS / JavaScript / SVG / Canvas ist in Ordnung.

Wenn Ihre Antwort eine dieser Antworten unterstützt, erwähnen Sie sie:

  • ziehbare Elemente
  • ziehbare / bearbeitbare Verbindungen
  • Vermeidung von Elementüberlappungen

Diese Frage wurde aktualisiert, um die zahlreichen Variationen zu konsolidieren .

Antworten:


164

jsPlumb ist eine verfügbare Option, die Drag & Drop unterstützt, wie aus den zahlreichen Demos hervorgeht , einschließlich der Flowchart-Demo .

Es ist in einer kostenlosen Community-Edition und einer kostenpflichtigen Toolkit-Edition erhältlich.

Die Toolkit-Edition umfasst die Community-Edition mit einer umfassenden Datenbindungsebene sowie mehreren UI-Widgets zum Erstellen von Anwendungen und Integrationen für beliebte Bibliotheken und ist kommerziell lizenziert.


4
Erstaunliches Toolkit, aber seien Sie gewarnt: Es ist nicht kostenlos! Sie möchten, dass Sie eine Lizenz kaufen, wenn Sie beabsichtigen, öffentlich zu hosten oder innerhalb Ihrer eigenen Produkte zu verkaufen (siehe jsplumbtoolkit.com/purchase ).
Chris

50

Das Verbinden von Linien mit SVGs war für mich einen Versuch wert und hat perfekt funktioniert. Zunächst einmal ist Scalable Vector Graphics (SVG) ein XML-basiertes Vektorbildformat für zweidimensionale Grafiken mit Unterstützung für Interaktivität und Animation. SVG-Bilder und ihr Verhalten werden in XML-Textdateien definiert. Sie können ein SVG in HTML mit <svg>Tag erstellen . Adobe Illustrator ist eine der besten Software zum Erstellen komplexer SVGs mithilfe von Pfaden.

Vorgehensweise zum Verbinden von zwei Divs über eine Linie:

  1. Erstellen Sie zwei Divs und geben Sie ihnen eine beliebige Position

    <div id="div1" style="width: 100px; height: 100px; top:0; left:0; background:#e53935 ; position:absolute;"></div>
    <div id="div2" style="width: 100px; height: 100px; top:0; left:300px; background:#4527a0 ; position:absolute;"></div>

    (Zur Erklärung mache ich ein Inline-Styling, aber es ist immer gut, eine separate CSS-Datei für das Styling zu erstellen.)

  2. <svg><line id="line1"/></svg>

    Mit dem Linien-Tag können wir eine Linie zwischen zwei angegebenen Punkten (x1, y1) und (x2, y2) zeichnen. (für einen Referenzbesuch w3schools.) Wir haben sie noch nicht spezifiziert. weil wir jQuery verwenden werden, um die Attribute (x1, y1, x2, y2) des Zeilen-Tags zu bearbeiten.

  3. im <script>Tag schreiben

    line1 = $('#line1');   
    div1 = $('#div1');   
    div2 = $('#div2');

    Ich habe Selektoren verwendet, um die beiden Divs und Linien auszuwählen ...

    var pos1 = div1.position();
    var pos2 = div2.position();

    Mit der jQuery- position()Methode können wir die aktuelle Position eines Elements ermitteln. Weitere Informationen finden Sie unter https://api.jquery.com/position/ (Sie können auch die offset()Methode verwenden).

Nachdem wir alle Positionen erhalten haben, die wir brauchen, können wir die folgende Linie ziehen ...

line1
  .attr('x1', pos1.left)
  .attr('y1', pos1.top)
  .attr('x2', pos2.left)
  .attr('y2', pos2.top);

Die jQuery- .attr()Methode wird verwendet, um die Attribute des ausgewählten Elements zu ändern.

Alles, was wir in der obigen Zeile getan haben, ist, dass wir die Attribute der Zeile von geändert haben

x1 = 0
y1 = 0
x2 = 0
y2 = 0

zu

x1 = pos1.left
y1 = pos1.top
x2 = pos2.left
y2 = pos2.top

als position()Erträge zwei Werte, ‚links‘ ein und andere ‚top‘, können wir sie leicht zugänglich machen mit .top und .Left die Objekte mit (hier pos1 und pos2) ...

Jetzt hat das Linien-Tag zwei unterschiedliche Koordinaten, um eine Linie zwischen zwei Punkten zu ziehen.

Tipp: Fügen Sie nach Bedarf Ereignis-Listener zu Divs hinzu

Tipp: Stellen Sie sicher, dass Sie zuerst die jQuery-Bibliothek importieren, bevor Sie etwas in das Skript-Tag schreiben

Nach dem Hinzufügen von Koordinaten über JQuery ... sieht es ungefähr so ​​aus

Das folgende Snippet dient nur zu Demonstrationszwecken. Befolgen Sie die obigen Schritte, um die richtige Lösung zu erhalten

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="div1" style="width: 100px; height: 100px; top:0; left:0; background:#e53935 ; position:absolute;"></div>
<div id="div2" style="width: 100px; height: 100px; top:0; left:300px; background:#4527a0 ; position:absolute;"></div>
<svg width="500" height="500"><line x1="50" y1="50" x2="350" y2="50" stroke="red"/></svg>


3
Bitte kopieren Sie nicht dieselbe Antwort und fügen Sie sie nicht in mehrere Fragen ein. Passen Sie stattdessen die Antworten auf die einzelnen Fragen an.
Andy

2
Ich muss das SVG mit Z-Index -1 zu 100% in Breite und Höhe in den Hintergrund stellen, aber es funktioniert wie ein Zauber.
Steven


31
Downvoters, bitte kommentieren Sie den Grund dafür ... Ich habe für beide Fragen die gleichen Antworten gepostet, da ich sicher bin, dass diese Antwort für beide Fragen gilt ... Wenn zwei Fragen relevant sind, können ihre Antworten auch relevant sein. Ich habe nichts falsch gemacht ...
Ani

6

Ich hatte auch die gleiche Anforderung vor ein paar Tagen

Ich habe ein SVG mit voller Breite und Höhe verwendet und es unter all meinen Divs hinzugefügt und Linien dynamisch zu diesem SVG hinzugefügt .

Überprüfen Sie, wie ich es hier mit svg gemacht habe

HTML

<div id="ui-browser"><div class="anchor"></div>
     <div id="control-library" class="library">
       <div class="name-title">Control Library</div>
       <ul>
         <li>Control A</li>
         <li>Control B</li>
         <li>Control C</li>
         <li>Control D</li>
       </ul>
     </div><!--
--></div><!--
--><div id="canvas">
     <svg id='connector_canvas'></svg>
     <div class="ui-item item-1"><div class="con_anchor"></div></div>
     <div class="ui-item item-2"><div class="con_anchor"></div></div>
     <div class="ui-item item-3"><div class="con_anchor"></div></div>
     <div class="ui-item item-1"><div class="con_anchor"></div></div>
     <div class="ui-item item-2"><div class="con_anchor"></div></div>
     <div class="ui-item item-3"><div class="con_anchor"></div></div>
   </div><!--
--><div id="property-browser"></div>

https://jsfiddle.net/kgfamo4b/

    $('.anchor').on('click',function(){
   var width = parseInt($(this).parent().css('width'));
   if(width==10){
     $(this).parent().css('width','20%');
     $('#canvas').css('width','60%');
   }else{
      $(this).parent().css('width','10px');
     $('#canvas').css('width','calc( 80% - 10px)');
   }
});

$('.ui-item').draggable({
  drag: function( event, ui ) {
           var lines = $(this).data('lines');
           var con_item =$(this).data('connected-item');
           var con_lines = $(this).data('connected-lines');

           if(lines) {
             lines.forEach(function(line,id){
                    $(line).attr('x1',$(this).position().left).attr('y1',$(this).position().top+1);  
             }.bind(this));
           }

           if(con_lines){
               con_lines.forEach(function(con_line,id){
                  $(con_line).attr('x2',$(this).position().left)
                        .attr('y2',$(this).position().top+(parseInt($(this).css('height'))/2)+(id*5));
               }.bind(this));

           }

       }
});

$('.ui-item').droppable({
  accept: '.con_anchor',
  drop: function(event,ui){
     var item = ui.draggable.closest('.ui-item');
     $(this).data('connected-item',item);
     ui.draggable.css({top:-2,left:-2});
     item.data('lines').push(item.data('line'));

     if($(this).data('connected-lines')){
        $(this).data('connected-lines').push(item.data('line'));

         var y2_ = parseInt(item.data('line').attr('y2'));
         item.data('line').attr('y2',y2_+$(this).data('connected-lines').length*5);

     }else $(this).data('connected-lines',[item.data('line')]);

     item.data('line',null);
    console.log('dropped');
  }
});


$('.con_anchor').draggable({drag: function( event, ui ) {
     var _end = $(event.target).parent().position();
     var end = $(event.target).position();
     if(_end&&end)  
     $(event.target).parent().data('line')
                                                    .attr('x2',end.left+_end.left+5).attr('y2',end.top+_end.top+2);
},stop: function(event,ui) {
        if(!ui.helper.closest('.ui-item').data('line')) return;
        ui.helper.css({top:-2,left:-2});
        ui.helper.closest('.ui-item').data('line').remove();
        ui.helper.closest('.ui-item').data('line',null);
        console.log('stopped');
      }
});


$('.con_anchor').on('mousedown',function(e){
    var cur_ui_item = $(this).closest('.ui-item');
    var connector = $('#connector_canvas');
    var cur_con;

  if(!$(cur_ui_item).data('lines')) $(cur_ui_item).data('lines',[]);

  if(!$(cur_ui_item).data('line')){
         cur_con = $(document.createElementNS('http://www.w3.org/2000/svg','line'));
         cur_ui_item.data('line',cur_con);
    } else cur_con = cur_ui_item.data('line');

    connector.append(cur_con);
    var start = cur_ui_item.position();
     cur_con.attr('x1',start.left).attr('y1',start.top+1);
     cur_con.attr('x2',start.left+1).attr('y2',start.top+1);
});

Scheint nicht auf Safari Version 12.0.1 (14606.2.104.1.1) zu
funktionieren



2

Vor kurzem habe ich versucht, eine einfache Web-App zu entwickeln, die Drag & Drop-Komponenten verwendet und durch Linien verbunden ist. Ich bin auf diese zwei einfachen und erstaunlichen Javascript-Bibliotheken gestoßen:

  1. Plain Draggable : Einfache und leistungsstarke Bibliothek zum Ziehen von HTML / SVG-Elementen.
  2. Leader Linie : Zeichnen Sie eine Führungslinie in Ihrer Web - Seite


1




Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.