欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue結(jié)合g6實(shí)現(xiàn)樹級(jí)結(jié)構(gòu)(compactBox?緊湊樹)

 更新時(shí)間:2023年06月20日 10:19:09   作者:我有一棵向日葵  
本文主要介紹了vue結(jié)合g6實(shí)現(xiàn)樹級(jí)結(jié)構(gòu),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

最近公司項(xiàng)目需求有用到樹級(jí)結(jié)構(gòu),所以就上網(wǎng)上找了點(diǎn)資料,本文就實(shí)現(xiàn)vue結(jié)合g6實(shí)現(xiàn)樹級(jí)結(jié)構(gòu),具體如下:

G6文檔

自定義節(jié)點(diǎn)

G6.registerNode(
  "dom-node",
  {
    draw: (cfg, group) => {
      let str = `
        <div class='item-box catalog-node ${
          cfg.isSelected ? "is-selected" : ""
        } ${cfg.status}-box' οnclick='handleDetail("${cfg.id}")' id="${
        cfg.id
      }" style="width: ${cfg.size[0] - 5}px;">
          ${
            cfg.status
              ? `<span class='status ${cfg.status}'>${getLabel(
                  ISSUE_STATUS,
                  cfg.status
                )}</span>`
              : ""
          }
          ${
            cfg?.manager?.name
              ? `<p class=''><span class="title-txt avatar-img" title='負(fù)責(zé)人'>
            <img 
              src="${cfg?.manager?.avatar}"
            />
            </span>${cfg.manager.name}
            </p>`
              : ""
          }
          <div class='title' οnclick='handleDetail("${cfg.id}")'><span ${
        cfg.typeName === "Bug" ? `class='tipText'` : ""
      }>${cfg.title}</span>
          </div>
        </div>
        `;
      return group.addShape("dom", {
        attrs: {
          width: cfg.size[0],
          height: nodeHeight(cfg),
          // 傳入 DOM 的 html
          html: str,
        },
        draggable: true,
      });
    },
  },
  "single-node"
);

在pc端,自定義的節(jié)點(diǎn),綁定的點(diǎn)擊事件起作用,但是移動(dòng)端模式,不會(huì)起作用;

解決方法:

文檔中也說明了,節(jié)點(diǎn)的選中事件,需要將Mode切換到edit模式。graph.setMode("edit");(模式可自定義)

如:

graph.setMode("edit");
graph.on("nodeselectchange", (e) => {
  // 當(dāng)前操作的 item
  alert("node");
  console.log(e.target);
  // 當(dāng)前操作后,所有被選中的 items 集合
  console.log(e.selectedItems);
  // 當(dāng)前操作時(shí)選中(true)還是取消選中(false)
  console.log(e.select);
});

此處,直接用自定節(jié)點(diǎn)的事件了。

以上只是解決了移動(dòng)端不能觸發(fā)點(diǎn)擊事件,但是移動(dòng)端存在拖動(dòng)canvas與點(diǎn)擊事件沖突問題,所以為了PC端與移動(dòng)端都能起效果,做了以下處理。

  • 設(shè)置兩個(gè)模式,default: [“drag-node”, “drag-canvas”, “click-select”]; edit: [‘click-select’]。edit 模式還需要添加個(gè)自定義的Behavior(G6.registerBehavior(“behavior-name”, {})),自定義鼠標(biāo)拖動(dòng)事件;
  • 所以,先判斷是否是移動(dòng)端,如果是移動(dòng)端,setMode(‘edit’);

全部代碼

<template>
  <div id="container"></div>
</template>
<script>
// 引入antv-G6
import G6 from "@antv/g6";
import { ISSUE_STATUS } from "@/utils/constant";
import { getLabel } from "@/utils";
// G6的配置項(xiàng)
G6.registerNode(
  "icon-node",
  {
    options: {
      size: [60, 20], // 寬高
      stroke: "#91d5ff", // 變顏色
      fill: "#fff", // 填充色
    },
    // draw是繪制后的附加操作-節(jié)點(diǎn)的配置項(xiàng)  圖形分組,節(jié)點(diǎn)中圖形對(duì)象的容器
    draw(cfg, group) {
      // 獲取節(jié)點(diǎn)的配置
      const styles = this.getShapeStyle(cfg);
      // 解構(gòu)賦值
      const { labelCfg = {} } = cfg;
      const w = styles.width;
      const h = styles.height;
      // 向分組中添加新的圖形 圖形 配置 rect矩形 xy 代表左上角坐標(biāo) w h是寬高
      const keyShape = group.addShape("rect", {
        attrs: {
          ...styles,
          x: -w / 2,
          y: -h / 2,
        },
      });
      // 文本文字的配置
      if (cfg.title) {
        group.addShape("text", {
          attrs: {
            ...labelCfg.style,
            text: cfg.title,
            x: 50 - w / 2,
            y: 25 - h / 2,
          },
        });
      }
      return keyShape;
    },
    // 更新節(jié)點(diǎn)后的操作,一般同 afterDraw 配合使用
    update: undefined,
  },
  "rect"
);
const nodeHeight = (obj) => {
  // if (obj.depth == 0) {
  //   return 100;
  // }
  const l = ["manager", "title"];
  const arr = l.filter((item) => {
    return obj[item];
  });
  return arr.length * 25 + 50;
};
G6.registerNode(
  "dom-node",
  {
    draw: (cfg, group) => {
      let str = `
        <div class='item-box catalog-node ${
          cfg.isSelected ? "is-selected" : ""
        } ${cfg.status}-box' οnclick='handleDetail("${cfg.id}")' id="${
        cfg.id
      }" style="width: ${cfg.size[0] - 5}px;">
          ${
            cfg.status
              ? `<span class='status ${cfg.status}'>${getLabel( ISSUE_STATUS, cfg.status )}</span>`
              : ""
          }
          ${
            cfg?.manager?.name
              ? `<p class=''><span class="title-txt avatar-img" title='負(fù)責(zé)人'> <img src="${cfg?.manager?.avatar}" /> </span>${cfg.manager.name} </p>`
              : ""
          }
          <div class='title' οnclick='handleDetail("${cfg.id}")'><span ${
        cfg.typeName === "Bug" ? `class='tipText'` : ""
      }>${cfg.title}</span>
          </div>
        </div>
        `;
      return group.addShape("dom", {
        attrs: {
          width: cfg.size[0],
          height: nodeHeight(cfg),
          // 傳入 DOM 的 html
          html: str,
        },
        draggable: true,
      });
    },
  },
  "single-node"
);
// 繪制層級(jí)之間的連接線
G6.registerEdge("flow-line", {
  // 繪制后的附加操作
  draw(cfg, group) {
    // 邊兩端與起始節(jié)點(diǎn)和結(jié)束節(jié)點(diǎn)的交點(diǎn);
    const startPoint = cfg.startPoint;
    const endPoint = cfg.endPoint;
    // 邊的配置
    const { style } = cfg;
    const shape = group.addShape("path", {
      attrs: {
        stroke: style.stroke, // 邊框的樣式
        endArrow: style.endArrow, // 結(jié)束箭頭
        // 路徑
        path: [
          ["M", startPoint.x, startPoint.y],
          ["L", startPoint.x, (startPoint.y + endPoint.y) / 2],
          ["L", endPoint.x, (startPoint.y + endPoint.y) / 2],
          ["L", endPoint.x, endPoint.y],
        ],
      },
    });
    return shape;
  },
});
// 默認(rèn)連接邊線的顏色 末尾箭頭
const defaultEdgeStyle = {
  stroke: "#ccc",
};
// 默認(rèn)布局
// compactBox 緊湊樹布局
// 從根節(jié)點(diǎn)開始,同一深度的節(jié)點(diǎn)在同一層,并且布局時(shí)會(huì)將節(jié)點(diǎn)大小考慮進(jìn)去。
const defaultLayout = {
  type: "compactBox", // 布局類型樹
  direction: "TB", // TB 根節(jié)點(diǎn)在上,往下布局
  getId: function getId(d) {
    // 節(jié)點(diǎn) id 的回調(diào)函數(shù)
    return d.id;
  },
  getHeight: function getHeight() {
    // 節(jié)點(diǎn)高度的回調(diào)函數(shù)
    return 16;
  },
  getWidth: function getWidth() {
    // 節(jié)點(diǎn)寬度的回調(diào)函數(shù)
    return 16;
  },
  getVGap: function getVGap(d) {
    // 節(jié)點(diǎn)縱向間距的回調(diào)函數(shù)
    if (d.parId === "0") return 70;
    return 80;
  },
  getHGap: function getHGap(d) {
    // 節(jié)點(diǎn)橫向間距的回調(diào)函數(shù)
    if (d.parId === "0") return 100;
    return 150;
  },
};
// 自定義拖動(dòng)事件
G6.registerBehavior("finger-drag-canvas", {
  dragging: false,
  offset: 0,
  getEvents() {
    return {
      touchstart: "onDragStart",
      touchmove: "onDrag",
      touchend: "onDragEnd",
    };
  },
  onDragStart(e) {
    const self = this;
    self.dragging = false;
    self.offset = 0;
    const clientX = +e.clientX;
    const clientY = +e.clientY;
    this.origin = {
      x: clientX,
      y: clientY,
    };
  },
  onDrag(e) {
    const { graph } = this;
    if (!this.dragging) {
      this.dragging = true;
    }
    this.updateViewport(e);
  },
  onDragEnd(evt) {
    const edges = graph.getEdges();
    const nodes = graph.getNodes();
    const node = evt.item;
    const point = { x: evt.x, y: evt.y };
    // this.updateViewport(e);
    this.dragging = false;
    // 這里開始識(shí)別點(diǎn)擊事件
    if (this.offset < 30) {
      // 觸發(fā)點(diǎn)擊事件(或者依靠e.target,e.type去做相應(yīng)的業(yè)務(wù)操作)
      console.log(evt, evt.type);
    }
    console.log(evt, evt.type);
    this.updateViewport(evt);
  },
  updateViewport(e) {
    const { origin } = this;
    const clientX = +e.clientX;
    const clientY = +e.clientY;
    if (isNaN(clientX) || isNaN(clientY)) {
      return;
    }
    let dx = clientX - origin.x;
    let dy = clientY - origin.y;
    if (this.get("direction") === "x") {
      dy = 0;
    } else if (this.get("direction") === "y") {
      dx = 0;
    }
    this.origin = {
      x: clientX,
      y: clientY,
    };
    const width = graph.get("width");
    const height = graph.get("height");
    const graphCanvasBBox = graph.get("canvas").getCanvasBBox();
    if (
      (graphCanvasBBox.minX <= width && graphCanvasBBox.minX + dx > width) ||
      (graphCanvasBBox.maxX >= 0 && graphCanvasBBox.maxX + dx < 0)
    ) {
      dx = 0;
    }
    if (
      (graphCanvasBBox.minY <= height && graphCanvasBBox.minY + dy > height) ||
      (graphCanvasBBox.maxY >= 0 && graphCanvasBBox.maxY + dy < 0)
    ) {
      dy = 0;
    }
    if (dx === 0 && dy === 0) return;
    // 增加拖動(dòng)距離統(tǒng)計(jì)
    this.offset += Math.abs(dx) + Math.abs(dy);
    graph.translate(dx, dy);
  },
});
let graph;
export default {
  name: "Home",
  props: {
    treeListData: {
      type: Array,
      default: () => [],
    },
    options: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  emits: ["handleSelected"],
  data() {
    return {
      listData: [],
      selectedId: "", // 選中的節(jié)點(diǎn)Id
      initOptions: {
        isFitView: true, // 是否默認(rèn)適應(yīng)全局
        isFitCenter: true, // 是否居中
        isHiddenRoot: true, // 是否顯示根元素
      },
      flag: false, // 如果是移動(dòng)端,true
    };
  },
  methods: {
    G6init() {
      if (typeof window !== "undefined") {
        window.onresize = () => {
          if (!graph || graph.get("destroyed")) return;
          if (!container || !container.scrollWidth || !container.scrollHeight)
            return;
          graph.changeSize(container.scrollWidth, container.scrollHeight);
        };
      }
      // 獲取容器
      const container = document.getElementById("container");
      // 獲取容器的寬高
      const width = container.scrollWidth;
      const height = container.scrollHeight - 30 || 500;
      // Graph 是 G6 圖表的載體-實(shí)例化
      graph = new G6.TreeGraph({
        container: "container", // 圖的 DOM 容器
        width,
        height,
        linkCenter: true, // 指定邊是否連入節(jié)點(diǎn)的中心
        modes: {
          // default 模式中包含點(diǎn)擊選中節(jié)點(diǎn)行為和拖拽畫布行為;
          default: [
            {
              type: "zoom-canvas",
              enableOptimize: true, //開啟性能優(yōu)化
            },
            "drag-node",
            "drag-canvas",
            // "zoom-canvas",
            "click-select",
          ],
          edit: ["click-select"],
        },
        // 默認(rèn)狀態(tài)下節(jié)點(diǎn)的配置
        defaultNode: {
          type: "dom-node", // 'icon-node',
          size: [250, 60],
        },
        // 默認(rèn)狀態(tài)下邊線的配置,
        defaultEdge: {
          type: "flow-line",
          style: defaultEdgeStyle,
        },
        // 布局配置項(xiàng)
        layout: defaultLayout,
        renderer: "svg",
      });
      graph.data([...this.listData][0]);
      graph.render();
      // 讓畫布內(nèi)容適應(yīng)視口。
      if (this.initOptions.isFitView) {
        graph.fitView();
      }
      if (this.initOptions.isFitCenter) {
        graph.fitCenter();
      }
      if (!this.initOptions.isHiddenRoot) {
        // 是否要移除根節(jié)點(diǎn)
        const item = graph.findById([...this.listData][0].id);
        graph.removeItem(item);
      }
      // 改變視口的縮放比例,在當(dāng)前畫布比例下縮放,是相對(duì)比例。
      graph.zoom(1);
    },
    async init() {
      let _this = this;
      if (graph) {
        // 如果原來有畫布,需要先清除
        graph.destroy();
      }
      this.initOptions = Object.assign(this.initOptions, this.options);
      this.listData = [...this.treeListData];
      function setSelectFalse(obj) {
        obj.forEach((element) => {
          element.isSelected = false;
          if (element.children) {
            setSelectFalse(element.children);
          }
        });
      }
      window.handleDetail = (id) => {
        const item = graph.findById(id);
        if (item?._cfg?.parent) {
          _this.$emit("handleSelected", id);
        }
      };
      this.G6init();
      this.isMobile();
    },
    isMobile() { // 判斷是否是移動(dòng)端
      this.flag = navigator.userAgent.match(
        /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
      );
      if (this.flag) {
        graph.setMode("edit");
        graph.addBehaviors("finger-drag-canvas", "edit");
      }
    },
  },
  beforeDestroy() {
    console.log("推出");
  },
};
</script>
<style lang="scss" scoped>
@import "@/assets/styles/common.scss";
#container {
  height: 100%;
  width: 100%;
  border: 1px solid #efefef;
  ::v-deep .title {
    font-size: 15px;
    display: block;
    // text-align: center;
    position: relative;
    margin: 10px 0;
    padding-left: 15px;
    color: #1199ff;
    cursor: pointer;
  }
  ::v-deep .item-box {
    background-color: #fff;
    border-radius: 5px;
    padding: 5px;
    // height: 100%;
    border: 1px solid;
    position: relative;
    p {
      margin-bottom: 2px;
      display: flex;
      align-items: center;
      color: #333;
    }
    &.is-selected {
      border: 1px solid #1199ff;
    }
    .tipText {
      color: red;
    }
    .logs {
      height: 70px;
      overflow: hidden;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 3;
    }
    .title-txt {
      display: inline-block;
      width: 80px;
      color: rgb(169, 169, 169);
    }
    .avatar-img {
      width: 35px;
      height: 35px;
      margin-right: 15px;
      img {
        width: 100%;
        height: 100%;
        border-radius: 100%;
      }
    }
    .status {
      position: absolute;
      right: 15px;
      top: 15px;
      border: 1px solid;
      padding: 0 5px;
      font-size: 12px;
      border-radius: 4px;
      // Wait 未開始、Doing進(jìn)行中、Pause暫停、Verify待驗(yàn)證、Done已完成、Cancel已取消
    }
  }
}
::v-deep g g g:not(:first-child) foreignObject {
  font-size: 14px;
}
foreignObject {
  overflow: initial !important;
}
</style>

到此這篇關(guān)于vue結(jié)合g6實(shí)現(xiàn)樹級(jí)結(jié)構(gòu)(compactBox 緊湊樹)的文章就介紹到這了,更多相關(guān)vue g6 樹級(jí)結(jié)構(gòu) 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue修改Dom不生效的解決

    Vue修改Dom不生效的解決

    這篇文章主要介紹了Vue修改Dom不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue3?setup中使用響應(yīng)式的方法

    vue3?setup中使用響應(yīng)式的方法

    文章主要介紹了Vue3中的響應(yīng)式數(shù)據(jù)處理機(jī)制,包括ref和reactive函數(shù)的使用,它們的區(qū)別,以及如何使用watch和watchEffect來監(jiān)聽數(shù)據(jù)變化,文章最后提到了Vue3的生命周期鉤子和自定義hooks的概念,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Vue3中使用reactive時(shí),后端有返回?cái)?shù)據(jù)但dom沒有更新的解決

    Vue3中使用reactive時(shí),后端有返回?cái)?shù)據(jù)但dom沒有更新的解決

    這篇文章主要介紹了Vue3中使用reactive時(shí),后端有返回?cái)?shù)據(jù)但dom沒有更新的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Vue數(shù)據(jù)變化后頁面更新詳細(xì)介紹

    Vue數(shù)據(jù)變化后頁面更新詳細(xì)介紹

    這篇文章主要介紹了Vue在數(shù)據(jù)發(fā)生變化后是如何更新頁面的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • 如何利用Echarts根據(jù)經(jīng)緯度給地圖畫點(diǎn)畫線

    如何利用Echarts根據(jù)經(jīng)緯度給地圖畫點(diǎn)畫線

    最近工作中遇到了一個(gè)需求,需要利用echarts在地圖上面標(biāo)記點(diǎn)位,所下面這篇文章主要給大家介紹了關(guān)于如何利用Echarts根據(jù)經(jīng)緯度給地圖畫點(diǎn)畫線的相關(guān)資料,需要的朋友可以參考下
    2022-05-05
  • vue.js移動(dòng)數(shù)組位置,同時(shí)更新視圖的方法

    vue.js移動(dòng)數(shù)組位置,同時(shí)更新視圖的方法

    下面小編就為大家分享一篇vue.js移動(dòng)數(shù)組位置,同時(shí)更新視圖的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • 如何在Vue單頁面中進(jìn)行業(yè)務(wù)數(shù)據(jù)的上報(bào)

    如何在Vue單頁面中進(jìn)行業(yè)務(wù)數(shù)據(jù)的上報(bào)

    為什么要在標(biāo)題里加上一個(gè)業(yè)務(wù)數(shù)據(jù)的上報(bào)呢,因?yàn)樵谠蹅兦岸隧?xiàng)目中,可上報(bào)的數(shù)據(jù)維度太多,比如還有性能數(shù)據(jù)、頁面錯(cuò)誤數(shù)據(jù)、console捕獲等。這里我們只講解業(yè)務(wù)數(shù)據(jù)的埋點(diǎn)。
    2021-05-05
  • Vue項(xiàng)目移動(dòng)端滾動(dòng)穿透問題的實(shí)現(xiàn)

    Vue項(xiàng)目移動(dòng)端滾動(dòng)穿透問題的實(shí)現(xiàn)

    這篇文章主要介紹了Vue項(xiàng)目移動(dòng)端滾動(dòng)穿透問題的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Vue 實(shí)現(xiàn)簡(jiǎn)易多行滾動(dòng)

    Vue 實(shí)現(xiàn)簡(jiǎn)易多行滾動(dòng)"彈幕"效果

    這篇文章主要介紹了Vue 實(shí)現(xiàn)簡(jiǎn)易多行滾動(dòng)“彈幕”效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • vue+element樹形選擇器組件封裝和使用方式

    vue+element樹形選擇器組件封裝和使用方式

    這篇文章主要介紹了vue+element樹形選擇器組件封裝和使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2020-04-04

最新評(píng)論