[VUE2]基于vue-workflow-chart的DEG图组件

2022年7月18日 336点热度 0人点赞 0条评论

[VUE2]基于vue-workflow-chart的DEG图组件

vue-workflow-chart调用

 <workflow-chart
      :style='size'
      :transitions='transitions'
      :states='states'
      :stateSemantics='stateSemantics'
      :orientation="isHorizontal ? 'horizontal' : 'vertical'"
      @state-click="onStateClick($event)"
      @transition-click="onLabelClicked('transition', $event)"
      @sizeChange='sizeChanged'
    />

官方demo

Image

<template>
    <div id="app">
        <workflow-chart
            :transitions="transitions"
            :states="states" />

    </div>
</template>

<script>
import WorkflowChart from 'vue-workflow-chart';

export default {
    name"App",
    components: {
        WorkflowChart,
    },
    data() => ({
        states: [{
            "id""state_1",
            "label""State 1",
        }, {
            "id""state_2",
            "label""State 2",
        }],
        transitions: [{
            "id""transition_1",
            "label""this is a transition",
            "target""state_2",
            "source""state_1",
        }],
    }),
};
</script>

自定义组件效果

主要是重写了一下样式,自定义每个节点里的图片,达到workflow DEG图的效果。Image

自定义组件调用

<Workflow :nodeData='nodeData' :isHorizontal='isHorizontal' @clickNode='clickNode' v-dragScroll />

自定义组件代码

<template>
  <div class='hzs-workflow-chart-box' ref='box'>
    <workflow-chart
      :style='size'
      :transitions='transitions'
      :states='states'
      :stateSemantics='stateSemantics'
      :orientation="isHorizontal ? 'horizontal' : 'vertical'"
      @state-click="onStateClick($event)"
      @transition-click="onLabelClicked('transition', $event)"
      @sizeChange='sizeChanged'
    />

  </div>
</template>
<script>
import WorkflowChart from 'vue-workflow-chart'

const phaseToClass = {
  Succeeded'succeeded',
  Running'running',
  Pending'pending',
  Omitted'omitted',
  Failed'failed'
}

export default {
  name'Workflow',
  components: {
    WorkflowChart
  },
  props: {
    nodeData: {
      typeObject,
      default() => ({})
    },

    isHorizontal: {
      typeBoolean,
      defaultfalse
    }
  },
  watch: {
    nodeData: {
      handlerfunction(newVal{
        console.log('检测到有新的节点数据')
        console.log(newVal)
        this.composeChartData(newVal.status.nodes)
        setTimeout(this.dealWordPosition)
      },
      deeptrue
    }
  },
  data() => ({
    states: [],
    transitions: [],
    stateSemantics: [],
    size: { width'0px'height'0px' }

  }),

  methods: {
    onStateClick(e) {
      console.log('点击了节点')
      console.log(e)
      this.$emit('clickNode', e)
    },
    addData() {
      for (let i = 0; i < 100; i++) {
        this.states.push({
          id`node${i}`,
          label`node${i}`
        })
      }
      for (let i = 0; i < 50; i++) {
        this.transitions.push({

          'label''',
          'source'`node${i}`,
          'target'`node${i + 1}`
        })
      }

      for (let i = 50; i < 100; i++) {
        this.transitions.push({
          'label''',
          'source'`node${i - 50}`,
          'target'`node${i}`
        })
      }

    },
    sizeChanged(size) {
      this.size = {
        width`${size.width}px`,
        height`${size.height}px`
      }
    },

    // 组装成图的数据
    composeChartData(dataObj) {
      if (!dataObj || JSON.stringify(dataObj) === '{}' || dataObj.length < 1) {
        return
      }
      let nodeList = []
      let lineList = []
      let stateSemanticList = []

      Object.keys(dataObj).forEach((key) => {
        let node = dataObj[key]
        console.log(node)

        // 放入节点
        nodeList.push({
          'id': node.id,
          'label': node.displayName
        })

        // 放入节点状态信息
        stateSemanticList.push({
          'id': node.id,
          'classname': phaseToClass[node.phase]
        })

        // 放入连线的情况
        if (node.children && node.children.length > 0) {
          node.children.forEach((child, index) => {
            lineList.push({
              'id'`${node.id}-${index}`,
              'target': child,
              'source': node.id
            })
          })

        }
      })

      console.log('组装出来的数据')
      console.log(nodeList)
      console.log(lineList)

      this.states = nodeList
      this.transitions = lineList
      this.stateSemantics = stateSemanticList
    },


    getMaxHeight() {
      let maxHeight = 0
      let nodeList = document.getElementsByClassName('vue-workflow-chart-state')

      for (let i = 0; i < nodeList.length; i++) {
        if (nodeList[i].style.top) {
          let top = +nodeList[i].style.top.split('px')[0]
          if (top > maxHeight) {
            maxHeight = top
          }
        }
      }

      console.log(this.$refs.box)
    },


    // 调整文字位置
    dealWordPosition() {
      let nodeList = document.getElementsByClassName('vue-workflow-chart-state')

      for (let i = 0; i < nodeList.length; i++) {
        // console.log(nodeList[i])
        let label = nodeList[i].innerText

        let element = document.createElement('p')
        element.innerText = label
        element.className = 'vue-workflow-chart-state-text'

        nodeList[i].innerText = ''
        nodeList[i].appendChild(element)

      }
    },


    onLabelClicked(type, id) {
      console.log('点击了节点')
      alert(`Clicked on ${type} with id: ${id}`)
    }
  },

  created() {
    // this.addData()
    // this.composeChartData(this.nodeData.status.nodes)
  },
  mounted() {
    //
    // this.getMaxHeight()
  }
}
</script>
<style lang='less'>
@import '~vue-workflow-chart/dist/vue-workflow-chart.css';

.hzs-workflow-chart-box {
  min-height: 800px;
  //border: 1px solid black;
  overflow: auto;
  //margin-left: 50px;
  position: relative;


  .vue-workflow-chart-state {
    padding: 0;
    margin: 0;
    z-index: 999;
    //border: 2px solid black;
    border-radius: 50%;
    width: 60px;
    height: 60px;

    overflow: visible;
    color: black;
    font-size: 8px;
    //background-color: white;
    //position: relative;
    //font-weight: 500;
    //flex-wrap: nowrap;

    //display: flex;
    //justify-content: flex-end;
    //background-image: url("/img/success.svg");
    background-position: center;
    background-origin: content-box;
    background-attachment: local;
    background-size: 100%;
    //background-size: cover;
    background-repeat: no-repeat;

    p {
      position: absolute;
      left: 30px;
      top: 55px;
      width: 150px;
      transform: translate(-50%);
    }
  }

  .vue-workflow-chart-state-delete {
    color: white;
    background: red;
  }


  .vue-workflow-chart-state-succeeded {
    //color: white;
    //background: green;
    //background: #00FF00 url("/img/success.svg") no-repeat fixed top;
    //background-image: url("/img/success.svg");
    background-image: url("/img/success.svg");

  }

  .vue-workflow-chart-state-running {
    background-image: url("/img/loading.gif");

  }

  .vue-workflow-chart-state-pending {
    background-image: url("/img/wait.svg");
    //background-size: cover;
    //background: gray;
  }

  .vue-workflow-chart-state-omitted {
    background-image: url("/img/ignore.svg");
    //background-size: cover;
  }

  .vue-workflow-chart-state-failed {
    background-image: url("/img/fail.svg");
    //background-size: cover;
  }


  .vue-workflow-chart-transition-arrow-delete {
    fill: red;
  }

  .vue-workflow-chart-transition-path-delete {
    stroke: red;
  }
}

</style>

52570[VUE2]基于vue-workflow-chart的DEG图组件

这个人很懒,什么都没留下

文章评论