如何在两个或多个元素之间画一条线来连接它们?HTML/CSS/JavaScript/SVG/Canvas的任何组合都可以。
如果你的答案支持其中任何一个,那么一定要提到它:
- 可拖动元素
- 可拖动/可编辑连接
- 元素重叠避免
这个问题已经更新,以整合它的众多变体
jsPlumb是一个支持拖放的选项,正如其众多演示(包括流程图演示)所示。
它有免费的社区版和付费的工具包版。
Toolkit版本为Community版本提供了一个全面的数据绑定层,以及用于构建应用程序和集成流行库的几个UI小部件,并获得了商业许可。
用svgs连接线路对我来说值得一试,而且效果很好。。。首先,可缩放矢量图形(SVG)是一种基于XML的二维图形矢量图像格式,支持交互性和动画。SVG图像及其行为是在XML文本文件中定义的。您可以使用<svg>
标记在HTML中创建svg。Adobe Illustrator是用于创建使用路径的复杂svg的最佳软件之一。
使用一行连接两个div的过程:
-
创建两个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文件进行样式设计总是很好的)
-
<svg><line id="line1"/></svg>
Line标签允许我们在两个指定点(x1,y1)和(x2,y2)之间绘制一条线。(参考访问w3schools。)我们还没有指定它们。因为我们将使用jQuery来编辑行标记的属性(x1,y1,x2,y2)。
-
在
<script>
标签中写入line1 = $('#line1'); div1 = $('#div1'); div2 = $('#div2');
我使用选择器来选择两个div和line。。。
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()
返回两个值,一个"left",另一个"top",我们可以使用.top和.left使用对象(此处为pos1和pos2)轻松访问它们。。。
现在,线标签有两个不同的坐标来绘制两点之间的线。
提示:根据需要添加事件侦听器以划分
提示:在脚本标记中写入任何内容之前,请确保先导入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>
最近,我尝试开发一个简单的web应用程序,该应用程序使用拖放组件并有连接它们的行。我发现了这两个简单而神奇的javascript库:
- 简单可拖动:简单且高性能的库,允许拖动HTML/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示例支持这一点,该示例支持可拖动元素。
它还支持可编辑的连接,例如交互事件。
GoJS支持这一点,其状态图示例支持拖放元素和编辑连接。
这个答案是基于沃尔特·诺斯伍德的答案。
mxGraph--由draw.io使用--通过其Grapheditor示例支持此用例。文档示例。
这个答案是基于Vainhav Jain的答案。
Raphaël通过其Graffle示例支持这一点。
这个答案是基于Awais Akhtar的答案和Vaibhav Jain的答案。
D3有数百个例子,其中一些适合这个问题。
没有拖放的固定示例:
- https://beta.observablehq.com/@mbostock/d3聚类树状图
- https://beta.observablehq.com/@mbostock/d3整洁树
- https://beta.observablehq.com/@mbostock/d3层次边缘绑定
- https://beta.observablehq.com/@mbostock/d3径向树状图
- https://beta.observablehq.com/@mbostock/d3-sankey图
- https://www.jasondavies.com/collatz-graph/
- https://bost.ocks.org/mike/hive/
- https://bost.ocks.org/mike/fisheye/
- https://bl.ocks.org/wvengen/cab9b01816490edb7083
没有拖放的交互式示例:
- https://beta.observablehq.com/@mbostock/可折叠树
- https://beta.observablehq.com/@mbostock/d3力有向图
拖放示例:
- http://bl.ocks.org/MoritzStefaner/1377729
- http://bl.ocks.org/Neilos/584b9a5d44d5fe00f779
这个答案是基于格伦·戴顿的答案。
Cytoscape通过其支持拖动元素的架构示例支持这一点。
对于创建连接,有edgehandles扩展。它还不支持编辑现有连接。问题
对于编辑连接形状,有边缘编辑扩展插件。演示。
编辑编辑扩展似乎很有希望,但是还没有演示。
js-graph.it支持这个用例,正如其入门指南所示,它支持在没有连接重叠的情况下拖动元素。它似乎不支持编辑/创建连接。它似乎不再被维护了。
JointJS/Rappid通过其Kitchensink示例支持此用例,该示例支持拖放元素和重新定位连接。它有很多例子。
这个答案是基于Vainhav Jain的答案。