这段时间由于业务需要,需要展现动态的流程图。具体实现效果如图所示:

jointJS中的线条以及框都是依赖SVG进行的二次开发。建议初学者先学习svg里相关属性,便于在阅读jointJs的API或者demo的时候有更好的理解。

svg学习可参考:http://www.w3school.com.cn/svg/index.asp

jointJS学习可参考:https://www.jointjs.com/

核心代码:

    1.   定义画布:

      var graph = new joint.dia.Graph();
      //定义画布
      var paperWidth = $('#paper').width();  //兼容性考虑这边拿div的长度
      var paper = new joint.dia.Paper({
      el: $('#paper'),
      width: paperWidth-15,
      height: 1000,
      gridSize: 1,
      model: graph,
      elementView: ElementView,
      linkView:LinkView
      });
    2.   定义连线
          //定义连线
      function link(source, target, label){
      var cell = new joint.shapes.standard.Link({
      source: { id: source.id },
      target: { id: target.id },
      labels: [{ position: 0.5, attrs: { text: { text: label || '', 'font-weight': 'bold','font-size': '12px' } } }],
      router: { name: 'manhattan' },//设置连线弯曲样式 manhattan直角
      attrs: {
      '.marker-target': {
      fill: '#333333',//箭头颜色
      d: 'M 10 0 L 0 5 L 10 10 z'//箭头样式
      },
      line: {
      stroke: '#333333', // SVG attribute and value
      'stroke-width': 0.5//连线粗细
      }
      }
      });
      graph.addCell(cell);
      return cell;
      }
    3. 业务需要去掉可移动的属性:
         var ElementView = joint.dia.ElementView.extend({
      pointerdown: function () {
      this._click = true;
      joint.dia.ElementView.prototype.pointerdown.apply(this, arguments);
      },
      pointermove: function(evt, x, y) {
      this._click = false;
      },
      pointerup: function (evt, x, y) {
      this._click = true;
      if (this._click) {
      this.notify('cell:click', evt, x, y);
      } else {
      joint.dia.ElementView.prototype.pointerup.apply(this, arguments);
      }
      }
      });
    4. 定义框的形状
         var state = function(x, y, shape, background, text){
      var cell;
      var textColor;
      if(background=="#009ACD"||background=="#FB9900"||background=="#FB9900" || background=="#EE5C42") {
      textColor = "white";
      strokeWidth = "0"
      }else {
      textColor = "black";
      strokeWidth = "1"
      } if(shape==="rect"){
      cell = new joint.shapes.standard.Rectangle();
      cell.resize(shapesSize, 40);
      cell.position(x, y);
      cell.attr('label/text', text);
      cell.attr('label/font-size', '14px');
      cell.attr('label/fill', textColor);
      cell.attr('body/refPoints', '0,5 10,0 20,5 10,10');
      cell.attr('body/fill', background);
      cell.attr('body/strokeWidth', strokeWidth);
      cell.attr('body/stroke', '#999999');
      cell.attr('body/rx', '5px');
      cell.attr('body/ry', '5px'); } else if(shape==="rect"){
      cell = new joint.shapes.basic.Rect({
      position: { x: x, y: y },//坐标
      size: { width: shapesSize, height: 40 },//宽高
      attrs: {
      rect: {
      fill: background,
      stroke: '#999999',//边框颜色
      'stroke-width': 1 ,//边框大小
      rx:'5px',
      ry: '5px'
      },
      text: { text: text,fill:textColor}, //显示文字
      }
      });
      } else if(shape==="ellipse"){
      cell = new joint.shapes.basic.Rect({
      position: { x: x, y: y },//坐标
      size: { width: shapesSize, height: 40 },//宽高
      attrs: {
      rect: {
      fill: background,
      stroke: '#999999',//边框颜色
      'stroke-width': strokeWidth,//边框大小
      rx:'28px',
      ry: '28px'
      },
      text: { text: text,fill:textColor } //显示文字
      }
      });
      } else if(shape==="polygon") {
      cell = new joint.shapes.standard.Polygon();
      cell.resize(shapesSize, 40);
      cell.position(x, y);
      cell.attr('label/text', text);
      cell.attr('label/font-size', '12px');
      cell.attr('label/fill', textColor); cell.attr('body/refPoints', '0,5 10,0 20,5 10,10');
      cell.attr('body/fill', background);
      cell.attr('body/strokeWidth', '1');
      } else if(shape==="circle") {
      var cell = new joint.shapes.standard.Circle();
      cell.resize(20, 20);
      cell.position(x, y);
      cell.attr('root/title', 'joint.shapes.standard.Circle');
      cell.attr('label/text', text);
      cell.attr('label/fill', 'white');
      cell.attr('body/fill', background);
      cell.attr('body/strokeWidth', '0');
      cell.attr('label/fill', textColor);
      cell.attr('label/font-size', '12px');
      }
      graph.addCell(cell);
      return cell;
      };
    5. 弹出框部分(根据jointJS中的demo实例进行部分修改)
          //彈出框propOver部分定義
      joint.shapes.html = {}; joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
      defaults: joint.util.deepSupplement({
      type: 'html.Element',
      attrs: {
      rect: { stroke: 'none', 'fill-opacity': 0 }
      }
      }, joint.shapes.basic.Rect.prototype.defaults)
      }); var mapFlag = new Map(); joint.shapes.html.ElementView = joint.dia.ElementView.extend({
      template: [
      '<div class="html-element"><div id="flag" style="display:none;"></div>',
      '<div class="popover fade right in" style="display: block;">',
      '<div class="arrow" style="top: 50%;"></div><div class="popover-title card-header"><a href="#" class="title "></a> <span class="arrowImg"><img src="./image/ArrowRight_2.png" class="right-side" style="margin-left:10px;" /> <img src="./image/ArrowLeft_2.png" class="left-side"/> </span></div>',
      '<div class="popover-content" style="width:200px">',
      '<div class="content">',
      '</div>',
      '</div>',
      '</div>',
      '</div>'
      ].join(''), initialize: function() {
      _.bindAll(this, 'updateBox');
      joint.dia.ElementView.prototype.initialize.apply(this, arguments);
      this.$box = $(_.template(this.template)());
      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() {
      var bbox = this.model.getBBox();
      var classBox = "html-element"+this.model.get("id");
      $(".html-element").each(function(index,tep){
      var className = String($(this).attr("class"));
      if(className=="html-element") {
      $(this).addClass(classBox);
      }
      });
      $("." + classBox + " .popover-title .title").text(this.model.get('title')); var index = mapFlag.get("html-element"+this.model.get("id")) || 0 ; //記錄第幾次 var valueSize = this.model.get('JsonValue').length;
      if(valueSize>1) {
      if(index != 0) {
      $(".left-side").attr('src',"./image/Arrowleft_1.png");
      $(".left-side").css("cursor","pointer");
      }else {
      $(".left-side").css("cursor","auto");
      $(".right-side").css("cursor","pointer");
      }
      if(index != valueSize-1) {
      $(".right-side").attr('src',"./image/ArrowRight_1.png");
      $(".right-side").css("cursor","pointer");
      } else {
      $(".left-side").css("cursor","pointer");
      $(".right-side").css("cursor","auto");
      }
      $("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); } var JsonValue = this.model.get('JsonValue')[index]; for(var item in JsonValue){
      $(".content").append('<span class="labelSpan">'+String(JsonValue[item].name)+'</span>');
      $(".content").append("<span class='valueSpan'>"+JsonValue[item].value+"</span></br>");
      } $("." + classBox).on("click",(e)=>{
      e.stopPropagation()
      }); if(this.model.get('title')=="最終理算"){
      $('.right-side').on('click', (e)=>{
      e.stopPropagation();
      index++;
      if(index > valueSize-1 || index < 0) {
      index--;
      return;
      }
      mapFlag.set("html-element"+this.model.get("id"),index);
      JsonValue = this.model.get('JsonValue')[index];
      $("." + classBox + " .labelSpan").each(function(index,tep){
      $(this).text(JsonValue[index].name);
      }); $("." + classBox + " .valueSpan").each(function(index,tep){
      $(this).text(JsonValue[index].value);
      });
      $("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); $(".right-side").attr('src',"./image/ArrowRight_2.png");
      $(".left-side").attr('src',"./image/Arrowleft_2.png");
      if(valueSize > 1) {
      if(index != 0) {
      $(".left-side").attr('src',"./image/Arrowleft_1.png");
      $(".left-side").css("cursor","pointer");
      }else {
      $(".left-side").css("cursor","auto");
      $(".right-side").css("cursor","pointer");
      }
      if(index != valueSize-1) {
      $(".right-side").attr('src',"./image/ArrowRight_1.png");
      $(".right-side").css("cursor","pointer");
      } else {
      $(".left-side").css("cursor","pointer");
      $(".right-side").css("cursor","auto");
      }
      }
      }); $('.left-side').on('click', (e)=>{
      e.stopPropagation();
      index--;
      if(index > valueSize-1 || index < 0) {
      index++;
      return;
      }
      mapFlag.set("html-element"+this.model.get("id"),index);
      JsonValue = this.model.get('JsonValue')[index];
      $("." + classBox + " .labelSpan").each(function(index,tep){
      $(this).text(JsonValue[index].name);
      }); $("." + classBox + " .valueSpan").each(function(index,tep){
      $(this).text(JsonValue[index].value);
      });
      $("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); $(".right-side").attr('src',"./image/ArrowRight_2.png");
      $(".left-side").attr('src',"./image/Arrowleft_2.png");
      if(valueSize>1) {
      if(index != 0) {
      $(".left-side").attr('src',"./image/Arrowleft_1.png");
      $(".left-side").css("cursor","pointer");
      }else {
      $(".left-side").css("cursor","auto");
      $(".right-side").css("cursor","pointer");
      }
      if(index != valueSize-1) {
      $(".right-side").attr('src',"./image/ArrowRight_1.png");
      $(".right-side").css("cursor","pointer");
      } else {
      $(".left-side").css("cursor","pointer");
      $(".right-side").css("cursor","auto");
      }
      }
      });
      } this.$box.css({
      width: bbox.width,
      height: bbox.height,
      left: bbox.x,
      top: bbox.y,
      });
      },
      removeBox: function(evt) {
      this.$box.remove();
      }, changeBox: function(evt) {
      this.$box.remove();
      }, });
    6. 定义事件
          paper.on('cell:click', function (e) {
      let offsetX = $("#"+e.id).offset().left;
      let offsetY = $("#"+e.id).offset().top; if($("#"+e.id+" title").html()=="joint.shapes.standard.Circle") {
      return;
      } var arr = $("#"+e.id+" tspan");
      var tmp="";
      $.each(arr, function(k,v){
      tmp+=$(v).html();
      }); map.forEach(function (item, key, mapObj) {
      item.remove();
      });
      map.clear(); var el1;
      if(tmp=="已完成" || tmp=="未完成" || tmp=="未生成" || tmp=="整案結案" || tmp=="代服務簽核?" || tmp=="預估調整?" || tmp=="預估簽核?" || tmp=="免賠簽核?" || tmp=="全部免賠?" || tmp=="賠款決賠簽核?" || tmp=="部分賠付?") {
      return;
      }
      if(tmp=="立案" || tmp=="分案確認" || tmp=="初次預估" || tmp == "車損查勘") {
      el1 = new joint.shapes.html.Element({
      id: e.id,
      position: { x: offsetX+5, y: offsetY-210 },
      size: { width: 170, height: 120 },
      JsonValue:[[{name: "開始時間" , value:'107/07/01'},{name: '結束時間' , value:'107/07/01'},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'}]],
      title:tmp
      });
      } else if(tmp=="最終理算") {
      el1 = new joint.shapes.html.Element({
      id: e.id,
      position: { x: offsetX+5, y: offsetY-210 },
      size: { width: 170, height: 120 },
      JsonValue:[[{name: "開始時間" , value:'107/07/01'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'},{name: '和解時間' , value: '107/07/04'},{name: '資料補全日' , value: '107/07/04'}],[{name: '開始時間' , value:'107/07/03'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '否'},{name: '處理人員' , value: '張三'},{name: '和解時間' , value: '107/07/04'},{name: '資料補全日' , value: '107/07/04'}]],
      title:tmp
      });
      } else {
      el1 = new joint.shapes.html.Element({
      id: e.id,
      position: { x: offsetX+5, y: offsetY-210 },
      size: { width: 170, height: 120 },
      JsonValue:[[{name: '開始時間' , value:'107/07/01'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'}]],
      title:tmp
      });
      }
      graph.addCell(el1);
      map.set(e.id,el1);
      });

    代码会有部分冗余,没有做过多的修改,只是做demo用,后期因为会封装进react。所以数据结构等暂未考虑!依赖部分网络上有请自行下载,vendor.min.css样式可忽略。全部代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="./css/joint.css" />
<link rel="stylesheet" type="text/css" href="./css/vendor.min.css" />
<link rel="stylesheet" type="text/css" href="./css/bootstrap.min.css" /> <!-- dependencies -->
<script src="./js/jquery.js"></script>
<script src="./js/lodash.js"></script>
<script src="./js/backbone.js"></script>
<script src="./js/joint.js"></script>
<script src="./js/bootstrap.min.js"></script>
<style> .html-element {
position: absolute;
pointer-events: auto;
} .html-element .valueSpan {
padding-left:25px
} .right-side {
pointer-events: auto;
float:right
} .left-side {
pointer-events: auto;
float:right
}
.html2-margin {
margin-left:120px;
} .card-header {
margin-bottom: 0;
background-color: rgba(0,0,0,.03);
border-bottom: 1px solid rgba(0,0,0,.125);
} .card-header h4:before {
height: 100%;
transform: scale(0.75);
width: 5px;
margin-top: -3px;
} .card-header h4:before {
content: '';
width: 4px;
float: left;
height: 25px!important;
background-color: #ff8200;
margin-right: 10px;
border-radius: 8px;
} .card-header a:before {
height: 100%;
transform: scale(0.75);
width: 5px;
} .card-header a:before {
content: '';
width: 4px;
float: left;
height: 20px!important;
background-color: #ff8200;
margin-right: 8px;
border-radius: 8px;
} .colorBlue {
width:10px;
height:10px;
background-color:#009ACD
} .colorBlue {
width:10px;
height:10px;
background-color:#009ACD
} .colorBlue {
width:10px;
height:10px;
background-color:#009ACD
} .colorOrange {
width:10px;
height:10px;
background-color:#FB9900
} .colorGrey {
width:10px;
height:10px;
background-color:#F2F2F2
} .finishColor:before{
content: '';
width: 12px;
height: 12px!important;
background-color: #009ACD;
margin-right: 20px;
padding-right: 16px;
} .finishColor {
float:right;
margin-top:40px;
padding-right:30px;
} .notFinishColor:before{
content: '';
width: 12px;
height: 12px!important;
background-color: #FB9900;
margin-right: 20px;
padding-right: 16px;
} .notFinishColor {
float:right;
margin-top:40px;
padding-right:30px;
} .notGenerate:before{
content: '';
width: 12px;
height: 12px!important;
background-color: #F2F2F2;
margin-right: 20px;
padding-right: 16px;
} .notGenerate {
float:right;
margin-top:40px;
padding-right:30px;
} .arrowImg img {
float:right
} .html-element .labelSpan {
color: #666;
display: inline-block;
width: 42%;
} .html-element .valueSpan {
color: #212529;
}
</style> </head>
<body>
<div class="container" style="width: 100%; max-width: 90%;">
<div style="height:100px">
<p class="notGenerate">未開啟</p>
<p class="notFinishColor">未完成</p>
<p class="finishColor">已完成</p> </div>
<div class="card card-outline-default">
<div class="card-header">
<h4 class="card-title" tabindex="-1">
賠案號碼:123789123978
</h4>
</div>
<div class="card-block collapse show">
<div id="paper" class="paper" onclick="ccc()"></div>
</div>
<div>
</div> </body> <!-- code -->
<script type="text/javascript"> var graph = new joint.dia.Graph(); //定义连线
function link(source, target, label){
var cell = new joint.shapes.standard.Link({
source: { id: source.id },
target: { id: target.id },
labels: [{ position: 0.5, attrs: { text: { text: label || '', 'font-weight': 'bold','font-size': '12px' } } }],
router: { name: 'manhattan' },//设置连线弯曲样式 manhattan直角
attrs: {
'.marker-target': {
fill: '#333333',//箭头颜色
d: 'M 10 0 L 0 5 L 10 10 z'//箭头样式
},
line: {
stroke: '#333333', // SVG attribute and value
'stroke-width': 0.5//连线粗细
}
}
});
graph.addCell(cell);
return cell;
} var ElementView = joint.dia.ElementView.extend({
pointerdown: function () {
this._click = true;
joint.dia.ElementView.prototype.pointerdown.apply(this, arguments);
},
pointermove: function(evt, x, y) {
this._click = false;
},
pointerup: function (evt, x, y) {
this._click = true;
if (this._click) {
this.notify('cell:click', evt, x, y);
} else {
joint.dia.ElementView.prototype.pointerup.apply(this, arguments);
}
}
}); var LinkView = joint.dia.LinkView.extend({
addVertex: function(evt, x, y) {},
removeVertex: function(endType) {},
pointerdown:function(evt, x, y) {}
}); //定义画布
var paperWidth = $('#paper').width();
var paper = new joint.dia.Paper({
el: $('#paper'),
width: paperWidth-15,
height: 1000,
gridSize: 1,
model: graph,
elementView: ElementView,
linkView:LinkView
});
var shapesSize = paperWidth/12;
//定義框的形狀
var state = function(x, y, shape, background, text){
var cell;
var textColor;
if(background=="#009ACD"||background=="#FB9900"||background=="#FB9900" || background=="#EE5C42") {
textColor = "white";
strokeWidth = "0"
}else {
textColor = "black";
strokeWidth = "1"
} if(shape==="rect"){
cell = new joint.shapes.standard.Rectangle();
cell.resize(shapesSize, 40);
cell.position(x, y);
cell.attr('label/text', text);
cell.attr('label/font-size', '14px');
cell.attr('label/fill', textColor);
cell.attr('body/refPoints', '0,5 10,0 20,5 10,10');
cell.attr('body/fill', background);
cell.attr('body/strokeWidth', strokeWidth);
cell.attr('body/stroke', '#999999');
cell.attr('body/rx', '5px');
cell.attr('body/ry', '5px'); } else if(shape==="rect"){
cell = new joint.shapes.basic.Rect({
position: { x: x, y: y },//坐标
size: { width: shapesSize, height: 40 },//宽高
attrs: {
rect: {
fill: background,
stroke: '#999999',//边框颜色
'stroke-width': 1 ,//边框大小
rx:'5px',
ry: '5px'
},
text: { text: text,fill:textColor}, //显示文字
}
});
} else if(shape==="ellipse"){
cell = new joint.shapes.basic.Rect({
position: { x: x, y: y },//坐标
size: { width: shapesSize, height: 40 },//宽高
attrs: {
rect: {
fill: background,
stroke: '#999999',//边框颜色
'stroke-width': strokeWidth,//边框大小
rx:'28px',
ry: '28px'
},
text: { text: text,fill:textColor } //显示文字
}
});
} else if(shape==="polygon") {
cell = new joint.shapes.standard.Polygon();
cell.resize(shapesSize, 40);
cell.position(x, y);
cell.attr('label/text', text);
cell.attr('label/font-size', '12px');
cell.attr('label/fill', textColor); cell.attr('body/refPoints', '0,5 10,0 20,5 10,10');
cell.attr('body/fill', background);
cell.attr('body/strokeWidth', '1');
} else if(shape==="circle") {
var cell = new joint.shapes.standard.Circle();
cell.resize(20, 20);
cell.position(x, y);
cell.attr('root/title', 'joint.shapes.standard.Circle');
cell.attr('label/text', text);
cell.attr('label/fill', 'white');
cell.attr('body/fill', background);
cell.attr('body/strokeWidth', '0');
cell.attr('label/fill', textColor);
cell.attr('label/font-size', '12px');
}
graph.addCell(cell);
return cell;
}; //创建元素
//定义形状
var setX = 20; //初始的x軸位置
var setY = 20; //初始的y軸位置
var addSetX = paperWidth/8;
var addSetY = 80; //leave 1
//var start = state(setX,setY,"ellipse","#009ACD", "开始");
var last = state(setX + addSetX*7,setY,"ellipse","#F2F2F2","整案結案");
//leave 2
setY = setY-addSetY
var state0 = state(setX,setY+addSetY,"ellipse","#009ACD", "立案"); //leave 3
var state4 = state(setX,setY+addSetY*2,"rect","#009ACD","分案確認");
link(state0,state4,""); //leave 4
setY = setY+shapesSize/2;
var state5 = state(setX + addSetX*1,setY+addSetY*3,"rect","#009ACD","竊盜查勘");
link(state4,state5,"").vertices([
new g.Point(setX+shapesSize/2, setY+addSetY*3+20),
]); //state(setX + addSetX*1+83,setY+addSetY*3-10,"circle","#289DD8", "15"); var state6 = state(setX + addSetX*2,setY+addSetY*3,"rect","#009ACD","初次預估");
link(state5,state6,"")
var state7 = state(setX + addSetX*3,setY+addSetY*3,"rect","#FB9900","預估調整");
state(setX + addSetX*3+shapesSize-shapesSize/8,setY+addSetY*3-10,"circle","#EE5C42", "15"); link(state6,state7,"")
var state8 = state(setX + addSetX*4,setY+addSetY*3,"rect","#FB9900","最終理算");
link(state7,state8,"")
var state9 = state(setX + addSetX*5,setY+addSetY*3,"rect","#F2F2F2","賠款決賠");
link(state8,state9,"")
var state10 = state(setX + addSetX*6,setY+addSetY*3,"rect","#F2F2F2","錯更簽核");
link(state10,state9,"")
link(state10,state8,"").vertices([
new g.Point(setX + addSetX*6+shapesSize/2, setY+addSetY*3-20),
new g.Point(setX + addSetX*4+shapesSize/2, setY+addSetY*3-20),
]); //leave 5
var state31 = state(setX + addSetX,setY+addSetY*4,"rect","#009ACD","查勘簽核");
link(state5,state31); var state11 = state(setX + addSetX*3,setY+addSetY*4,"rect","#F2F2F2","預估簽核");
link(state7,state11,"");
var state12 = state(setX + addSetX*4,setY+addSetY*4,"rect","#F2F2F2","免賠簽核"); link(state8,state12,"");
var state13 = state(setX + addSetX*5,setY+addSetY*4,"rect","#F2F2F2","決賠簽核");
link(state9,state13,"");
var state14 = state(setX + addSetX*6,setY+addSetY*4,"rect","#F2F2F2","錯誤結次更正");
link(state13,state14,"");
link(state14,state10,"");
//leave 6
var state15 = state(setX + addSetX,setY+addSetY*5,"rect","#FB9900","損失關閉");
link(state4,state15,"").vertices([
new g.Point(setX+shapesSize/2, setY+addSetY*5+20),
]); var state16 = state(setX + addSetX*2,setY+addSetY*5,"rect","#F2F2F2","損失關閉簽核");
link(state15,state16,"");
var state17 = state(setX + addSetX*6,setY+addSetY*5,"rect","#F2F2F2","結案");
link(state16,state17,"");
link(state12,state17,"").vertices([
new g.Point(setX+addSetX*4+shapesSize/2, setY+addSetY*5+20),
]);
link(state13,state17,"").vertices([
new g.Point(setX+addSetX*5+shapesSize/2, setY+addSetY*5+20),
]);
link(state17,last,"").vertices([
new g.Point(setX+addSetX*7+shapesSize/2, setY+addSetY*5+20),
]); //leave 8
var state18 = state(setX + addSetX*1,setY+addSetY*7,"rect","#009ACD","人傷查勘");
link(state4,state18,"").vertices([
new g.Point(setX+shapesSize/2, setY+addSetY*7+20),
]); //leave 8
var state19 = state(setX + addSetX*2,setY+addSetY*7,"rect","#009ACD","初次預估");
link(state18,state19,"");
var state20 = state(setX + addSetX*3,setY+addSetY*7,"rect","#FB9900","預估調整");
link(state19,state20,"");
var state21 = state(setX + addSetX*4,setY+addSetY*7,"rect","#F2F2F2","最終理算");
link(state20,state21,"");
var state22 = state(setX + addSetX*5,setY+addSetY*7,"rect","#F2F2F2","賠款決賠");
link(state21,state22,"");
var state23 = state(setX + addSetX*6,setY+addSetY*7,"rect","#F2F2F2","錯更簽核");
link(state23,state22,"");
link(state23,state21,"").vertices([
new g.Point(setX+addSetX*6+shapesSize/2, setY+addSetY*7-20),
new g.Point(setX+addSetX*4+shapesSize/2, setY+addSetY*7-20)
]); //leave 8
var state24 = state(setX + addSetX*3,setY+addSetY*8,"rect","#F2F2F2","預估簽核");
link(state20,state24,"");
var state25 = state(setX + addSetX*4,setY+addSetY*8,"rect","#F2F2F2","免賠簽核");
link(state21,state25,"");
var state26 = state(setX + addSetX*5,setY+addSetY*8,"rect","#F2F2F2","決賠簽核");
link(state22,state26,"");
var state27 = state(setX + addSetX*6,setY+addSetY*8,"rect","#F2F2F2","錯誤結次更正");
link(state26,state27,"");
link(state27,state23,""); //leave 10
var state28 = state(setX + addSetX,setY+addSetY*9,"rect","#FB9900","損失關閉");
link(state4,state28,"").vertices([
new g.Point(setX+shapesSize/2, setY+addSetY*9+20),
]);
var state29 = state(setX + addSetX*2,setY+addSetY*9,"rect","#F2F2F2","損失關閉簽核");
link(state28,state29);
var state30 = state(setX + addSetX*6,setY+addSetY*9,"rect","#F2F2F2","結案");
link(state29,state30);
link(state25,state30).vertices([
new g.Point(setX + addSetX*4+shapesSize/2, setY+addSetY*9+20),
]);
link(state26,state30).vertices([
new g.Point(setX+addSetX*5+shapesSize/2, setY+addSetY*9+20),
]);
link(state30,last).vertices([
new g.Point(setX+addSetX*7+shapesSize/2, setY+addSetY*9+20),
]); //彈出框propOver部分定義
joint.shapes.html = {}; joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'html.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
}); var mapFlag = new Map(); joint.shapes.html.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element"><div id="flag" style="display:none;"></div>',
'<div class="popover fade right in" style="display: block;">',
'<div class="arrow" style="top: 50%;"></div><div class="popover-title card-header"><a href="#" class="title "></a> <span class="arrowImg"><img src="./image/ArrowRight_2.png" class="right-side" style="margin-left:10px;" /> <img src="./image/ArrowLeft_2.png" class="left-side"/> </span></div>',
'<div class="popover-content" style="width:200px">',
'<div class="content">',
'</div>',
'</div>',
'</div>',
'</div>'
].join(''), initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
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() {
var bbox = this.model.getBBox();
var classBox = "html-element"+this.model.get("id");
$(".html-element").each(function(index,tep){
var className = String($(this).attr("class"));
if(className=="html-element") {
$(this).addClass(classBox);
}
});
$("." + classBox + " .popover-title .title").text(this.model.get('title')); var index = mapFlag.get("html-element"+this.model.get("id")) || 0 ; //記錄第幾次 var valueSize = this.model.get('JsonValue').length;
if(valueSize>1) {
if(index != 0) {
$(".left-side").attr('src',"./image/Arrowleft_1.png");
$(".left-side").css("cursor","pointer");
}else {
$(".left-side").css("cursor","auto");
$(".right-side").css("cursor","pointer");
}
if(index != valueSize-1) {
$(".right-side").attr('src',"./image/ArrowRight_1.png");
$(".right-side").css("cursor","pointer");
} else {
$(".left-side").css("cursor","pointer");
$(".right-side").css("cursor","auto");
}
$("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); } var JsonValue = this.model.get('JsonValue')[index]; for(var item in JsonValue){
$(".content").append('<span class="labelSpan">'+String(JsonValue[item].name)+'</span>');
$(".content").append("<span class='valueSpan'>"+JsonValue[item].value+"</span></br>");
} $("." + classBox).on("click",(e)=>{
e.stopPropagation()
}); if(this.model.get('title')=="最終理算"){
$('.right-side').on('click', (e)=>{
e.stopPropagation();
index++;
if(index > valueSize-1 || index < 0) {
index--;
return;
}
mapFlag.set("html-element"+this.model.get("id"),index);
JsonValue = this.model.get('JsonValue')[index];
$("." + classBox + " .labelSpan").each(function(index,tep){
$(this).text(JsonValue[index].name);
}); $("." + classBox + " .valueSpan").each(function(index,tep){
$(this).text(JsonValue[index].value);
});
$("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); $(".right-side").attr('src',"./image/ArrowRight_2.png");
$(".left-side").attr('src',"./image/Arrowleft_2.png");
if(valueSize > 1) {
if(index != 0) {
$(".left-side").attr('src',"./image/Arrowleft_1.png");
$(".left-side").css("cursor","pointer");
}else {
$(".left-side").css("cursor","auto");
$(".right-side").css("cursor","pointer");
}
if(index != valueSize-1) {
$(".right-side").attr('src',"./image/ArrowRight_1.png");
$(".right-side").css("cursor","pointer");
} else {
$(".left-side").css("cursor","pointer");
$(".right-side").css("cursor","auto");
}
}
}); $('.left-side').on('click', (e)=>{
e.stopPropagation();
index--;
if(index > valueSize-1 || index < 0) {
index++;
return;
}
mapFlag.set("html-element"+this.model.get("id"),index);
JsonValue = this.model.get('JsonValue')[index];
$("." + classBox + " .labelSpan").each(function(index,tep){
$(this).text(JsonValue[index].name);
}); $("." + classBox + " .valueSpan").each(function(index,tep){
$(this).text(JsonValue[index].value);
});
$("." + classBox + " .popover-title .title").text(this.model.get('title')+"-00"+(index+1)); $(".right-side").attr('src',"./image/ArrowRight_2.png");
$(".left-side").attr('src',"./image/Arrowleft_2.png");
if(valueSize>1) {
if(index != 0) {
$(".left-side").attr('src',"./image/Arrowleft_1.png");
$(".left-side").css("cursor","pointer");
}else {
$(".left-side").css("cursor","auto");
$(".right-side").css("cursor","pointer");
}
if(index != valueSize-1) {
$(".right-side").attr('src',"./image/ArrowRight_1.png");
$(".right-side").css("cursor","pointer");
} else {
$(".left-side").css("cursor","pointer");
$(".right-side").css("cursor","auto");
}
}
});
} this.$box.css({
width: bbox.width,
height: bbox.height,
left: bbox.x,
top: bbox.y,
});
},
removeBox: function(evt) {
this.$box.remove();
}, changeBox: function(evt) {
this.$box.remove();
}, }); //彈出部分定義
joint.shapes.html2 = {}; joint.shapes.html2.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'html2.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
}); joint.shapes.html2.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="container html2-margin">',
'<div class="card card-outline-default" style="margin-top: 200px;">',
'<div class="card-header" style="padding:5px;"><span><h4 class="card-title" tabindex="-1">賠案號碼:123789123978</h4></span></div>',
'<div class="card-block collapse show">',
'<div style="height:250px"></div>',
'</div>',
'</div>',
'</div>'
].join(''), initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)()); this.updateBox();
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
this.updateBox();
return this;
},
updateBox: function() {
let width = paperWidth*0.8 + "px";
$(".html2-margin .card-outline-default").css('width',width);
let maginleft = paperWidth/12+20+"px"
$(".html2-margin").css('margin-left',maginleft);
var bbox = this.model.getBBox();
this.model.get("title");
this.$box.find(".card-header h4").text(this.model.get("title"));
this.$box.find(".card-outline-default").css("margin-top",this.model.get("top"));
this.$box.css({
width: bbox.width,
height: bbox.height,
left: bbox.x,
top: bbox.y,
});
},
removeBox: function(evt) {
this.$box.remove();
}
}); var html2 = new joint.shapes.html2.Element({
title:"本車財損:PCE-0234",
top:"135px"
}); var html3 = new joint.shapes.html2.Element({
title:"人傷查勘:江志軍",
top:"455px"
}); graph.addCell(html2);
graph.addCell(html3); //给所有元素添加点击事件
var map = new Map();
paper.on('cell:click', function (e) {
let offsetX = $("#"+e.id).offset().left;
let offsetY = $("#"+e.id).offset().top; if($("#"+e.id+" title").html()=="joint.shapes.standard.Circle") {
return;
} var arr = $("#"+e.id+" tspan");
var tmp="";
$.each(arr, function(k,v){
tmp+=$(v).html();
}); map.forEach(function (item, key, mapObj) {
item.remove();
});
map.clear(); var el1;
if(tmp=="已完成" || tmp=="未完成" || tmp=="未生成" || tmp=="整案結案" || tmp=="代服務簽核?" || tmp=="預估調整?" || tmp=="預估簽核?" || tmp=="免賠簽核?" || tmp=="全部免賠?" || tmp=="賠款決賠簽核?" || tmp=="部分賠付?") {
return;
}
if(tmp=="立案" || tmp=="分案確認" || tmp=="初次預估" || tmp == "車損查勘") {
el1 = new joint.shapes.html.Element({
id: e.id,
position: { x: offsetX+5, y: offsetY-210 },
size: { width: 170, height: 120 },
JsonValue:[[{name: "開始時間" , value:'107/07/01'},{name: '結束時間' , value:'107/07/01'},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'}]],
title:tmp
});
} else if(tmp=="最終理算") {
el1 = new joint.shapes.html.Element({
id: e.id,
position: { x: offsetX+5, y: offsetY-210 },
size: { width: 170, height: 120 },
JsonValue:[[{name: "開始時間" , value:'107/07/01'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'},{name: '和解時間' , value: '107/07/04'},{name: '資料補全日' , value: '107/07/04'}],[{name: '開始時間' , value:'107/07/03'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '否'},{name: '處理人員' , value: '張三'},{name: '和解時間' , value: '107/07/04'},{name: '資料補全日' , value: '107/07/04'}]],
title:tmp
});
} else {
el1 = new joint.shapes.html.Element({
id: e.id,
position: { x: offsetX+5, y: offsetY-210 },
size: { width: 170, height: 120 },
JsonValue:[[{name: '開始時間' , value:'107/07/01'},{name: '結束時間' , value:''},{name:'是否逾期' , value: '是'},{name: '處理人員' , value: '張三'}]],
title:tmp
});
}
graph.addCell(el1);
map.set(e.id,el1);
}); function ccc() {
map.forEach(function (item, key, mapObj) {
item.remove();
});
map.clear();
} </script> </html>

动态流程图关于jointJs的使用的更多相关文章

  1. vue JointJS 实例demo

    前言 越来越发现,前端深入好难哦!虐成渣渣了. 需求:前端绘制灵活的关系图(此demo还是简单的,我的需求才跨出一小步) 安装 npm install jointjs 容器,工具栏 <templ ...

  2. JointJS绘制流程图

    摘要: JointJS是一个javascript图表库.你可以使用它制作静态或者动态的图表.关系表.流程图. 效果图:

  3. [原]JointJS流程图

    最近项目上需要用流程图来做问题定界分析,之前有同事用jsPlumb做过,但是阅读代码后觉得比较麻烦,所以自己又找了一圈,找到一个叫Dagre-D3的开源类库,画出来的效果如下图,Dagre-D3最大的 ...

  4. jointJS初使用随记

    jointJs使用随记 1.下载与安装 前提:一个健康良好且干净的vue脚手架项目. 还是普遍的安装方式 yarn:yarn add jointjs npm:npm install jointjs 还 ...

  5. 20款 JavaScript 开发框架推荐给前端开发者

    下面,我们给大家提供了一个用于 HTML5 开发的各种用途的 JavaScript 库列表.这些框架能够给前端开发人员提供更好的功能实现的解决方案.如果你有收藏优秀的框架,也可以在后面的评论中分享给我 ...

  6. HTML5优秀图表控件

    不管是哪个领域的开发,都有机会用到图表来做统计分析,以更直观的表现形式来代替传统的文字.在以前,图表控件主要有使用程序代码生成的静态图片,或者是使用flash实现的图表控件. 在HTML5非常流行的当 ...

  7. 使用jsPlumb制作流程图设计器

    jsPlumb是一个比较强大的绘图组件,它提供了一种方法,主要用于连接网页上的元素.在现代浏览器中,它使用SVG或者Canvas技术,而对于IE8以下(含IE8)的古董浏览器,则使用VML技术. 项目 ...

  8. jQuery图表开源软件

    jQuery图表插件 jQchart jQchart 是一个jQuery的插件,用来绘制图表的.支持各种形状的图表. 示例代码: == Mini sample == $('#canvasMyID'). ...

  9. 用HTML5构建一个流程图绘制工具

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

随机推荐

  1. svn hotcopy backup

    ================== 备份 1/2 ==================svnbackup.bat@echo off@rem Subversion Server 的安装目录set SV ...

  2. ElasticSearch改造研报查询实践

    背景: 1,系统简介:通过人工解读研报然后获取并录入研报分类及摘要等信息,系统通过摘要等信息来获得该研报的URI 2,现有实现:老系统使用MSSQL存储摘要等信息,并将不同的关键字分解为不同字段来提供 ...

  3. 站在Web3.0 理解IPFS是什么

    尽管网络上,已经有不少文章讨论IPFS,不过真正讲明白IPFS想做什么的很少,文本尝试站在未来Web3.0的高度来看看IPFS究竟用来解决什么问题. DApp 的缺陷 对区块链有所了解的同学,知道区块 ...

  4. java之JVM(一)

    内存模型: Java内存模型建立在自动内存管理的概念之上.当一个对象不再被一个应用所引用,垃圾回收器就会回收它,从而释放相应的内存. JVM从底层操作系统中分配内存,并将它们分为以下几个区域: 方法区 ...

  5. Linux 细节(杂)

    1.所有上传至linux服务器的文件都是英文,避免中文出现乱码导致一些非预期错误,难以查找. 2.删除较危险,linux没有回收站,慎用 rm -rf 3.vi/vim学习地址:http://www. ...

  6. Vue2.0使用vue-cli脚手架搭建

    一:安装node.js Node.js官网:https://nodejs.org/en/download/ 选择相应的版本即可安装 通过node自带的npm包管理工具 二.安装依赖 安装依赖:npm ...

  7. python数据结构与算法之问题求解

    懂得计算机的童鞋应该都知道,一条计算机程序由数据结构跟算法两大部分组成.所以,其实不管你使用哪种计算机语言编写程序,最终这两部分才是一个程序设计的核心.所以,一个不懂得数据结构与算法的程序员不是一个好 ...

  8. var that = this 小坑记

    在js编码过程中,经常会使用如上的语句来规避拿不到变量的问题. 比如: queryData:function () { var that=this; var param={}; for(var key ...

  9. Abp 中 模块 加载及类型自动注入 源码学习笔记

    注意 互相关联多使用接口注册,所以可以 根据需要替换. 始于 Startup.cs 中的  通过 AddApplication 扩展方法添加 Abp支持 1 services.AddApplicati ...

  10. 干货!一篇文章集合所有Linux基础命令

    1 文件{ls -rtl # 按时间倒叙列出所有目录和文件 ll -rttouch file # 创建空白文件rm -rf 目录名 # 不提示删除非空目录(-r:递归删除 -f强制)dos2unix ...