我们专注攀枝花网站设计 攀枝花网站制作 攀枝花网站建设
成都网站建设公司服务热线:400-028-6601

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

JointJSJavaScript流程图绘制框架的示例分析

这篇文章主要介绍JointJS JavaScript流程图绘制框架的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

在凯里等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站设计、成都网站制作 网站设计制作按需搭建网站,公司网站建设,企业网站建设,品牌网站设计,营销型网站建设,外贸营销网站建设,凯里网站建设费用合理。

JointJS:JavaScript 流程图绘制框架

最近调研了js画流程图的框架,最后选择了Joint。配合上 dagre 可以画出像模像样的流程图。

JointJS 简介

JointJS 是一个开源前端框架,支持绘制各种各样的流程图、工作流图等。Rappid 是 Joint 的商业版,提供了一些更强的插件。JointJS 的特点有下面几条,摘自官网:

  • 能够实时地渲染上百(或者上千)个元素和连接

  • 支持多种形状(矩形、圆、文本、图像、路径等)

  • 高度事件驱动,用户可自定义任何发生在 paper 下的事件响应

  • 元素间连接简单

  • 可定制的连接和关系图

  • 连接平滑(基于贝塞尔插值 bezier interpolation)& 智能路径选择

  • 基于 SVG 的可定制、可编程的图形渲染

  • NodeJS 支持

  • 通过 JSON 进行序列化和反序列化

总之 JoingJS 是一款很强的流程图制作框架,开源版本已经足够日常使用了。

一些常用地址:

API: https://resources.jointjs.com/docs/jointjs/v1.1/joint.html

Tutorials: https://resources.jointjs.com/tutorial

JointJS Hello world




  


  
  
                         var graph = new joint.dia.Graph;     var paper = new joint.dia.Paper({       el: document.getElementById('myholder'),       model: graph,       width: 600,       height: 100,       gridSize: 1     });     var rect = new joint.shapes.standard.Rectangle();     rect.position(100, 30);     rect.resize(100, 40);     rect.attr({       body: {         fill: 'blue'       },       label: {         text: 'Hello',         fill: 'white'       }     });     rect.addTo(graph);     var rect2 = rect.clone();     rect2.translate(300, 0);     rect2.attr('label/text', 'World!');     rect2.addTo(graph);     var link = new joint.shapes.standard.Link();     link.source(rect);     link.target(rect2);     link.addTo(graph);   

hello world 代码没什么好说的。要注意这里的图形并没有自动排版,而是通过移动第二个 rect 实现的手动排版。

JointJS JavaScript流程图绘制框架的示例分析

前后端分离架构

既然支持 NodeJs,那就可以把繁重的图形绘制任务交给服务器,再通过 JSON 序列化在 HTTP 上传输对象,这样减轻客户端的压力。

NodeJS 后端

var express = require('express');
var joint = require('jointjs');

var app = express();

function get_graph(){
  var graph = new joint.dia.Graph();

  var rect = new joint.shapes.standard.Rectangle();
  rect.position(100, 30);
  rect.resize(100, 40);
  rect.attr({
    body: {
      fill: 'blue'
    },
    label: {
      text: 'Hello',
      fill: 'white'
    }
  });
  rect.addTo(graph);

  var rect2 = rect.clone();
  rect2.translate(300, 0);
  rect2.attr('label/text', 'World!');
  rect2.addTo(graph);

  var link = new joint.shapes.standard.Link();
  link.source(rect);
  link.target(rect2);
  link.addTo(graph);

  return graph.toJSON();
}

app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  next();
});

app.get('/graph', function(req, res){
  console.log('[+] send graph json to client')
  res.send(get_graph());
});
app.listen(8071);

HTML 前端




  


  
  
                         var graph = new joint.dia.Graph;     var paper = new joint.dia.Paper({       el: document.getElementById('myholder'),       model: graph,       width: 600,       height: 100,       gridSize: 1     });     $.get('http://192.168.237.128:8071/graph', function(data, statue){       graph.fromJSON(data);     });   

其他

自动布局 Automatic layout

JointJS 内置了插件进行自动排版,原理是调用 Dagre 库。官方 api 中有样例。

使用方法:

var graphBBox = joint.layout.DirectedGraph.layout(graph, {
nodeSep: 50,
edgeSep: 80,
rankDir: "TB"
});
配置参数注释
nodeSep相同rank的邻接节点的距离
edgeSep相同rank的邻接边的距离
rankSep不同 rank 元素之间的距离
rankDir布局方向 ( "TB" (top-to-bottom) / "BT" (bottom-to-top) / "LR" (left-to-right) / "RL"(right-to-left))
marginXnumber of pixels to use as a margin around the left and right of the graph.
marginYnumber of pixels to use as a margin around the top and bottom of the graph.
ranker排序算法。 Possible values: 'network-simplex' (default), 'tight-tree' or 'longest-path'.
resizeClustersset to false if you don't want parent elements to stretch in order to fit all their embedded children. Default is true.
clusterPaddingA gap between the parent element and the boundary of its embedded children. It could be a number or an object e.g. { left: 10, right: 10, top: 30, bottom: 10 }. It defaults to 10.
setPosition(element, position)a function that will be used to set the position of elements at the end of the layout. This is useful if you don't want to use the default element.set('position', position) but want to set the position in an animated fashion via transitions.
setVertices(link, vertices)If set to true the layout will adjust the links by setting their vertices. It defaults to false. If the option is defined as a function it will be used to set the vertices of links at the end of the layout. This is useful if you don't want to use the default link.set('vertices', vertices) but want to set the vertices in an animated fashion via transitions.
setLabels(link, labelPosition, points)If set to true the layout will adjust the labels by setting their position. It defaults to false. If the option is defined as a function it will be used to set the labels of links at the end of the layout. Note: Only the first label (link.label(0);) is positioned by the layout.
dagre默认情况下,dagre 应该在全局命名空间当中,不过你也可以当作参数传进去
graphlib默认情况下,graphlib 应该在全局命名空间当中,不过你也可以当作参数传进去

我们来试一下。NodeJS 后端

var express = require('express');
var joint = require('jointjs');
var dagre = require('dagre')
var graphlib = require('graphlib');
var app = express();
function get_graph(){
  var graph = new joint.dia.Graph();
  var rect = new joint.shapes.standard.Rectangle();
  rect.position(100, 30);
  rect.resize(100, 40);
  rect.attr({
    body: {
      fill: 'blue'
    },
    label: {
      text: 'Hello',
      fill: 'white'
    }
  });
  rect.addTo(graph);
  var rect2 = rect.clone();
  rect2.translate(300, 0);
  rect2.attr('label/text', 'World!');
  rect2.addTo(graph);
  for(var i=0; i<10; i++){
    var cir = new joint.shapes.standard.Circle();
    cir.resize(100, 100);
    cir.position(10, 10);
    cir.attr('root/title', 'joint.shapes.standard.Circle');
    cir.attr('label/text', 'Circle' + i);
    cir.attr('body/fill', 'lightblue');
    cir.addTo(graph);
    var ln = new joint.shapes.standard.Link();
    ln.source(cir);
    ln.target(rect2);
    ln.addTo(graph);
  }
  var link = new joint.shapes.standard.Link();
  link.source(rect);
  link.target(rect2);
  link.addTo(graph);
  //auto layout
  joint.layout.DirectedGraph.layout(graph, {
    nodeSep: 50,
    edgeSep: 50,
    rankDir: "TB",
    dagre: dagre,
    graphlib: graphlib
  });
  return graph.toJSON();
}
app.all('*', function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "X-Requested-With");
  res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
  next();
});
app.get('/graph', function(req, res){
  console.log('[+] send graph json to client')
  res.send(get_graph());
});
app.listen(8071);

HTML 前端




  


  
  
                         var graph = new joint.dia.Graph;     var paper = new joint.dia.Paper({       el: document.getElementById('myholder'),       model: graph,       width: 2000,       height: 2000,       gridSize: 1     });     $.get('http://192.168.237.128:8071/graph', function(data, statue){       graph.fromJSON(data);     });   

结果:

JointJS JavaScript流程图绘制框架的示例分析

使用 HTML 定制元素

流程图中的每个点,也就是是元素,都可以自定义,直接编写 html 代码能添加按钮、输入框、代码块等。

我的一个代码块 demo,搭配 highlight.js 可以达到类似 IDA 控制流图的效果。这个 feature 可玩度很高。

joint.shapes.BBL = {};
joint.shapes.BBL.Element = joint.shapes.basic.Rect.extend({
  defaults: joint.util.deepSupplement({
    type: 'BBL.Element',
    attrs: {
      rect: { stroke: 'none', 'fill-opacity': 0 }
    }
  }, joint.shapes.basic.Rect.prototype.defaults)
});

// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.BBL.ElementView = joint.dia.ElementView.extend({
  template: [
    '',
    '
',     '
',     ''   ].join(''),   initialize: function() {     _.bindAll(this, 'updateBox');     joint.dia.ElementView.prototype.initialize.apply(this, arguments);     this.$box = $(_.template(this.template)());     // Prevent paper from handling pointerdown.     this.$box.find('h4').on('mousedown click', function(evt) {       evt.stopPropagation();     });     // Update the box position whenever the underlying model changes.     this.model.on('change', this.updateBox, this);     // Remove the box when the model gets removed from the graph.     this.model.on('remove', this.removeBox, this);     this.updateBox();   },   render: function() {     joint.dia.ElementView.prototype.render.apply(this, arguments);     this.paper.$el.prepend(this.$box);     this.updateBox();     return this;   },   updateBox: function() {   // Set the position and dimension of the box so that it covers the JointJS element.     var bbox = this.model.getBBox();     // Example of updating the HTML with a data stored in the cell model.     this.$box.find('label').text(this.model.get('label'));     this.$box.find('code').html(this.model.get('code'));     var color = this.model.get('color');     this.$box.css({       width: bbox.width,       height: bbox.height,       left: bbox.x,       top: bbox.y,       background: color,       "border-color": color     });   },   removeBox: function(evt) {     this.$box.remove();   } });

以上是“JointJS JavaScript流程图绘制框架的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注创新互联行业资讯频道!


分享名称:JointJSJavaScript流程图绘制框架的示例分析
转载注明:http://shouzuofang.com/article/geccge.html

免费获取网站建设与品牌策划方案报价

*主要业务范围包括:高端网站建设, 集团网站建设(网站建设网站制作)找网站建设公司就上四川攀枝花网站建设。
提交需求

    联系我们

    028-86922220
  • 手机:13518219792
  • 地址:成都市太升南路288号锦天国际A幢1002号
  • 24小时服务热线:400-028-6601

    网站建设服务

  • 网页设计
  • 网站制作
  • 网站开发

    网站推广服务

  • 营销网站建设
  • 百度快速排名
  • 整站网站推广

    网站运维服务

  • 基础维护
  • 网站改版
  • 网站维护

    FOLLOW US

  • 微信二维码

    微信二维码

Copyright © 2022 四川攀枝花网站建设公司 四川攀枝花网站建设公司-选我们!四川专业的攀枝花网站制作公司!
All Rights Reserved 版权所有 蜀ICP备2024105912号-3