153 votes

Tracez une ligne de connexion entre deux éléments

Comment tracer une ligne entre deux ou plusieurs éléments pour les relier ? Toute combinaison de HTML/CSS/JavaScript/SVG/Canvas est acceptable.

Si votre réponse va dans le sens de l'une de ces idées, mentionnez-la :

  • éléments glissants
  • connexions glissables/éditables
  • évitement du chevauchement des éléments

Cette question a été mise à jour pour consolider les nombreuses variations d'elle.

176voto

Tomasz Kowalczyk Points 7520

jsPlumb est une option disponible qui prend en charge la fonction glisser-déposer, comme le montre sa fonction de nombreuses démonstrations y compris le Démonstration de l'organigramme .

Il est disponible dans une édition communautaire gratuite et une édition payante Toolkit.

L'édition Toolkit complète l'édition Community avec une couche de liaison de données complète, ainsi que plusieurs widgets d'interface utilisateur pour la création d'applications et d'intégrations pour les bibliothèques les plus populaires, et fait l'objet d'une licence commerciale.

20 votes

Une boîte à outils étonnante, mais attention : elle n'est pas gratuite ! Ils veulent que vous achetiez une licence si vous avez l'intention de l'héberger publiquement ou de le vendre dans vos propres produits (cf. jsplumbtoolkit.com/achat ).

4 votes

À ce jour, il existe également une édition communautaire : jsplumbtoolkit.com/communauté qui est une source ouverte

1 votes

Pas gratuit ! la solution avec svg est plus simple

86voto

Cherubim Points 3621

Récemment, j'ai essayé de développer une application web simple qui utilise des composants glisser-déposer et des lignes qui les relient. Je suis tombé sur ces deux bibliothèques javascript simples et étonnantes :

  1. Plain Draggable : bibliothèque simple et performante permettant de faire glisser des éléments HTML/SVG.
  2. Leader Line : Dessinez une ligne de repère dans votre page web

Lien vers un exemple de travail (utilisation : cliquer sur ajouter une scène pour créer un draggable, cliquer sur ajouter un choix pour dessiner une ligne de conduite entre deux draggables différents)

79voto

Ani Points 1093

Joindre des lignes avec des svgs valait la peine d'essayer pour moi, et cela a parfaitement fonctionné... tout d'abord, Scalable Vector Graphics (SVG) est un format d'image vectorielle basé sur XML pour les graphiques bidimensionnels avec un support pour l'interactivité et l'animation. Les images SVG et leurs comportements sont définis dans des fichiers texte XML. Vous pouvez créer un svg en HTML à l'aide des éléments suivants <svg> étiquette. Adobe Illustrator est l'un des meilleurs logiciels utilisés pour créer des svgs complexes à l'aide de chemins.

Procédure pour joindre deux divs en utilisant une ligne :

  1. créez deux divs et donnez-leur la position que vous souhaitez

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

    (pour des raisons d'explication, je fais un peu de style en ligne, mais il est toujours bon de créer un fichier css séparé pour le style).

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

    La balise Line nous permet de tracer une ligne entre deux points spécifiés (x1,y1) et (x2,y2). (pour une référence visitez w3schools.) nous ne les avons pas encore spécifiés. parce que nous allons utiliser jQuery pour éditer les attributs (x1,y1,x2,y2) de la balise line.

  3. sur <script> tag écrire

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

    J'ai utilisé des sélecteurs pour sélectionner les deux divs et la ligne...

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

    jQuery position() nous permet d'obtenir la position actuelle d'un élément. Pour plus d'informations, consultez https://api.jquery.com/position/ (vous pouvez utiliser offset() également)

Maintenant que nous avons obtenu toutes les positions dont nous avons besoin, nous pouvons dessiner la ligne comme suit...

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

jQuery .attr() est utilisée pour modifier les attributs de l'élément sélectionné.

Tout ce que nous avons fait dans la ligne ci-dessus est de changer les attributs de la ligne de

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

a

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

comme position() retourne deux valeurs, l'une 'gauche' et l'autre 'haut', nous pouvons facilement y accéder en utilisant .top et .left en utilisant les objets (ici pos1 et pos2) ...

Maintenant, la balise de ligne a deux coordonnées distinctes pour tracer une ligne entre deux points.

Conseil : ajoutez des écouteurs d'événements aux divs selon vos besoins.

Conseil : assurez-vous d'importer la bibliothèque jQuery avant d'écrire quoi que ce soit dans la balise script.

Après ajouter des coordonnées par le biais de JQuery ... Cela ressemblera à quelque chose comme ceci

L'extrait suivant n'est fourni qu'à des fins de démonstration. Veuillez suivre les étapes ci-dessus pour obtenir une solution correcte.

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

15voto

Awais Akhtar Points 135

Bonjour, vérifiez cette page http://raphaeljs.com/graffle.html

8voto

Nadir Laskar Points 2758

J'ai également eu la même exigence il y a quelques jours

J'ai utilisé un plein largeur y hauteur svg et l'a ajouté en dessous de tous mes divs et a ajouté lignes à ces svg de manière dynamique.

Regardez comment je l'ai fait ici en utilisant svg

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X