vue画树状图和有向图

(记录专用)

树状图

vue根据树状结构生成流程图_vue 树结构流程图_正兒八经DI瞎练ぃ的博客-优快云博客

组件代码:

<template>
  <div class="processBox" v-if="list.length">
    <div class="childs">
      <div class="child" v-for="(item,index) in list" :key="item.id +'-child-'+index">
        <div class="child-item" :style="{marginRight: item.children && item.children.length > 1 ? '20px' :''}">
          <div class="childname" :id="item.id">
            <div class="shows"
			:class="{ highlighted: item.isfinished }">
              <slot :items="item">
                {{item.name}}
              </slot>
            </div>
            <div class="position-arrow" v-if="list.length > 1">
              <i class="el-icon-right"></i>
            </div>
            <div class="position-top" v-if="isFirst(item.id) && domready" :style="position_top(item.id,'top')"></div>
            <div class="position-top" v-if="isLast(item.id)" :style="position_top(item.id,'bottom')"></div>
          </div>
          <div class="childarrow" :style="{borderRight:item.children && item.children.length >1 ? '2px solid #606266' : '3px solid transparent'}">
            <div :class="item.children && item.children.length<=1?'long-img':''"></div>
              <i class="el-icon-right" v-if="item.children && item.children.length" ></i>

          </div>
        </div>
        <div class="child-children" v-if="item.children && item.children.length">
          <processJson :list="item.children" >
            <template v-slot="item">
              <slot :items='item.items' />
            </template>

          </processJson>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "processJson",
  components: {},
  data() {
    return {
      domready: false,
    };
  },
  props: {
    list: {
      type: Array,
      default: () => [],
    },
  },

  mounted() {
    this.$nextTick(() => {
      this.domready = true;
    });
  },
  methods: {
    position_top(id, position) {
      let dom = document.getElementById(id);
      let height;
      if (dom) {
        height = dom.clientHeight;
      }
      let rt;
      if (position === "top") {
        rt = {
          height: height / 2 - 2 + "px",
          top: 0,
        };
      }
      if (position === "bottom") {
        rt = {
          height: height / 2 + 1 + "px",
          bottom: 0,
        };
      }
      return rt;
    },

    isFirst(id) {
      return (
        this.list.length > 1 && this.list.map((x) => x.id).indexOf(id) === 0
      );
    },

    isLast(id) {
      return (
        this.list.length > 1 &&
        this.list.map((x) => x.id).indexOf(id) === this.list.length - 1
      );
    },
  },
};
</script>

<style lang="scss" scoped>
.el-icon-right{
  font-weight: 600;
}
.processBox {
  p {
    margin: 0;
    font-size: 13px;
  }
  display: flex;
  .father {
    width: 70px;
    background-color: red;
    padding: 100px 10px;
  }
  .childs {
    .child {
      display: flex;
      background-color: #fff;
      .child-item {
        display: flex;
        align-items: center;
        margin: 10px 0;
        .childname {
			.shows {
				text-align: center;
				border: 1px solid #b4b4b4;
				padding: 10px;
				width: 150px;
				font-size: 25px;
				background-color: #409EFF !important;  /* 设置背景色为蓝色 */
				color: white;  /* 设置文本颜色为白色 */
				display: flex;  /* 使用flexbox */
				justify-content: center;  /* 文本水平居中 */
				align-items: center;  /* 文本垂直居中 */
				box-shadow: 1px 2px 8px #00000033;
				&:hover{
					box-shadow: 1px 2px 8px #00000066;
				}
				&.highlighted {
				  background-color: #67C23A !important; // 设置背景颜色为红色
				  color: white !important; // 设置文本颜色为白色
			    }
			}
          cursor: pointer;
          height: 100%;
          display: flex;
          align-items: center;
          text-align: center;
          justify-content: center;
          position: relative;
          padding: 10px 0;
          .position-arrow {
            position: absolute;
            // top: 50%;
            left: -22px;
          }
          .position-top {
            position: absolute;
            width: 3px;
            background-color: #fff;
            left: -23px;
            height: 10px;
          }
        }
        .childarrow {
          height: 100%;
          // border-right: ;
          display: flex;
          align-items: center;
        }
      }
    }
    .child-children {
      display: flex;
      flex-direction: column;
      justify-content: center;
    }
  }
  .long-img{
    width: 20px;
    height: 2px;
    background-color: #606266;
  }
  .icon_arrow {
    // margin-left: 20px;
    &:after {
      width: 30px;
      height: 1px;
      background-color: #000;
    }
  }
}
</style>

调用组件代码

<template>
	<div>
		<josnToProcess :list="list">
		    <template #default="{ items }">
		        <div class="node_item ">
		              {{items.unitName }}
		        </div>
		    </template>
		 </josnToProcess>
	</div>
</template>

有向图

Vue中使用dagre-d3绘制流程图实用指南_vue流程图插件_sleepwalker_1992的博客-优快云博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值