it-swarm.com.de

Zeichnen einer Verbindungslinie zwischen zwei Elementen

Wie kann ich (oder welche Tools stehen zur Verfügung) zum Zeichnen einer Linie zwischen zwei oder mehr Elementen, um sie zu verbinden? Jede Kombination von HTML/CSS/JavaScript/SVG/Canvas ist in Ordnung.

Wenn Ihre Antwort einen dieser Punkte unterstützt, erwähnen Sie es:

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

Diese Frage wurde aktualisiert, um konsolidiere die zahlreichen Variationen davon.

86
Bakhtiyor

jsPlumb ist eine Option, die das Ziehen und Ablegen unterstützt, wie aus den zahlreichen Demos ersichtlich ist, einschließlich der Flowchart-Demo .

Es ist in einer kostenlosen Community-Edition und einer kostenpflichtigen Toolkit-Edition verfügbar.

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.

155

Das Zusammenfügen von Zeilen mit svgs war für mich einen Versuch wert, und es hat perfekt funktioniert. Zunächst 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 eine svg in HTML mit dem <svg>-Tag erstellen. Adobe Illustrator ist eine der besten Software zum Erstellen komplexer SVGs mit Pfaden.

Verfahren, um zwei Divs mithilfe einer Zeile zu verknüpfen:

  1. erstellen Sie zwei Divs und geben Sie ihnen jede Position, die Sie brauchen

    <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 paar 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 eine Referenz besuchen Sie w3schools.) Wir haben sie noch nicht angegeben. weil wir jQuery verwenden werden, um die Attribute (x1, y1, x2, y2) des Zeilen-Tags zu bearbeiten.

  3. in <script> tag schreiben

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

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

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

    mit der Methode jQuery position() 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.)

Nun, da wir alle Positionen erhalten haben, die wir brauchen, können wir die Linie wie folgt zeichnen ...

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

mit der Methode jQuery .attr() werden die Attribute des ausgewählten Elements geändert. 

In der obigen Zeile haben wir nur die Attribute der Zeile geändert 

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

zu

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

da position() zwei Werte zurückgibt, einen 'left' und einen 'top', können wir sie mit .top und .left über die Objekte (hier pos1 und pos2) erreichen ... 

Das Linien-Tag hat jetzt zwei verschiedene Koordinaten, um eine Linie zwischen zwei Punkten zu zeichnen.

Tipp: Fügen Sie Ereignis-Listener hinzu, wenn Sie Divs benötigen

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

Nachdem durch JQuery Koordinaten hinzugefügt hat ... sieht es ungefähr so ​​aus

Das folgende Snippet dient nur zu Demonstrationszwecken. Führen Sie die oben genannten Schritte aus, 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>

34
Ani

Ich habe auch die gleiche Anforderung vor ein paar Tagen

Ich habe ein volles width und heightsvg verwendet, es unter allen meinen divs hinzugefügt und lines dynamisch zu diesen svg hinzugefügt.

Überprüfen Sie, wie ich es 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);
});
4
Nadir Laskar
1
balupton

Cytoscape unterstützt dies mit seinem Architecture-Beispiel das ziehende Elemente unterstützt.

Zum Erstellen von Verbindungen gibt es die Erweiterung edgehandles . Die Bearbeitung vorhandener Verbindungen wird noch nicht unterstützt.Frage.

Zum Bearbeiten von Verbindungsformen gibt es die Erweiterung Edge-Editing . Demo.

Die Erweiterung edit-editation scheint vielversprechend, es gibt jedoch noch keine Demo.

1
balupton

Raphaël unterstützt dies mit Graffle-Beispiel .

Diese Antwort basiert auf Awais Akhtar'sAntwort und Vaibhav JainAntwort .

0
balupton

VisJS unterstützt dies mit seinem Arrows Beispiel , das ziehbare Elemente unterstützt.

Ich konnte jedoch kein Beispiel finden, das editierbare Verbindungen unterstützt.

0
balupton

GoJS unterstützt dies mit seinem State Chart-Beispiel , das das Ziehen und Ablegen von Elementen und das Bearbeiten von Verbindungen unterstützt.

Diese Antwort basiert auf Walter Northwoods 'answer .

0
balupton

JointJS/Rappid unterstützt diesen Anwendungsfall mit seinem Kitchensink-Beispiel , das das Ziehen und Ablegen von Elementen sowie das Umsetzen von Verbindungen unterstützt. Es hat viele Beispiele.

Diese Antwort basiert auf Vainbhav JainsAntwort .

0
balupton

js-graph.it unterstützt diesen Anwendungsfall, wie aus der Getting Started-Anleitung hervorgeht, die das Ziehen von Elementen ohne Verbindungsüberschneidungen unterstützt. Es scheint nicht so, als würde es das Bearbeiten/Erstellen von Verbindungen unterstützen. Scheint nicht mehr, dass es mehr gepflegt wird.

0
balupton

mxGraph - verwendet von draw.io - unterstützt diesen Anwendungsfall mit seinem Grapheditor-Beispiel . Dokumentation.Beispiele.

Diese Antwort basiert auf Vainbhav JainsAntwort .

0
balupton