【sgTopo】强哥古法炮制、纯手工打造简单拓扑图、流程图、思维导图组件(完善中ing)(一)

简介: 【sgTopo】强哥古法炮制、纯手工打造简单拓扑图、流程图、思维导图组件(完善中ing)

疯狂撸码中ing

实现组件效果

src/components/sgTopo.vue

<template>
  <!-- 强哥的拓扑图2021.09.14 -->
  <div
    class="sg-topo tree-body"
    v-if="data"
    :arrow-right="data.body.arrowRight"
    :style="data.body.style || {}"
  >
    <div
      class="topo-title main-node"
      :active="data.body.title.active"
      :style="data.body.title.style || {}"
    >
      {{ data.body.title.text }}
    </div>
    <ul
      class="topo-container"
      :style="data.body.container ? data.body.container.style || {} : {}"
    >
      <li class="tree-level" v-for="(a, $i) in data.body.data" :key="$i">
        <!-- 拓扑图类型:1 ------------------------------------------>
        <div v-if="a.type == 1" :type="a.type">
          <span
            :active="a.title.active"
            :style="a.title.style || {}"
            class="node-title"
            >{{ a.title.text }}</span
          >
          <!-- 二级树 -->
          <div v-if="a.children" class="topo-childrens">
            <div
              class="tree-body"
              gray
              v-for="(child, $i) in a.children"
              :key="$i"
            >
              <div class="tree-level">
                <span
                  :active="child.title.active"
                  :style="child.title.style || {}"
                  class="topo-title"
                  gray
                  >{{ child.title.text }}</span
                >
                <ul class="topo-container">
                  <!-- 三级节点 -->
                  <li
                    :active="childNode.title.active"
                    :style="childNode.title.style || {}"
                    v-for="(childNode, $i) in child.data"
                    :key="$i"
                    class="node-title"
                    border
                  >
                    {{ childNode.title.text }}
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
        <!-- 拓扑图类型:2 ------------------------------------------>
        <div v-if="a.type == 2" :type="a.type">
          <span
            :active="a.title.active"
            :style="a.title.style || {}"
            class="node-title"
            >{{ a.title.text }}</span
          >
          <!-- 二级树 -->
          <ul v-if="a.children" class="topo-childrens">
            <li class="tree-level" v-for="(child, $i) in a.children" :key="$i">
              <span
                :active="child.title.active"
                :style="child.title.style || {}"
                class="topo-title"
                >{{ child.title.text }}</span
              >
              <ul v-if="child.children" class="topo-childrens">
                <!-- 三级节点 -->
                <li
                  v-for="(childNode, $i) in child.children"
                  :key="$i"
                  class="tree-level"
                >
                  <span
                    :active="childNode.title.active"
                    :style="childNode.title.style || {}"
                    class="topo-title"
                    >{{ childNode.title.text }}</span
                  >
                </li>
              </ul>
            </li>
          </ul>
        </div>
        <!-- 拓扑图类型:3 ------------------------------------------>
        <!-- 这个类型太没规律了,担心设计师的脑回路有一定问题 -->
      </li>
    </ul>
  </div>
</template>
 
<script>
export default {
  props: ["data"],
};
</script>
 
<style lang="scss" scoped>
@import "~@/css/sg";
.tree-body {
  height: min-content;
  position: relative;
  display: inline-block;
  background: #ffffff;
  border-radius: 4px;
  border: 1px dashed #0050b3;
  box-sizing: border-box;
  padding: 10px;
 
  &[gray] {
    background: #ffffff;
    border-radius: 4px;
    border: 1px dashed #dddddd;
    box-sizing: border-box;
    padding: 10px;
    display: inline-block;
    font-size: 12px;
    width: min-content;
    flex-shrink: 0;
  }
 
  &[arrow-right]::after {
    content: url(~@/assets/softwareIndustryBigBrain/common/tree-body/tree-body-arrow.jpg); //右上角的向右箭头图片
    position: absolute;
    right: -22px;
    top: -10px;
  }
  .topo-title {
    transition: 0.618s ease;
    pointer-events: none;
    cursor: pointer;
    box-sizing: border-box;
    text-align: center;
    width: calc(100% - 40px);
    height: 30px;
    line-height: 26px;
    padding: 0 20px;
    margin: 0 auto;
    margin-top: -25px;
    background: #002766;
    border-radius: 4px;
    font-size: 16px;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: #ffffff;
    &[gray] {
      padding: 0 10px;
      height: 22px;
      background: #f0f2f5;
      border-radius: 11px;
      font-size: 12px;
      font-weight: 400;
      color: #999999;
      line-height: 22px;
      display: inline-block;
      width: min-content;
      white-space: nowrap;
      display: block;
      margin-top: -20px;
    }
    &.main-node[active] {
      pointer-events: auto;
      &:hover {
        background: #0050b3!important;
      }
    }
  }
  .topo-container {
    margin-top: 15px;
    .node-title {
      pointer-events: none;
      display: inline-block;
      height: 30px;
      padding: 0 20px;
      background: #40a9ff;
      border-radius: 4px;
      font-size: 14px;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #ffffff;
      line-height: 26px;
      display: inline-block;
      width: min-content;
      white-space: nowrap;
      cursor: pointer;
      transition: 0.618s ease;
      &:hover {
        background: #0050b3;
      }
      &[active] {
        pointer-events: auto;
        background: #0050b3;
        &:hover {
          background: #0050b3cc;
        }
      }
    }
    [type="1"] {
      text-align: center;
 
      .topo-childrens {
        display: flex;
        justify-content: space-evenly;
        margin-top: 40px;
        position: relative;
        &::before {
          content: "";
          width: 1px;
          height: 16px;
          background: #40a9ff;
          position: absolute;
          top: -42px;
        }
        &::after {
          content: "";
          width: 50px; //二级横线宽度
          height: 1px;
          background: #40a9ff;
          position: absolute;
          top: -26px;
        }
        > * {
          position: relative;
          // 默认的节点⊥
          &::before {
            position: absolute;
            content: "";
            // width: 100%;
            width: 0;
            height: 16px;
            // border-radius: 4px;
            box-sizing: border-box;
            border-right: 1px solid #40a9ff;
            top: -27px;
          }
          //第一个节点顶部的曲线╭
          &:first-of-type {
            &::before {
              border: 1px solid #40a9ff;
              border-top-left-radius: 4px;
              border-right: none;
              left: 50%;
              width: 50%;
              border-bottom: none;
            }
          }
          //最后一个节点顶部的曲线╮
          &:last-of-type {
            &::before {
              border: 1px solid #40a9ff;
              border-top-right-radius: 4px;
              border-left: none;
              right: 50%;
              width: 50%;
              border-bottom: none;
            }
          }
        }
      }
      .node-title[border] {
        pointer-events: none;
        background: #ffffff;
        border: 1px solid #40a9ff;
        color: #40a9ff;
        margin-bottom: 10px;
        &:last-of-type {
          margin-right: 0;
          margin-bottom: 0;
        }
        cursor: pointer;
        transition: 0.618s ease;
        &:hover {
          color: #0050b3;
          border-color: #0050b3;
        }
        &[active] {
          pointer-events: auto;
          color: #0050b3;
          border-color: #0050b3;
          &:hover {
            background: #40a9ff33;
          }
        }
      }
    }
    .tree-level {
      margin-bottom: 10px;
      &:last-of-type {
        margin-right: 0;
        margin-bottom: 0;
      }
    }
  }
}
// ----------------------------------------
[type="2"] {
  width: min-content;
  margin: 0 auto;
  .tree-level {
    margin-top: -5px;
    width: min-content;
    margin-left: 20px;
    //二级元素 第一个节点的左侧线条└
    &:first-of-type .topo-title::before {
      height: 25px;
      top: -11px;
    }
  }
  .topo-title {
    pointer-events: none;
    margin-top: 15px;
    background: #ffffff;
    border: 1px solid #40a9ff;
    color: #40a9ff;
    font-size: 14px;
    height: 30px;
    line-height: 26px;
    display: block;
    width: min-content;
    white-space: nowrap;
    box-sizing: border-box;
    position: relative;
    cursor: pointer;
    transition: 0.618s ease;
    + .topo-childrens {
      margin-top: 10px;
      .tree-level {
        .topo-title {
          margin-right: -30px;
          margin-top: 15px;
          //二级元素 常规点的左侧线条└
          &::before {
            height: 40px;
            top: -26px;
          }
 
          //二级元素延长线|
          &::after {
            content: "";
            position: absolute;
            top: -25px;
            left: -36px;
            height: 40px;
            width: 1px;
            background: #40a9ff;
          }
        }
        //三级元素 第一个节点的左侧线条└
        &:first-of-type .topo-title::before {
          height: 25px;
          top: -11px;
        }
      }
    }
    &:hover {
      color: #0050b3;
      border-color: #0050b3;
    }
    /* &[active] {
      &:hover {
      color: #0044b1;
        border-color: #0044b1;
      }
    } */
    &[active] {
      pointer-events: auto;
      color: #0050b3;
      border-color: #0050b3;
      &:hover {
        background: #40a9ff33;
      }
    }
    &::before {
      content: "";
      position: absolute;
      left: -16px;
      top: -25px;
      width: 16px;
      height: 40px;
      box-sizing: border-box;
      border: 1px solid #40a9ff;
      border-top: 0;
      border-right: 0;
    }
  }
  > .topo-childrens {
    display: flex;
    flex-wrap: wrap;
    margin-top: 0px;
    > .tree-level {
      margin-top: -5px;
      margin-bottom: 0;
    }
  }
  .topo-childrens {
    flex-direction: column;
    .tree-level:last-of-type {
      position: relative;
      // 用于隐藏二级元素左侧最后多余的延长线|
      &::after {
        content: "";
        position: absolute;
        top: 30px;
        left: -15px;
        width: 1px;
        height: calc(100% - 40px);
        background: white;
      }
      // 最后一个节点元素左侧线条╰
      > .topo-title:last-of-type {
        &::before {
          border-bottom-left-radius: 4px;
        }
      }
    }
  }
}
</style>



【sgTopo】强哥古法炮制、纯手工打造简单拓扑图、流程图、思维导图组件(完善中ing)(二)https://developer.aliyun.com/article/1476837

相关文章
|
7月前
【sgTopo】强哥古法炮制、纯手工打造简单拓扑图、流程图、思维导图组件(完善中ing)(二)
【sgTopo】强哥古法炮制、纯手工打造简单拓扑图、流程图、思维导图组件(完善中ing)
|
7月前
|
存储 供应链 安全
dapp系统开发详细规则/玩法功能/案例设计/源码步骤
DApp是指去中心化应用(Decentralized Application),是构建在区块链技术之上的应用程序。与传统的中心化应用不同,DApp不依赖于中心化的服务器或管理者,而是通过智能合约和分布式网络来实现去中心化的运行。
|
6月前
|
Java 数据安全/隐私保护
JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)(二)
JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)(二)
188 0
|
6月前
|
Java API 数据安全/隐私保护
JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)(一)
JavaSE——基础小项目-模拟ATM系统(项目主要目标、技术选型、架构搭建、具体实现、完整代码注释)(一)
142 0
|
7月前
|
存储 NoSQL Java
10张流程图+部署图,讲透单点登录原理与简单实现
10张流程图+部署图,讲透单点登录原理与简单实现
196 1
10张流程图+部署图,讲透单点登录原理与简单实现
|
存储 人工智能 供应链
产品流程图是什么?怎么做?
介绍产品流程图的5个种类,4个模板网站
产品流程图是什么?怎么做?
|
Kubernetes 应用服务中间件 nginx
CKAD考试实操指南(四)---优雅设计:掌握Pod设计技巧
在这篇 CKAD 考试实操指南文章中将为你介绍如何使用知十平台并结合开源项目 CKAD Exercises 中提供的练习题来练习 CKAD 考试中 Pod Design 部分的考试内容。在这个过程中你将熟悉如何通过 kubectl 命令行工具去操作「Label」、「Annotation」、「Pod」、「Deployment」、「Job」、「CronJob」,并在实践中加深对知识的理解。
204 0
CKAD考试实操指南(四)---优雅设计:掌握Pod设计技巧
|
存储 程序员 uml
【程序员必备】绘制架构图,流程图神器推荐
好的图形可以帮我们更好的表达自己,帮我们理清逻辑
|
JSON 数据可视化 前端开发
可视化拖拽组件库一些技术要点原理分析(二)(下)
可视化拖拽组件库一些技术要点原理分析(二)(下)
113 0
|
前端开发 搜索推荐 JavaScript
JSplumb 中文教程(前端自定义组件,流程图,拓扑图)
JSplumb 中文教程(前端自定义组件,流程图,拓扑图)
1509 0