svg技术绘制血缘关系

该项目旨在根据后端接口返回的数据,自定义绘制一层作业血缘关系图。通过计算节点位置和文本宽度,利用SVG的path标签来实现图形绘制。提供了初步的预览和代码实现。
摘要由CSDN通过智能技术生成
  • 说明
    项目中需要绘制作业血缘图,网上调研了下也没有找到合适的轮子,于是就自己撸了,这里只有一层依赖关系,及父与子作业。
  • 思路
    根据后端返回的接口数据,计算每个节点的位置坐标,根据节点文本内容计算每个节点的宽度,高度固定。得到这些位置信息后,借用svg的path标签绘制出本依赖关系图。
  • 预览 在这里插入图片描述
  • 实现(代码写得比较粗糙,需要整体,这里贴个初版)

接口返回的数据结构如下:
在这里插入图片描述
代码实现:

// dag.js
const SVG_NS = 'http://www.w3.org/2000/svg'
export const getTextWidth = text => {
   
  let svg = document.createElementNS(SVG_NS, 'svg')
  let oText = document.createElementNS(SVG_NS, 'text')
  oText.innerHTML = text
  svg.appendChild(oText)
  document.body.appendChild(svg)
  let width = oText.getBBox().width
  document.body.removeChild(svg)
  return width + 10
}

// 创建tag标签
export const createTag = (tag, attrObjs) => {
   
  let tagEle = document.createElementNS(SVG_NS, tag)
  for (let key in attrObjs) {
   
    tagEle.setAttribute(key, attrObjs[key])
  }
  return tagEle
}

// node类
class DagNode {
   
  constructor (job = {
   }, options = {
   }, containerId) {
   
    this.prev = []
    this.next = []
    this.job = job
    this.width = Math.max(getTextWidth(job.jobName || job.jobId), 100)
    this.height = 40
    this.offsetX = options.offsetX || 0
    this.offsetY = options.offsetY || 0
    this.containerId = containerId || 'bloodChart'
  }
  // 绘制node
  drawNode () {
   
    let oG = createTag('g')
    let oRect = createTag('rect', {
   
      x: this.offsetX,
      y: this.offsetY,
      rx: 5,
      ry: 5,
      width: this.width,
      height: this.height,
      style: 'cursor: pointer; fill: transparent; stroke-width: 2; stroke: #303030'
    })
    let oText = createTag('text', {
   
      x: this.offsetX + 10,
      y: this.offsetY + 15,
      style: `cursor: pointer; fill: #303030`,
      'data-node': JSON.stringify(this.job)
    })

    let tSpan = createTag('tspan', {
   
      x: this.offsetX + 10,
      y: this.offsetY + 15,
      style: `cursor: pointer; fill: #303030`,
      'data-node': JSON.stringify(this.job)
    })
    tSpan.innerHTML = `${
     this.job.jobName || this.job.jobId}`

    let tSpan2 = createTag('tspan', {
   
      x: this.offsetX + 10,
      y: this.offsetY + 35,
      style: `cursor: pointer; font-size: 12px; fill: #303030`,
      'data-node': JSON.stringify(this.job)
    })
    tSpan2.innerHTML = `${
     this.job.jobTypeCn} / 
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值