İki öğe arasında bir bağlantı çizgisi çizme [kapalı]


106

Bunları birbirine bağlamak için iki veya daha fazla öğe arasına nasıl çizgi çizebilirim? Herhangi bir HTML / CSS / JavaScript / SVG / Canvas kombinasyonu uygundur.

Cevabınız bunlardan herhangi birini destekliyorsa, bundan bahsedin:

  • sürüklenebilir elemanlar
  • sürüklenebilir / düzenlenebilir bağlantılar
  • eleman çakışmasından kaçınma

Bu soru, çeşitli varyasyonlarını birleştirmek için güncellendi .

Yanıtlar:


164

jsPlumb , Flowchart demosu da dahil olmak üzere çok sayıda gösterisinde görüldüğü gibi sürükle ve bırak özelliğini destekleyen bir seçenektir .

Ücretsiz bir Topluluk sürümünde ve ücretli bir Araç Seti sürümünde mevcuttur.

Toolkit sürümü, Topluluk sürümünü kapsamlı bir veri bağlama katmanıyla ve popüler kütüphaneler için uygulamalar ve entegrasyonlar oluşturmak için çeşitli UI pencere öğeleri ile tamamlar ve ticari olarak lisanslıdır.


4
Şaşırtıcı bir araç seti, ancak uyarılmalıdır: ücretsiz değil! Herkese açık olarak ev sahipliği yapmayı veya kendi ürünlerinizin içinde satış yapmayı planlıyorsanız, bir lisans satın almanızı istiyorlar (bkz. Jsplumbtoolkit.com/purchase ).
Chris

50

Satırları svgs ile birleştirmek benim için bir çekim değeriydi ve mükemmel çalıştı ... her şeyden önce, Ölçeklenebilir Vektör Grafikleri (SVG), etkileşim ve animasyon desteği ile iki boyutlu grafikler için XML tabanlı bir vektör görüntü formatıdır. SVG görüntüleri ve davranışları XML metin dosyalarında tanımlanır. kullanarak HTML'de bir svg oluşturabilirsiniz<svg>etiketi . Adobe Illustrator, yolları kullanarak karmaşık bir svg oluşturmak için kullanılan en iyi yazılımlardan biridir.

Bir satır kullanarak iki div'i birleştirme prosedürü:

  1. iki div oluşturun ve onlara ihtiyacınız olan herhangi bir konumu verin

    <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>

    (açıklama uğruna bazı satır içi şekillendirme yapıyorum ancak stil için ayrı bir css dosyası yapmak her zaman iyidir)

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

    Çizgi etiketi, belirtilen iki nokta (x1, y1) ve (x2, y2) arasında bir çizgi çizmemizi sağlar. (w3schools referans ziyareti için.) henüz belirtmedik. çünkü satır etiketinin niteliklerini (x1, y1, x2, y2) düzenlemek için jQuery kullanacağız.

  3. içinde <script>etiket yazma

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

    İki div'i ve satırı seçmek için seçicileri kullandım ...

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

    jQuery position()yöntemi, bir elemanın mevcut konumunu elde etmemizi sağlar. Daha fazla bilgi için https://api.jquery.com/position/ adresini ziyaret edin ( offset()yöntemi de kullanabilirsiniz )

Şimdi ihtiyacımız olan tüm pozisyonları elde ettiğimiz için aşağıdaki gibi çizgi çekebiliriz ...

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

jQuery .attr()yöntemi, seçilen elemanın niteliklerini değiştirmek için kullanılır.

Yukarıdaki satırda yaptığımız tek şey, satırın özniteliklerini

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

-e

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

gibi position() döner iki değerden, diğeri 'top', kolayca .top kullanarak erişebilirsiniz 'sol' ve nesneleri (burada pos1 ve POS2) kullanılarak .left ...

Artık çizgi etiketi, iki nokta arasında çizgi çizmek için iki farklı koordinata sahiptir.

İpucu: Div'lere ihtiyaç duyduğunuzda olay dinleyicileri ekleyin

İpucu: komut dosyası etiketine herhangi bir şey yazmadan önce jQuery kitaplığını içe aktardığınızdan emin olun

JQuery aracılığıyla koordinatları ekledikten sonra ... Şuna benzer

Aşağıdaki ön bilgi yalnızca tanıtım amaçlıdır, lütfen doğru çözümü bulmak için yukarıdaki adımları izleyin

<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
Lütfen aynı yanıtı kopyalayıp birden çok soruya yapıştırmayın. Bunun yerine, tek tek soruların yanıtlarını özelleştirin.
Andy

2
Svg'yi z-endeksi -1 kullanarak arka planda genişlik ve yüksekliğe% 100 koymam gerekiyor ama bu bir cazibe gibi çalışıyor.
steven


31
Olumsuz oy verenler, lütfen bunu yapmanın nedenini açıklayın ... Her iki soru için de aynı cevabı gönderdim çünkü bu cevabın her iki soru için de geçerli olduğundan eminim ... Eğer iki soru alakalıysa, cevapları da alakalı olabilir .. Yanlış bir şey yapmadım ...
Ani

6

Birkaç gün önce de aynı gereksinime sahiptim

Tam genişlik ve yükseklik svg kullandım ve tüm div'lerimin altına ekledim ve bu svg'ye dinamik olarak satırlar ekledim .

Svg kullanarak burada nasıl yaptığımı kontrol edin

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);
});

Safari Sürüm 12.0.1'de (14606.2.104.1.1) çalışmıyor gibi görünüyor
balupton



2

Son zamanlarda, sürükle ve bırak bileşenlerini kullanan ve bunları birbirine bağlayan hatlara sahip basit bir web uygulaması geliştirmeye çalıştım. Bu iki basit ve harika javascript kitaplığına rastladım:

  1. Düz Sürüklenebilir : HTML / SVG öğelerinin sürüklenmesine izin veren basit ve yüksek performanslı kitaplık.
  2. Lider Çizgisi : Web sayfanıza bir lider çizgi çizin


1



1

js-graph.it , başlangıç kılavuzunda görüldüğü gibi , bağlantı çakışmaları olmadan öğeleri sürüklemeyi destekleyen bu kullanım durumunu destekler. Bağlantıları düzenlemeyi / oluşturmayı destekliyor gibi görünmüyor. Görünüşe göre artık korunuyor.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.