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

动态流程图关于jointJs的使用-LMLPHP

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>
04-13 16:22