ToB企服应用市场:ToB评测及商务社交产业平台

标题: html简易流程图 [打印本页]

作者: 花瓣小跑    时间: 2024-10-29 09:30
标题: html简易流程图
效果图

使用html+css+js,无图片,没用Canvas
demo:
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <link href="draw.css" rel="stylesheet" />
  5.     <script src="draw.js" type="text/javascript"></script>
  6. </head>
  7. <body>
  8.     <div class="diamond" style="top:100px;left: 100px;">
  9.         <span class="diamond-text">开始</span>
  10.     </div>
  11.     <!-- 下箭头 -->
  12.     <div class="arrow-down" style="top:195px;left:140px;">
  13.         <span></span>
  14.     </div>
  15.     <div class="rectangle" style="top:275px;left: 100px;">
  16.         <span class="rectangle-text">步骤一</span>
  17.     </div>
  18.     <div class="arrow-down" style="top:325px;left:140px;">
  19.         <span></span>
  20.     </div>
  21.     <div class="rectangle" style="top:405px;left: 100px;">
  22.         <span class="rectangle-text">步骤二</span>
  23.     </div>
  24.     <div class="arrow-down" style="top:455px;left:140px;">
  25.         <span></span>
  26.     </div>
  27.     <div class="diamond" style="top:550px;left: 100px;">
  28.         <span class="diamond-text">分叉节点</span>
  29.     </div>
  30.     <div>
  31.         <div class="arrow-down" style="top:645px;left:140px;">
  32.             <span></span>
  33.         </div>
  34.         <div class="rectangle" style="top:725px;left: 100px;">
  35.             <span class="rectangle-text">步骤三</span>
  36.         </div>
  37.     </div>
  38.     <div>
  39.         <div class="arrow-horizontal-down" style="top:590px;left:195px;">
  40.             <div></div>
  41.             <span></span>
  42.         </div>
  43.         <div class="rectangle" style="top:725px;left: 230px;">
  44.             <span class="rectangle-text">步骤四</span>
  45.         </div>
  46.     </div>
  47. </body>
  48. </html>
复制代码
css:
  1. /* 椭圆,未用到,使用时需修改 */
  2. .ellipse {
  3.   width: 200px;
  4.   height: 100px;
  5.   background-color: #6495ED;
  6.   border-radius: 100px;
  7. }
  8. .ellipse-text {
  9.   width: 150px;
  10.   height: 150px;
  11.   margin-top: 20px;
  12.   margin-left: 20px;
  13. }
  14. /* 菱形,长宽91.28 */
  15. .diamond {
  16.   width: 80px;
  17.   height: 80px;
  18.   transform: rotate(45deg);
  19.   background-color: #bfa;
  20.   position: absolute;
  21. }
  22. .diamond-text{
  23.   width: 60px;
  24.   margin-top: 10px;
  25.   display: inline-block;
  26.   transform: rotate(-45deg);
  27.   text-align: center;
  28. }
  29. /* 长方形 */
  30. .rectangle{
  31.   width: 92px;
  32.   height: 50px;
  33.   border: 1px;
  34.   border-color: black;
  35.   background-color: aquamarine;
  36.   text-align: center;
  37.   position: absolute;
  38. }
  39. /* 向下箭头 */
  40. .arrow-down {
  41.   width: 2px;
  42.   height: 80px;
  43.   background-color: black;
  44.   position: absolute;
  45. }
  46. .arrow-down span {
  47.   width: 0;
  48.   height: 0;
  49.   border-left: 5px solid transparent;
  50.   border-right: 5px solid transparent;
  51.   border-top: 10px solid black;
  52.   position: relative;
  53.   top:81px;left:-4px;
  54. }
  55. /* 折线箭头 */
  56. .arrow-horizontal-down {
  57.   width: 80px;
  58.   height: 2px;
  59.   background-color: black;
  60.   position: absolute;
  61. }
  62. .arrow-horizontal-down div{
  63.   width: 2px;
  64.   height: 125px;
  65.   left:80px;
  66.   background-color: black;
  67.   position: relative;
  68. }
  69. .arrow-horizontal-down span {
  70.   width: 0;
  71.   height: 0;
  72.   border-left: 5px solid transparent;
  73.   border-right: 5px solid transparent;
  74.   border-top: 10px solid black;
  75.   position: relative;
  76.   top:10px;left:76px;
  77. }
复制代码
js 代码 可以动态天生流程图
  1. // json 节点数据
  2. let data = [
  3.     {
  4.         "id": 0,
  5.         "name": "开始",
  6.         "type": "diamond",
  7.         "click": "alert('开始')",
  8.         "children": [
  9.             1
  10.         ]
  11.     },
  12.     {
  13.         "id": 1,
  14.         "name": "审批一",
  15.         "type": "rectangle",
  16.         "click": "alert('审批一')",
  17.         "children": [
  18.             2
  19.         ]
  20.     },
  21.     {
  22.         "id": 2,
  23.         "name": "审批二",
  24.         "type": "diamond",
  25.         "click": "alert('审批二')",
  26.         "children": [
  27.             3,
  28.             4
  29.         ]
  30.     },
  31.     {
  32.         "id": 3,
  33.         "name": "审批三",
  34.         "type": "rectangle",
  35.         "click": "alert('审批三')",
  36.         "children": []
  37.     },
  38.     {
  39.         "id": 4,
  40.         "name": "审批四",
  41.         "type": "rectangle",
  42.         "click": "alert('审批四')",
  43.         "children": []
  44.     }
  45. ]
  46. // 偏移数值
  47. let offsetNum = {
  48.     diamondTop :95,
  49.     diamondLeft :40,
  50.     rectangleTop :50,
  51.     rectangleLeft :40,
  52.     arrowTop :80,
  53.     arrowLeft :0,
  54.     brokenLineTop:135,
  55.     brokenLineLeft:80
  56. }
  57. // 开始创建
  58. function BeginDraw(){
  59.     CreateNode(data[0],100,100);
  60. }
  61. // 循环创建子节点
  62. function CreateChildNode(lastNode,lastTop,lastLeft){
  63.     // 一个子节点
  64.     if(lastNode.children.length > 0){
  65.         CreateVerticalArrow(lastNode,lastTop,lastLeft);
  66.     }
  67.     // 多个子节点
  68.     if(lastNode.children.length > 1){
  69.         let beginTop = GetOffsetTop(lastNode) / 2 + lastTop - 10;
  70.         let beginLeft = GetOffsetLeft(lastNode) * 2 + lastLeft + 15;
  71.         for (let c = 1;c < lastNode.children.length;c++) {
  72.             CreateBrokenArrow(beginTop,beginLeft,lastNode.children[c])
  73.         }
  74.     }
  75. }
  76. // 创建节点
  77. function CreateNode(node,top,left){
  78.     let div = document.createElement("div");
  79.     div.className = node.type;
  80.     div.style.top = top + "px";
  81.     div.style.left = left + "px";
  82.     let span = document.createElement("span");
  83.     span.innerText = node.name;
  84.     span.className = node.type + "-text";
  85.     div.appendChild(span);
  86.     div.onclick = function() {
  87.         // 使用eval执行方法
  88.         eval(node.click);
  89.     };
  90.     document.body.append(div);
  91.     CreateChildNode(node,top,left);
  92. }
  93. // 创建竖线箭头+节点
  94. function CreateVerticalArrow(lastNode,nodeTop,nodeLeft){
  95.     // 竖线箭头top
  96.     let arrowtop = GetOffsetTop(lastNode) + nodeTop;
  97.     // 竖线箭头left
  98.     let arrowleft = GetOffsetLeft(lastNode) + nodeLeft;
  99.     let div = document.createElement("div");
  100.     div.className = "arrow-down";
  101.     div.style.top = arrowtop + "px";
  102.     div.style.left = arrowleft + "px";
  103.     let span = document.createElement("span");
  104.     div.appendChild(span);
  105.     document.body.append(div);
  106.     for (let key in data) {
  107.         if(lastNode.children[0] == data[key].id){
  108.             // 新节点top
  109.             let newNodeTop = arrowtop + offsetNum.arrowTop;
  110.             if(data[key].type == "diamond"){
  111.                 newNodeTop = newNodeTop + 15;
  112.             }
  113.             CreateNode(data[key],newNodeTop,nodeLeft);
  114.         }
  115.     }
  116. }
  117. // 创建折线箭头+节点
  118. function CreateBrokenArrow(arrowTop,arrowLeft,childnum){
  119.     let div = document.createElement("div");
  120.     div.className = "arrow-horizontal-down";
  121.     div.style.top = arrowTop + "px";
  122.     div.style.left = arrowLeft + "px";
  123.     let ndiv = document.createElement("div");
  124.     let span = document.createElement("span");
  125.     div.appendChild(ndiv);
  126.     div.appendChild(span);
  127.     document.body.append(div);
  128.     for (let key in data) {
  129.         if(childnum == data[key].id){
  130.             // 新节点top
  131.             let newNodeTop = arrowTop + offsetNum.brokenLineTop;
  132.             // 新节点Left
  133.             let newNodeLeft = arrowLeft + offsetNum.brokenLineLeft - GetOffsetLeft(data[key]);
  134.             if(data[key].type == "diamond"){
  135.                 newNodeTop = newNodeTop + 15;
  136.             }
  137.             CreateNode(data[key],newNodeTop,newNodeLeft);
  138.         }
  139.     }
  140. }
  141. // 获取Top偏移量
  142. function GetOffsetTop(lastNode){
  143.     if(lastNode.type == "arrow"){
  144.         return offsetNum.arrowTop;
  145.     }
  146.     else if(lastNode.type == "diamond"){
  147.         return offsetNum.diamondTop;
  148.     }
  149.     else if(lastNode.type == "rectangle"){
  150.         return offsetNum.rectangleTop;
  151.     }
  152.     return 100;
  153. }
  154. // 获取Left偏移量
  155. function GetOffsetLeft(lastNode){
  156.     if(lastNode.type == "arrow"){
  157.         return offsetNum.arrowLeft;
  158.     }
  159.     else if(lastNode.type == "diamond"){
  160.         return offsetNum.diamondLeft;
  161.     }
  162.     else if(lastNode.type == "rectangle"){
  163.         return offsetNum.rectangleLeft;
  164.     }
  165.     return 0;
  166. }
复制代码
动态天生效果


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4