自定义横向思维导图,横向组织架构图,横向树图。可以自定义节点颜色,样式,还可以导出为图片

最近公司设计要求根据目录结构,横向展示。所以做了一个横向的思维导图,横向的树结构,横向的组织架构图,可以自定义节点颜色,样式,还可以导出为图片

话不多说,直接上图片,这个就是一个小例子
在这里插入图片描述子组件,直接上代码,子组件的线条颜色,可以自己设置变量从父组件传入,我这里没写。
isUnfold 表示是否有下级

<template>
  <div class="my-self-tree" ref="my-tree">
    <div class="info-card">
      <div class="card-item" v-for="(item, index) in data" :key="index">
        <div
          class="vertical-line"
          :style="computedHeight(item.height, data.length, index)"
          v-if="item.level !== 0"
        ></div>
        <div class="horizontal-line" v-if="item.level !== 0"></div>
        <div class="tree-node" :class="{'tree-node-1': item.level == 0&&item.isUnfold != 0}">
          <div
            class="tree-node-content"
            :class="[handlItem(item)]"
            @click="clickTreeNode(item)"
          >
            {{ item.name }}
          </div>
        </div>
        <div
          class="horizontal-line"
          v-if="item.childNode && item.childNode.length !== 0"
        ></div>
        <mytree
          @nodeClick="clickTreeNode"
          :data="item.childNode"
          v-if="item.childNode && item.childNode.length !== 0"
        ></mytree>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "mytree",
  props: {
    data: Array,
  },
  data() {
    return {};
  },
  methods: {
    computedHeight(pheight, length, index) {
      if (length == 1 || length == 0) {
        return {
          height: "0px",
          display: "none",
        };
      } else {
        let height = 0;
        let marginTop = 0;
        let marginB = 0;
        if (index == 0) {
          height = pheight / 2;
          marginTop = height;
          return {
            height: height + "px",
            "margin-top": marginTop + "px",
          };
        }
        if (index == length - 1) {
          height = pheight / 2;
          marginB = height;
          return {
            height: height + "px",
            "margin-bottom": marginB + "px",
          };
        } else {
          height = pheight;
          return {
            height: height + "px",
          };
        }
      }
    },
    clickTreeNode(item) {
      this.$emit("nodeClick", item);
    },
    handlItem(item) {
      if (item.level == 0) {
        return 'has-background'
      }else {
        if (item.isUnfold == 1) {//中间节点
          let flag = this.hasZeroCountNode(item.childNode);
          console.log(flag, 'flag')
          if (item.level == 1) {
            return flag ? 'font-color-black border-black' : 'font-color-green border-green';
          } else {
            return flag ? 'font-color-black' : 'font-color-green';
          }
        } else if (item.isUnfold == 0) {//最后一个节点
          if (item.level == 1) {
            return item.count == 0 ? 'font-color-red border-red' : 'font-color-green border-green'
          } else {
            return item.count == 0 ? 'font-color-red' : 'font-color-green'
          }
        }
      }
    },
    hasZeroCountNode(nodes) {
      //不含当前节点的count判断,判断所有子节点
      for (let node of nodes) {
        if (node.count === 0) {
          return true;
        }
        if (node.childNode && this.hasZeroCountNode(node.childNode)) {
          return true;
        }
      }
      return false;
      //含当前节点的count判断
      // if (node.count === 0) {
      //   return true; // 如果找到节点的count为0,立即返回true
      // }
      // if (node.childNode && node.childNode.length > 0) {
      //   // 如果节点有子节点,则递归检查子节点
      //   return node.childNode.some(child => this.hasZeroCountNode(child));
      // }
      // return false; // 如果节点和其子节点都不满足条件,返回false
    }
  },
  components: {},
  mounted() {},
};
</script>

<style lang="scss" scoped>
:root .my-self-tree {
  // height: 100%;
  // width: 100%;
  .vertical-line {
    position: relative;
    // display: inline-block;
    width: 0.5px;
    background: #009694;
    transform:scale(2, 1);
  }
  .card-item {
    margin:0;padding:0;
    display: flex;
    align-items: center;
    .horizontal-line {
      min-width: 30px !important;
      //   display: inline-block;
      height: 0.5px;
      background: #009694;
      transform:scale(1 , 2);
      position: relative;
    }
    .horizontal-line::before {
      content:'';
      position:absolute;
      height: 1px;
      width:2px;
      right:-1px;
      background: #009694;
    }
    .horizontal-line::after {
      content:'';
      position:absolute;
      height: 1px;
      width:2px;
      left:-1px;
      background: #009694;
    }
  }
  .tree-node {
    cursor: pointer;
    height: 30px;
    position: relative;
    &:nth-child(1)::after {
      display: none;
    }
    // &:nth-child(1)::before {
    //   position: absolute;
    //   content: "";
    //   width: 8px;
    //   display: inline-block;
    //   height: 8px;
    //   border-radius: 4px;
    //   top: 50%;
    //   right: -4px;
    //   transform: translateY(-50%);
    //   background: #009694;
    // }
    .tree-node-content {
      display: flex;
      position: relative;
      justify-content: center;
      align-items: center;
      width: auto;
      height: 100%;
      border: none;
      border-radius: 4px;
      color: #000;
      white-space: nowrap !important;
      padding: 0 10px;
    }
    .has-background {
      color: white;
      background: #009694;
    }
    .border-green {
      border: 1px solid #009694;
    }
    .border-black {
      border: 1px solid #000;
    }
    .border-red {
      border: 1px solid #FF6767;
    }
    .font-color-green {
      color: #009694;
    }
    .font-color-black {
      color: #000;
    }
    .font-color-red {
      color: #FF6767;
    }
  }
  .tree-node::after {
    position: absolute;
    content: "";
    width: 8px;
    display: inline-block;
    height: 8px;
    border-radius: 4px;
    top: 50%;
    left: -4px;
    transform: translateY(-50%);
    background: #009694;
  }
  .tree-node-1::before {
      position: absolute;
      content: "";
      width: 8px;
      display: inline-block;
      height: 8px;
      border-radius: 4px;
      top: 50%;
      right: -4px;
      transform: translateY(-50%);
      background: #009694;
    }
}
</style>

这里是父组件

<el-popconfirm
          placement="top-end"
          title="是否需要导出为图片?"
          @confirm="exportFn"
          >
          <el-button
            slot="reference"
            style="margin-left: 10px"
            type="primary"
            class="fliter-btn icons-btn"
            size="mini"
            ><i class="qhFileManage icon-daochu" style="font-size: 14px;"></i> 导出
          </el-button>
          </el-popconfirm>
<tree :data="dataInfo" @nodeClick="nodeClick" id="mytree" style="height: 100%;"></tree>

//处理数据
//temporaryData 为实际获取的数据 ,temporaryData1 是做例子写的数据
    handleData(temporaryData) {
      //自行调试测试数据,后面换成正式数据
      let temporaryData1 = [
        {
          id: 1,
          level: 0,
          name: "部门名称啊",
          childNode: [
            {
              id: 11,
              level: 1,
              name: "自己测试数据",
              isUnfold: 1,
              childNode: [
                {
                  id: 1111111,
                  level: 2,
                  name: "所有下级节点count>0",
                  isUnfold: 1,
                  childNode: [
                    {
                      id: 1111111,
                      level: 3,
                      name: "2ge",
                      count: 2,
                      isUnfold: 0,
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: 1,
                      isUnfold: 1,
                      childNode: [
                        {
                          id: 1111111,
                          level: 4,
                          name: "2",
                          isUnfold: 1,
                          childNode: [
                            {
                              id: 1111111,
                              level: 4,
                              name: "1ge",
                              count: 1,
                              isUnfold: 0,
                            },
                          ],
                        },
                      ],
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: "2ge",
                      count: 2,
                      isUnfold: 0,
                    },
                  ],
                },
                {
                  id: 1111111,
                  level: 2,
                  name: "所有下级节点count=0",
                  isUnfold: 1,
                  childNode: [
                    {
                      id: 1111111,
                      level: 3,
                      name: "0ge",
                      count: 0,
                      isUnfold: 0,
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: 1,
                      isUnfold: 1,
                      childNode: [
                        {
                          id: 1111111,
                          level: 4,
                          name: "0ge",
                          count: 0,
                          isUnfold: 0,
                        },
                      ],
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: "0ge",
                      count: 0,
                      isUnfold: 0,
                    },
                  ],
                },
                {
                  id: 1111111,
                  level: 2,
                  name: "所有下级节点存count=0,>0",
                  isUnfold: 1,
                  childNode: [
                    {
                      id: 1111111,
                      level: 3,
                      name: "0ge",
                      count: 0,
                      isUnfold: 0,
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: 1,
                      isUnfold: 1,
                      childNode: [
                        {
                          id: 1111111,
                          level: 4,
                          name: "1ge",
                          count: 1,
                          isUnfold: 0,
                        },
                      ],
                    },
                    {
                      id: 1111111,
                      level: 3,
                      name: "1ge",
                      count: 1,
                      isUnfold: 0,
                    },
                  ],
                },
              ],
            },
          ],
          isUnfold: 1,
        },
      ];
      let fixedData = temporaryData.map((item) => {
        return this.traveTree(item);
      });
      console.log(fixedData, "fixedData");
      this.dataInfo = fixedData;
    },
// traveTree这里是给每个节点设置高度,
    traveTree(nodeInfo) {
      let childrenInfo = nodeInfo.childNode;
      if (!childrenInfo || childrenInfo.length == 0) {
        nodeInfo.height = 40;
      } else {
        childrenInfo.map((item) => {
          this.traveTree(item);
        });

        nodeInfo.height = childrenInfo.reduce((preV, n) => {
          return preV + n.height;
        }, 0);
      }
      return nodeInfo;
    },

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/634514.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nssctf(Web刷题)

[SWPUCTF 2021 新生赛]gift_F12 打开题目是一个时间页面&#xff0c;不过看了一会儿发现没有什么用 直接F12打开网页源代码 CtrlF搜索flag 找到了flag NSSCTF{We1c0me_t0_WLLMCTF_Th1s_1s_th3_G1ft} [第五空间 2021]签到题 NSSCTF{welcometo5space} [SWPUCTF 2021 新生赛…

cPanel中如何为数据库添加用户权限

本周有一个客户&#xff0c;购买Hostease的主机&#xff0c;询问我们的在线客服&#xff0c;他的网站安装后再还是无法访问。 客户购买的是Linux虚拟主机&#xff0c;带cPanel面板的。网站访问有如下数据库连接错误: 随后检查发现客户创建的数据库没有添加数据库用户权限。 下面…

期权策略交易怎么做?怎么选择期权策略?

今天期权懂带你了解期权策略交易怎么做&#xff1f;怎么选择期权策略&#xff1f;期权交易是一种金融衍生品交易方式&#xff0c;它给予购买者在未来特定时间内以特定价格购买&#xff08;或出售&#xff09;标的资产的权利。 期权策略交易怎么做&#xff1f; 配对看跌期权&am…

基于地理坐标的高阶几何编辑工具算法(3)——相离面吸附

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理 工具步骤 点击面&#xff0c;点击“相离面吸附”工具&#xff0c;绘制一个面&#xff0c;双击结束后&#xff0c;与所有相交的面进行吸附 应用场景 为了让相离的两个几何面在空间上相邻&#xff0c;使用该工具…

llama_factory的使用

1.git clone llama_factory到本地 2.记得安环境&#xff0c;在clone后 3.多显卡要设置一下 4.数据文件放在data里面&#xff0c;仿照模板里的格式 5.进入llama_factory微调页面 python src/webui.py 6.llama_factory介绍&#xff1a;10分钟打造你个人专属的语言大模型&am…

离散数学--图论

目录 1.简单概念 2.握手定理 3.点割集 4.边割集 5.点连通度和边连通度 6.Dijstra算法&&最短路径 7.有向图的连通性 8.图的矩阵表示 9.欧拉图问题 10.哈密尔顿图 1.简单概念 &#xff08;1&#xff09;这个里面的完全图比较重要&#xff0c;完全图是例如k3,k5这…

GPT-SoVITS语音克隆部署与使用

GPT-SoVITS是一款强大的少量样本语音转换与语音合成开源工具。当前&#xff0c;GPT-SoVITS实现了如下几个方面的功能&#xff1a; 由参考音频的情感、音色、语速控制合成音频的情感、音色、语速可以少量语音微调训练&#xff0c;也可不训练直接推理可以跨语种生成&#xff0c;…

00-Vue的介绍和vue-cli

前言Vue的介绍和vue-cli一、发展历史相关网址介绍Vue框架的特点 二、Vue 的环境搭建1&#xff0c;卸载掉所有已经存在的所有Node.js版本2&#xff0c;下载MVM包4、安装node.js5、常见的插件 三、利用 vue-cli 新建一个空的项目1、官方代码参考2、安装 vue-cli&#xff08;命令行…

【C++】学习笔记——map和set

文章目录 十五、map和set1. 关联式容器2. set的介绍3. set的使用4. multiset5. map的介绍6. map的使用7. multimap8. map中重载的operator[] 未完待续 十五、map和set 1. 关联式容器 我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector 、list 、deque 等&…

04. Redis 配置文件

文章目录 单位包含网络 NETWORK通用 GENERAL快照 SNAPSHOTTING主从复制 REPLICATION安全 SECURITY客户端 CLIENTS内存设置 MEMORY MANAGEMENTAPPEND ONLY MODE 模式&#xff08;aof 的配置&#xff09; 单位 配置文件对大小写不敏感&#xff08;unit单位&#xff09;。 包含 …

通过域名接口申请免费的ssl多域名证书

来此加密已顺利接入阿里云的域名接口&#xff0c;用户只需一键调用&#xff0c;便可轻松完成域名验证&#xff0c;从而更高效地申请证书。接下来&#xff0c;让我们详细解读一下整个操作过程。 来此加密官网 免费申请SSL证书 免费SSL多域名证书&#xff0c;泛域名证书。 首先&a…

K8S认证|CKA题库+答案| 2. 查看Pod CPU资源使用量

2、查看集群中运行Pod CPU资源使用量 您必须在以下Cluster/Node上完成此考题&#xff1a; Cluster Master node Worker node k8s …

『Apisix安全篇』快速掌握APISIX Basic-Auth插件高效使用

&#x1f4e3;读完这篇文章里你能收获到 &#x1f468;‍&#x1f4bb; 学习如何快速安装并配置APISIX Basic-Auth插件&#xff0c;为您的API安全保驾护航。&#x1f6e0;️ 文章详细介绍了如何创建带有basic-auth配置的Consumer&#xff0c;以及如何在Route中启用该插件。&am…

爱校对:智能校对,让文字更专业

交互未来&#xff08;北京&#xff09;科技有限公司&#xff0c;源自清华大学计算机智能人机交互实验室&#xff0c;致力于通过高科技手段提升用户体验&#xff0c;实现“科技让生活更美好”的宗旨。我们的产品——爱校对&#xff0c;正是这种创新精神的结晶&#xff0c;旨在为…

怎样策划一场价值百万的营销活动?

策划一场活动听起来是不是就有点头大&#xff1f; 别急&#xff0c;其实只要掌握了活动策划的精髓&#xff0c;一步步来&#xff0c;从构思到实施&#xff0c;整个过程都能游刃有余。 一、定下目标&#xff1a; 咱们先得搞清楚&#xff0c;这场活动到底是为了啥。是想提升品…

代码随想录-Day17

110. 平衡二叉树 这道题中的平衡二叉树的定义是&#xff1a;二叉树的每个节点的左右子树的高度差的绝对值不超过 111&#xff0c;则二叉树是平衡二叉树。根据定义&#xff0c;一棵二叉树是平衡二叉树&#xff0c;当且仅当其所有子树也都是平衡二叉树&#xff0c;因此可以使用递…

四天学会JS高阶(学好vue的关键)——构造函数数据常用函数(理论+实战)(第二天)

一、对象创建引发构造函数产生 1.1 创建对象三种方式&#xff1a; 利用对象字面量创建对象 const obj {name: 佩奇}注&#xff1a;对象字面量的由来&#xff1a;即它是直接由字面形式&#xff08;由源代码直接&#xff09;创建出来的对象&#xff0c;而不是通过构造函数或者…

开箱测评!吸猫毛除味神器,希喂FreAir Lite宠物空气净化器实测

掉毛季又来了&#xff0c;猫咪的毛发满天飞&#xff0c;怎么办&#xff1f;我家掉毛怪一到季节就开始掉老多毛&#xff0c;关键还喜欢在家里打架跑酷&#xff01;天上地下都是毛&#xff01;为了减少家里空气中浮毛&#xff0c;你做过那些努力呢&#xff1f;最近猫掉毛掉的&…

设置height:100%不生效的原因

之前网课案例总是不屑于去看&#xff0c;因为总觉得太花时间&#xff0c;但是不可否认的是&#xff0c;认真去看还是会有收获的&#xff0c;而且常有意外收获 昨天在看实现动画效果的综合案例中&#xff0c;意外解决了我长久以来的一个疑问&#xff1a;为什么给元素设置height…

论文精读--InstructGPT

模型效果取决于数据效果&#xff0c;但在精细度上控制不够&#xff0c;只是大力出奇迹&#xff0c;这样有很大的问题&#xff1a; &#xff08;1&#xff09;数据量太多或者没有这方面的数据&#xff0c;模型学不会怎么办 &#xff08;2&#xff09;安全性问题&#xff0c;模…