program tip

두 요소 사이에 연결선 그리기

radiobox 2020. 8. 28. 07:19
반응형

두 요소 사이에 연결선 그리기


둘 이상의 요소를 연결하기 위해 선을 그리는 방법 (또는 사용 가능한 도구)은 무엇입니까? HTML / CSS / JavaScript / SVG / Canvas의 모든 조합이 좋습니다.

귀하의 답변이 다음 중 하나를 지원하는 경우 언급하십시오.

  • 드래그 가능한 요소
  • 드래그 가능 / 편집 가능한 연결
  • 요소 중복 방지

이 질문은 다양한 변형통합하기 위해 업데이트되었습니다 .


jsPlumbFlowchart 데모를 포함한 수많은 데모 에서 볼 수 있듯이 드래그 앤 드롭을 지원하는 옵션 입니다.

무료 커뮤니티 에디션과 유료 툴킷 에디션으로 제공됩니다.

Toolkit 에디션은 커뮤니티 에디션을 포괄적 인 데이터 바인딩 레이어와 함께 인기있는 라이브러리 용 애플리케이션 및 통합을 구축하기위한 여러 UI 위젯으로 래핑하며 상업적으로 라이선스가 부여됩니다.


svg로 선을 결합하는 것은 나에게 가치가 있었고 완벽하게 작동했습니다 ... 우선 SVG (Scalable Vector Graphics)는 상호 작용 및 애니메이션을 지원하는 2 차원 그래픽을위한 XML 기반 벡터 이미지 형식입니다. SVG 이미지와 그 동작은 XML 텍스트 파일에 정의되어 있습니다. <svg>태그를 사용하여 HTML로 svg를 만들 수 있습니다 . Adobe Illustrator는 경로를 사용하여 복잡한 svg를 만드는 데 사용되는 최고의 소프트웨어 중 하나입니다.

한 줄을 사용하여 두 div를 결합하는 절차 :

  1. 두 개의 div를 만들고 필요한 위치를 지정하십시오.

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

    (설명을 위해 인라인 스타일링을하고 있지만 스타일링을 위해 별도의 CSS 파일을 만드는 것이 항상 좋습니다)

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

    선 태그를 사용하면 지정된 두 점 (x1, y1)과 (x2, y2) 사이에 선을 그릴 수 있습니다. (참고로 w3schools를 방문하십시오.) 아직 지정하지 않았습니다. 라인 태그의 속성 (x1, y1, x2, y2)을 편집하기 위해 jQuery를 사용할 것이기 때문입니다.

  3. <script>태그 쓰기

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

    선택기를 사용하여 두 개의 div와 라인을 선택했습니다.

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

    jQuery position()메서드를 사용하면 요소의 현재 위치를 얻을 수 있습니다. 자세한 내용은 https://api.jquery.com/position/을 방문 하십시오 ( offset()방법도 사용할 수 있음 ).

이제 필요한 모든 위치를 얻었으므로 다음과 같이 선을 그릴 수 있습니다.

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

jQuery .attr()메서드는 선택한 요소의 속성을 변경하는 데 사용됩니다.

위 줄에서 우리가 한 것은 줄의 속성을

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

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

position()반환 두 값, 하나는 다른 '최고', 우리가 쉽게 .top 사용하여 액세스 할 수 있습니다를 '왼쪽'과 오브젝트 (여기 POS1과 POS2)를 사용하여 .left ...

이제 라인 태그에는 두 점 사이에 선을 그리는 두 개의 별개의 좌표가 있습니다.

팁 : div에 필요에 따라 이벤트 리스너 추가

팁 : 스크립트 태그에 무엇이든 쓰기 전에 먼저 jQuery 라이브러리를 가져와야합니다.

JQuery와 통해 좌표를 추가 ... 그것은 다음과 같이 보일 것입니다

다음 스 니펫은 데모 목적으로 만 사용됩니다. 올바른 솔루션을 얻으려면 위의 단계를 따르십시오.

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


며칠 전에도 동일한 요구 사항이있었습니다.

전체 너비높이 svg를 사용하여 모든 div 아래에 추가 하고 이러한 svg에 동적으로 추가했습니다 .

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

VisJS드래그 가능한 요소를 지원 하는 Arrows 예제 를 통해이를 지원합니다.

또한 상호 작용 이벤트 예제 와 함께 편집 가능한 연결을 지원합니다 .


RaphaëlGraffle 예제 를 통해 이를 지원합니다 .

이 답변은 Awais Akhtar의 답변Vaibhav Jain의 답변을 기반으로 합니다.


D3 has hundreds of examples, some of which are suitable for this question.

Examples without drag and drop, that are fixed:

Examples without drag and drop, that are interactive:

Examples with dragging and dropping:

This answer is based off of Glenn Dayton's answer.


mxGraph — used by draw.io — supports this use case, with its Grapheditor example. Documentation. Examples.

This answer is based off of Vainbhav Jain's answer.


Cytoscape supports this with its Architecture example which supports dragging elements.

For creating connections, there is the edgehandles extension. It does not yet support editing existing connections. Question.

For editing connection shapes, there is the edge-editing extension. Demo.

The edit-editation extension seems promising, however there is no demo yet.


GoJS supports this, with its State Chart example, that supports dragging and dropping of elements, and editing of connections.

This answer is based off of Walter Northwoods' answer.


js-graph.it supports this use case, as seen by its getting started guide, supporting dragging elements without connection overlaps. Doesn't seem like it supports editing/creating connections. Doesn't seem it is maintained anymore.


JointJS/Rappid supports this use case with its Kitchensink example which supports dragging and dropping of elements, and repositioning of connections. It has many examples.

This answer is based off of Vainbhav Jain's answer.

참고URL : https://stackoverflow.com/questions/6278152/drawing-a-connecting-line-between-two-elements

반응형