在我们的开发工程中经常会使用到各种图,所谓的图就是由节点和节点之间的连接所形成的系统,数学上专门有一个分支叫图论(Graph Theroy)。利用图我们可以做很多工具,比如思维导图,流程图,状态机,组织架构图,等等。今天我要做的是用开源的HTML5工具来快速构造一个做图的工具。

工具选择

工预善其事,必先利其器。第一件事是选择一件合适的工具,开源时代,程序员还是很幸福的,选择很多。

  • flowchart.js  http://adrai.github.io/flowchart.js/ , 基于SVG创建Flow Chart

  • go.js http://www.gojs.net/latest/index.html  go.js 提供一整套的JS工具 ,支持各种交互式图表的创建。有免费版和收费版

  • joint.js http://www.jointjs.com/ joint.js 是另一个创建图标库的工具,也提供免费版和商业版

  • jsPlumb http://www.jsplumb.org/  jsPlumb是一套开源的流程图创建工具 ,小巧精悍,使用简单

  • d3 http://d3js.org 在html5领域,d3可谓是最好的可视化基础库,提供方面的DOM操作,非常强大。

最终,我选择了jsPlumb,因为它完全开源,使用很简单,用D3的话可能会多花很多功夫。joint.js也不错。大家可以根据自己的需要选择。

构建静态应用

下面我们一步一步的来使用jsPlumb来创建我们的流程图工具。

第一步是等待DOM和jsPlumb初始化完毕,类似document.ready()和jquery.ready(), 要使用jsPlumb, 需要把代码放在这个函数里:

jsPlumb.ready(function() {// ... your code goes here ...
}

创建一个jsPlumb的实例,并初始化jsPlumb的配置参数:

//Initialize JsPlumb
var color = "#E8C870";
var instance = jsPlumb.getInstance({// notice the 'curviness' argument to this Bezier curve.  the curves on this page are far smoother// than the curves on the first demo, which use the default curviness value.      Connector : [ "Bezier", { curviness:50 } ],DragOptions : { cursor: "pointer", zIndex:2000 },PaintStyle : { strokeStyle:color, lineWidth:2 },EndpointStyle : { radius:5, fillStyle:color },HoverPaintStyle : {strokeStyle:"#7073EB" },EndpointHoverStyle : {fillStyle:"#7073EB" },Container:"container-id"});

这里给给出了一些配置包括,连接线(这里配置了一个贝塞尔曲线),线的风格,连接点得风格。Container需要配置一个对应的DIV容器的id。(这里也可以使用setContainer的方法)

下面我们要创建一个节点(node),每一个节点可以用一个DIV来实现。我这里提供了一个函数来创建节点。

function addNode(parentId, nodeId, nodeLable, position) {var panel = d3.select("#" + parentId);panel.append('div').style('width','120px').style('height','50px').style('position','absolute').style('top',position.y).style('left',position.x).style('border','2px #9DFFCA solid').attr('align','center').attr('id',nodeId).classed('node',true).text(nodeLable);return jsPlumb.getSelector('#' + nodeId)[0];
}

这里做的事情就是创建了一个DIV元素,并放在对应的容器的制定位置上,注意为了支持拖拽的功能,必须使用position:absolute 。

我使用D3来操作DOM,大家可能会更习惯JQuery,这纯属个人喜好的问题。

最后返回创建节点的实例引用,这是的selector使用了jsPlumb.getSelector()方法,它和JQuery的selector是一样的,这样用的好处是你可以使用不同的DOM操作库,例如Vanilla

下面我使用一个函数来创建端点/锚点(anchor),锚点就是节点上的连接点,用于连接不同的节点。

function addPorts(instance, node, ports, type) {//Assume horizental layoutvar number_of_ports = ports.length;var i = 0;var height = $(node).height();  //Note, jquery does not include border for heightvar y_offset = 1 / ( number_of_ports + 1);var y = 0;for ( ; i < number_of_ports; i++ ) {var anchor = [0,0,0,0];var paintStyle = { radius:5, fillStyle:'#FF8891' };var isSource = false, isTarget = false;if ( type === 'output' ) {anchor[0] = 1;paintStyle.fillStyle = '#D4FFD6';isSource = true;} else {isTarget =true;}anchor[1] = y + y_offset;y = anchor[1];instance.addEndpoint(node, {uuid:node.getAttribute("id") + "-" + ports[i],paintStyle: paintStyle,anchor:anchor,maxConnections:-1,isSource:isSource,isTarget:isTarget});}
}

instance是jsPlumb的实例

node是我们用addNode方法创建的Node实例

ports,是一个string的数组,指定端点的个数和名字

type,可能是output或者input,指定端点的种类,一个节点的输出端口可以连接另一个节点的输入端口。

这里anchor是一个四维数组,0维和1维分别是锚点在节点x轴和y轴的偏移百分比。我这里希望把端口画在节点的左右两侧,并按照端口的数量均匀分布。

最后使用instance.addEndpoint来创建端点。注意这里只要指定isSource和isTarget就可以用drag&drop的方式来连接端点,非常方便。

下面一步我们提供一个函数来连接端点:

function connectPorts(instance, node1, port1, node2 , port2) {// declare some common values:var color = "gray";var arrowCommon = { foldback:0.8, fillStyle:color, width:5 },// use three-arg spec to create two different arrows with the common values:overlays = [[ "Arrow", { location:0.8 }, arrowCommon ],[ "Arrow", { location:0.2, direction:-1 }, arrowCommon ]];var uuid_source = node1.getAttribute("id") + "-" + port1;var uuid_target = node2.getAttribute("id") + "-" + port2;instance.connect({uuids:[uuid_source, uuid_target]});
}

node1和node2是源节点和目标节点的引用,port1和port2是源端口和目标端口的名字。

使用instance.connect方法来创建连接。 overlays用来添加连接线的箭头效果或者其他风格,我这里没有使用,因为觉得都不是很好看。大家如果要用,只要把overlays加入到instance.connect的方法参数就可以了。

调用以上方法来创建节点,端点和连接线。

var node1 = addNode('container-id','node1', 'node1', {x:'80px',y:'20px'});
var node2 = addNode('container-id','node2', 'node2', {x:'280px',y:'20px'});addPorts(instance, node1, ['out1','out2'],'output');
addPorts(instance, node2, ['in','in1','in2'],'input');connectPorts(instance, node1, 'out2', node2, 'in');

这里我们创建了两个节点,第一个节点有两个输出端口,第二个节点有三个输入端口,然后把第一个节点的out2端口连接到第二个端点的in端口。效果如下:

最后我们给节点增加drag&drop的功能,这样我们就可以拖动这些节点来改变图的布局了。

instance.draggable($('.node'));

这里似乎依赖于JQuery-UI,我还不是很清楚。

交互式创建节点

我们已经初步具有了创建图的功能,可是节点的创建必须通过程序,我们希望用交互的方式来创建节点。

通常我们希望有一个tree view的控件,让后通过拖拽来创建对应类型的节点。这里我使用了这个开源的tree view,基于bootstrap https://github.com/jonmiles/bootstrap-treeview

我们先创建一个tree view:

function getTreeData() {var tree = [{text: "Nodes",nodes: [{text: "Node1",},{text: "Node2"}]}]; return tree;
}
//Initialize Control Tree View
$('#control-panel').treeview({data: getTreeData()});

树上有两个节点:

然后我实现从树上拖拽对应的节点,到流程图上的逻辑。

//Handle drag and drop
$('.list-group-item').attr('draggable','true').on('dragstart', function(ev){//ev.dataTransfer.setData("text", ev.target.id);ev.originalEvent.dataTransfer.setData('text',ev.target.textContent);console.log('drag start');
});$('#container-id').on('drop', function(ev){//avoid event conlict for jsPlumbif (ev.target.className.indexOf('_jsPlumb') >= 0 ) {return;}ev.preventDefault();var mx = '' + ev.originalEvent.offsetX + 'px';var my = '' + ev.originalEvent.offsetY + 'px';console.log('on drop : ' + ev.originalEvent.dataTransfer.getData('text'));var uid = new Date().getTime();var node = addNode('flow-panel','node' + uid, 'node', {x:mx,y:my});addPorts(instance, node, ['out'],'output');addPorts(instance, node, ['in1','in2'],'input');instance.draggable($(node));
}).on('dragover', function(ev){ev.preventDefault();console.log('on drag over');
});

这里要注意的是要避免和jsPlumb拖拽端点的逻辑冲突,当检测到target是jsPlumb对象是需要直接从drop方法中退出以执行对应的jsPlumb的drop逻辑。

好了,一个绘制流程图的软件工具初步完工。

我把代码放在oschina的代码托管服务上了, 大家有兴趣可以下来试试 http://git.oschina.net/gangtao/FlowChart-Builder

用HTML5构建一个流程图绘制工具相关推荐

  1. html5流程图制作,基于HTML5小巧精悍流程图绘制工具jsPlumb

    jsPlumb是一套开源的流程图创建工具 ,小巧精悍,使用简单.它可以将html中的元素用箭头.曲线.直线等连接起来,适用于开发Web上的图表.建模工具等. jsPlumbToolkit.ready( ...

  2. jquery实现流程图绘制工具——展现红警三建造出兵操作 ——一 简介

    作为一名红警三玩家,为了提高自己的技术,我会时不时的看一些别人的录像来学习,所以想要对录像的信息进行一定的记录. 单纯用文字是很麻烦的,且不够直观,容易啰嗦. 故而我有这样一个想法: 能否用图表比较详 ...

  3. 绘制业务流程图:流程图绘制工具

    文章描述:什么是流程图?流程图和其他图表(如线框图,概念图,架构图,用例图)有什么不同? 图1:用即时贴与白板做的简单流程图 转载请注明来处,关注我请点击:http://weibo.com/heidi ...

  4. 【PC工具】更新在线流程图绘制工具bullmind,免费云存储流程图绘制,可直接粘贴图片...

    上次推荐了bullmind,今天谈谈使用感受,再推荐一款类似的软件. 先发个bullmind快捷键: 每次进入都会提示上边的快捷键,为什么我要发呢?因为"创建标签"(快捷键t)和双 ...

  5. 原型和流程图绘制工具 OmniGraffle [for Mac]

    在 Mac 上制作原型和流程图绘制工具很多人都会选择  OmniGraffl , Felix 这里有一篇关于它的说明,  推荐阅读 . 另外下面这些信息也许对你有所帮助( 来自这里 ): OmniGr ...

  6. sketch 流程图_眼前一亮!2款免费手绘风流程图绘制工具

    我在另外一篇文章:[一款让Python开发效率提升50%的工具包]画了几张手绘风格的流程图,文章发表之后有读者私信我: "这种风格的流程图好漂亮啊,请问是用什么工具画的啊?" 的确 ...

  7. jquery实现流程图绘制工具——展现红警三建造出兵操作 ——二、代码初步介绍,项目结构与文件介绍

    目录 一.简介 二.代码初步介绍 拓展.实现红警三录像文件读取与自动分析生成流程图信息 ======================= 大爽歌作,made by big shuang ======== ...

  8. draw.io---一款免费、开源的流程图绘制工具

    draw.io 是一款非常强大实用的免费.开源流程图绘制工具,功能众多,例如通过流程图来可视化您的工作流程.创建组织结构图来来显示人员结构.创建网络图来可视化网络等等,适用于商务.工程.电气.网络设计 ...

  9. er图转为数据流程图_draw.io for Mac(流程图绘制工具)

    http://draw.io Mac版是Mac平台上的一款流程图绘制工具.http://draw.io Mac版是一款非常好用的绘制流程图的工具,提供了流程图,UML图等丰富的接口.它还支持第三方云存 ...

最新文章

  1. Castle ActiveRecord学习实践(5):实现Many–Many关系的映射
  2. ArcGIS.Server.9.3和ArcGIS API for JavaScript实现Identify功能(六)
  3. itextpdf 生成word显示不全_Word经常遇到这些偏僻小问题,值的收藏
  4. JAVA正则表达式介绍和使用
  5. [Linux C]利用libxml2解析xml文件
  6. CMake中include指令介绍
  7. Objective-C的动态特性
  8. 按之字形顺序打印二叉树(C++)
  9. ecstore 定时任务配置
  10. python基础知识——文件
  11. Android VideoVIew 视频全屏拉伸
  12. ansys中模态扩展是什么意思_ANSYS模态分析教程与实例讲解.ppt
  13. 基于Node.js+Electron+CPP(DLL)的Windows桌面应用程序(自助终端)开发简介
  14. express文件上传中间件Multer详解
  15. 迈向新征程!2019国际第三代半导体大赛颁奖典礼盛大举办!
  16. 菜鸡随笔第二笔:insmod模块时显示已杀死
  17. 基于FPGA的数据采集—信号产生篇
  18. 基于RK3568开源鸿蒙的助农金融服务终端设计方案
  19. 直播系统源码如何对直播平台进行搭建?
  20. mt9d131 驱动简介

热门文章

  1. 【C#基础】Dynamic类型和正确用法
  2. 如何实现Oracle先组内排序然后再组外排序
  3. Unity3D 在一加5T手机上USB调试
  4. NC外部交换平台XML使用及解析
  5. 计算机数据表示方法及工业标准IEEE754讲解教程
  6. IIC协议与OLED
  7. mac无法访问服务器的共享文件,如何使用Mac上的“文件共享”进行连接
  8. 集合两大类之Collection集合
  9. 利用AI+大数据的方式分析恶意样本(十四)
  10. .NET平台开源项目速览(20)Newlife.Core中简单灵活的配置文件