基于leafer-ui 实现简单流程图

1.实现:流程步骤使用dom元素,连接线使用leaf画出  实现如下

1.提供对应流程步骤元素 并设置样式

 <div ref="xxxRef" id="xxx" style="width: 500px; height: 500px">
    <div flowId="a" flowTo="b,c" class="flow" style="top: 50px; left: 180px; background-color: #0bdb96">订单审批</div>
    <div flowId="b" flowTo="d" class="flow" style="top: 210px; left: 50px; background-color: #f1f1f1">大额审批</div>
    <div flowId="c" flowTo="d" class="flow" style="top: 210px; left: 300px; background-color: #00bffff2">小额审批</div>
    <div flowId="d" class="flow" style="top: 400px; left: 180px; background-color: #00bffff2">最终确认</div>
  </div>



<style>
  .flow {
    position: absolute;
    width: 100px;
    height: 30px;
    line-height: 30px;
    border: 1px solid #ccc;
    border-radius: 5px;
    text-align: center;
    font-size: 14px;
    padding: 10px;
    z-index: 99;
  }
  #xxx {
    position: relative;
    border: 1px solid #ccc;
  }

</style>

 使用leaf  根据定位得到路径  最后画出路径

import { Leafer } from "leafer-draw"
import { Arrow } from "@leafer-in/arrow"
interface flowObjT {
  points: pointsT
  to: string
  id: string
  x: number
  y: number
  width: number
  height: number
  stroke?: string
  strokeWidth?: string
}
interface pointsT {
  top: { x: number; y: number }
  left: { x: number; y: number }
  right: { x: number; y: number }
  bottom: { x: number; y: number }
}
export function createFlow(ele: HTMLElement, drection: "row" | "col" = "col") {
  if (!ele) {
    throw new Error("please provide an element")
  }
  const LF = new Leafer({
    view: ele, // 支持 window 、div、canvas 标签对象, 可使用id字符串(不用加 # 号)
    // type: "draw",
    // wheel: { zoomMode: false },
    move: {
      disabled: true,
    },
  })

  const eles = ele.querySelectorAll(".flow") as unknown as HTMLElement[]
  const flowDict: { [property: string]: flowObjT } = {}
  for (let i = 0; i < eles.length; i++) {
    let x: number = eles[i].offsetLeft
    let y: number = eles[i].offsetTop
    let width: number = eles[i].offsetWidth
    let height: number = eles[i].offsetHeight

    flowDict[eles[i].getAttribute("flowId") || i.toString()] = {
      id: eles[i].getAttribute("flowId") || i.toString(),
      to: eles[i].getAttribute("flowTo") || "",
      x,
      y,
      points: {
        top: { x: x + width / 2, y: y },
        right: { x: x + width, y: y + height / 2 },
        bottom: { x: x + width / 2, y: y + height },
        left: { x: x, y: y + height / 2 },
      },
      width,
      height,
      stroke: eles[i].getAttribute("flowColor") || ele.getAttribute("flowColor") || "green",
      strokeWidth: eles[i].getAttribute("flowWidth") || ele.getAttribute("flowWidth") || "5",
    }
  }
  const pathsList: { id: string; paths: number[] }[] = []
  for (let x in flowDict) {
    if (flowDict[x].to) {
      for (let y in flowDict) {
        if (flowDict[x].to.includes(y)) {
          let begin = drection == "col" ? flowDict[x].points.bottom : flowDict[x].points.right
          let end = drection == "col" ? flowDict[y].points.top : flowDict[y].points.left
          if (begin.x == end.x || begin.y == end.y) {
            pathsList.push({ id: x, paths: [begin.x, begin.y, end.x, end.y] })
          } else {
            if (drection == "col") {
              let a = { x: begin.x, y: begin.y + (end.y - begin.y) / 2 }
              let b = { x: begin.x + (end.x - begin.x), y: begin.y + (end.y - begin.y) / 2 }
              pathsList.push({ id: x, paths: [begin.x, begin.y, a.x, a.y, b.x, b.y, end.x, end.y] })
            } else {
              let a = { x: begin.x + (end.x - begin.x) / 2, y: begin.y }
              let b = { x: begin.x + (end.x - begin.x) / 2, y: begin.y + (end.y - begin.y) }
              pathsList.push({ id: x, paths: [begin.x, begin.y, a.x, a.y, b.x, b.y, end.x, end.y] })
            }
          }
        }
      }
    }
  }
  pathsList.forEach((x) => {
    LF.add(
      new Arrow({
        points: x.paths,
        endArrow: "arrow",
        cornerRadius: flowDict[x.id].strokeWidth,
        stroke: flowDict[x.id].stroke,
        strokeWidth: flowDict[x.id].strokeWidth,
      })
    )
  })
  return (paths: number[]) => {
    LF.add(new Arrow({ points: paths, endArrow: "arrow", cornerRadius: 5, strokeWidth: 3, stroke: "rgb(50,205,121)" }))
  }
}

元素可绑定width,color属性定义路径颜色,方法返回一个函数   可以用于自定义路径  可以实现复杂路径

效果如下:

仅提供思路,没啥难度 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值