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

vue使用dagre-d3畫流程圖的完整代碼

 更新時間:2024年02月21日 10:29:35   作者:南半球與北海道#  
這篇文章主要給大家介紹了關(guān)于vue使用dagre-d3畫流程圖的完整代碼,dagre-d3.js是一個用于在Vue.js框架中實(shí)現(xiàn)DAG(有向無環(huán)圖)可視化的庫,它結(jié)合了vue.js、dagre和d3.js這三個庫的功能,需要的朋友可以參考下

一、安裝依賴

npm install --save d3 dagre-d3

二、dagre-d3基礎(chǔ)

其實(shí)畫普通的流程圖很簡單,主要關(guān)注節(jié)點(diǎn)數(shù)據(jù)和線條數(shù)據(jù),以上圖為例nodes用來存儲節(jié)點(diǎn)數(shù)據(jù)id必須唯一,nodeName是節(jié)點(diǎn)名稱,shape是節(jié)點(diǎn)形狀:

1)rect(長方形)

2)circle,ellipse(橢圓)

3)diamond(菱形)

還可以使用render.shapes()自定義形狀

edges用來存儲線條數(shù)據(jù),start是開始節(jié)點(diǎn),end是結(jié)束節(jié)點(diǎn),label可以給線條命名

三、流程圖

需求:根據(jù)表格中的工序名稱和上工序生成流程圖

列表數(shù)據(jù)如下:

tableList: [{
          name: "節(jié)點(diǎn)一",
          pre: []
        },{
          name: "節(jié)點(diǎn)二",
          pre: ["節(jié)點(diǎn)一"]
        },{
          name: "節(jié)點(diǎn)三",
          pre: ["節(jié)點(diǎn)一"]
        },{
          name: "節(jié)點(diǎn)四",
          pre: ["節(jié)點(diǎn)二", "節(jié)點(diǎn)三"]
        },{
          name: "節(jié)點(diǎn)五",
          pre: ["節(jié)點(diǎn)四"]
        },{
          name: "節(jié)點(diǎn)六",
          pre: ['節(jié)點(diǎn)四']
        },{
          name: "節(jié)點(diǎn)七",
          pre: ['節(jié)點(diǎn)五', '節(jié)點(diǎn)六']
        }]

數(shù)據(jù)處理,把表格數(shù)據(jù)轉(zhuǎn)變成節(jié)點(diǎn)和線條數(shù)據(jù)

async changeData() {
        // 給每個節(jié)點(diǎn)設(shè)置對應(yīng)的編號
        this.tableList.map((v, i) => {
          this.indexObj[v.name] = i;
        });
        await this.tableList.map(async (v, i) => {
          // 點(diǎn)
          this.nodes.push({
            id: i,
            nodeName: v.name,
            shape: "rect"
          });
          // 線
          let arr = await this.getLine(v);
          this.edges = this.edges.concat(arr);
        });
        this.draw();
      },
      getLine(node) {
        let brr = [];
        if (node.pre.length) {
          if (node.pre.length === 1) {
            brr.push({
              start: this.indexObj[node.pre[0]],
              end: this.indexObj[node.name],
              label: ""
            });
          } else {
            node.pre.map(v => {
              brr.push({
                start: this.indexObj[v],
                end: this.indexObj[node.name],
                label: ""
              });
            });
          }
        }
        return brr;
      },

完整代碼:

<template>
  <div style="border: 1px solid #ccc; padding: 20px; width: 600px">
    <svg class="dagre" width="600" height="600">
      <g class="container"></g>
    </svg>
    <div ref="tooltip" class="tooltip">
      <div>節(jié)點(diǎn)ID:{{currentNode.id}}</div>
      <div>節(jié)點(diǎn)名稱:{{currentNode.nodeName}}</div>
    </div>
  </div>
</template>

<script>
  import dagreD3 from 'dagre-d3';
  import * as d3 from 'd3';

  export default {
    name: 'dagre',
    props: {
      tableList: {
        type: Array,
        default: []
      }
    },
    data() {
      return {
        currentNode: {
          id: null,
          nodeName: '',
        },
        nodes: [],
        edges: [],
        indexObj: {},
        // nodes: [
        //   {id: 0,nodeName: "A",shape: "rect"},
        //   {id: 1,nodeName: "B",shape: "diamond"},
        //   {id: 2,nodeName: "C",shape: "rect"},
        //   {id: 3,nodeName: "D",shape: "rect"},
        //   {id: 4,nodeName: "E",shape: "rect"},
        //   {id: 5,nodeName: "F",shape: "rect"}
        // ],
        // edges: [
        //   {start: 0,end: 1,label: "哈哈"},
        //   {start: 1,end: 2,label: ""},
        //   {start: 1,end: 3,label: ""},
        //   {start: 2,end: 4,label: ""},
        //   {start: 3,end: 5,label: ""},
        //   {start: 4,end: 5,label: ""}
        // ],
      };
    },
    mounted() {
      // 把表格的數(shù)據(jù)轉(zhuǎn)成節(jié)點(diǎn)和線條
      this.changeData();
      // this.draw();
    },
    methods: {
      async changeData() {
        // 給每個節(jié)點(diǎn)設(shè)置對應(yīng)的編號
        this.tableList.map((v, i) => {
          this.indexObj[v.name] = i;
        });
        await this.tableList.map(async (v, i) => {
          // 點(diǎn)
          this.nodes.push({
            id: i,
            nodeName: v.name,
            shape: "rect"
          });
          // 線
          let arr = await this.getLine(v);
          this.edges = this.edges.concat(arr);
        });
        this.draw();
      },
      getLine(node) {
        let brr = [];
        if (node.pre.length) {
          if (node.pre.length === 1) {
            brr.push({
              start: this.indexObj[node.pre[0]],
              end: this.indexObj[node.name],
              label: ""
            });
          } else {
            node.pre.map(v => {
              brr.push({
                start: this.indexObj[v],
                end: this.indexObj[node.name],
                label: ""
              });
            });
          }
        }
        return brr;
      },
      // 繪制簡單的流程圖
      draw() {
        // 創(chuàng)建 Graph 對象
        const g = new dagreD3.graphlib.Graph().setGraph({
          rankdir: 'LR', // 流程圖從下向上顯示,默認(rèn)'TB',可取值'TB'、'BT'、'LR'、'RL'
        }).setDefaultEdgeLabel(function () {
          return {};
        });

        // Graph添加節(jié)點(diǎn)
        this.nodes.forEach(node => {
          g.setNode(node.id, {
            id: node.id,
            label: node.nodeName,
            shape: node
            .shape, //節(jié)點(diǎn)形狀,可以設(shè)置rect(長方形),circle,ellipse(橢圓),diamond(菱形) 四種形狀,還可以使用render.shapes()自定義形狀
            style: 'fill:#fff;stroke:#70baff', //節(jié)點(diǎn)樣式,可設(shè)置節(jié)點(diǎn)的顏色填充、節(jié)點(diǎn)邊框 fill:#61b2e4;stroke:#fff
            labelStyle: 'fill: #000;font-weight:bold', //節(jié)點(diǎn)標(biāo)簽樣式, 可設(shè)置節(jié)點(diǎn)標(biāo)簽的文本樣式(顏色、粗細(xì)、大?。ゝill: #fff;font-weight:bold
            rx: 5, // 設(shè)置圓角
            ry: 5, // 設(shè)置圓角
            paddingBottom: 15,
            paddingLeft: 20,
            paddingRight: 20,
            paddingTop: 15,
          });
        });

        // Graph添加節(jié)點(diǎn)之間的連線
        if (this.nodes.length > 1) {
          this.edges.forEach(edge => {
            g.setEdge(edge.start, edge.end, {
              label: edge.label, //邊標(biāo)簽
              style: 'stroke: #70baff; fill: none; stroke-width: 2px', // 連線樣式
              arrowheadStyle: 'fill: #70baff;stroke: #70baff;', //箭頭樣式,可以設(shè)置箭頭顏色
              arrowhead: 'normal', //箭頭形狀,可以設(shè)置 normal,vee,undirected 三種樣式,默認(rèn)為 normal
            })
          });
        }

        // 獲取要繪制流程圖的繪圖容器
        const container = d3.select('svg.dagre').select('g.container');

        // 創(chuàng)建渲染器
        const render = new dagreD3.render();
        // 在繪圖容器上運(yùn)行渲染器繪制流程圖
        render(container, g);

        // 拖拽縮放
        const svg = d3.select('svg.dagre');
        let zoom = d3.zoom().scaleExtent([0.5, 2]).on('zoom', current => {
          container.attr('transform', current.transform);
        });
        svg.call(zoom);


        // 鼠標(biāo)懸停顯示隱藏tooltip
        const that = this;
        const tooltipBox = that.$refs.tooltip;
        container.on('mouseover', e => {
          if (e.target.nodeName === "rect") {
            that.currentNode = that.nodes.filter(item => item.id === Number(e.target.__data__))[0];
            tooltipBox.style.display = 'block';
            tooltipBox.style.top = e.clientY + 20 + 'px';
            tooltipBox.style.left = e.clientX + 'px';
          }
        }).on('mouseout', function () {
          tooltipBox.style.display = 'none';
        })
      },
    },
  };

</script>

<style scoped>
  .tooltip {
    position: absolute;
    font-size: 12px;
    background-color: white;
    border-radius: 3px;
    box-shadow: rgb(174, 174, 174) 0px 0px 10px;
    cursor: pointer;
    display: none;
    padding: 10px;
  }

  .tooltip>div {
    padding: 10px;
  }

</style>

四、效果展示

五、節(jié)點(diǎn)點(diǎn)擊事件

需求:點(diǎn)擊某個節(jié)點(diǎn),修改節(jié)點(diǎn)樣式,再次點(diǎn)擊恢復(fù)原來的樣式

代碼很簡單,只需要在流程圖繪制好后加上如下代碼即可

d3.selectAll('.node').on('mousedown', (e) => {
    if(e.target.nodeName === "rect") {
      if(e.target.style.fill === "rgb(97, 178, 228)") {
        e.target.style = "fill:#877ee1;stroke:#fff";
      } else {
        e.target.style = "fill:#61b2e4;stroke:#fff";
      }
    }
});

tips:代碼里我們設(shè)置的顏色是十六進(jìn)制,但是經(jīng)過插件繪制后轉(zhuǎn)成了rgb格式,所以在比較的時候要用設(shè)置顏色的rgb格式比較

總結(jié)

到此這篇關(guān)于vue使用dagre-d3畫流程圖的文章就介紹到這了,更多相關(guān)vue dagre-d3畫流程圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue3使用Vue Router實(shí)現(xiàn)前端路由控制

    Vue3使用Vue Router實(shí)現(xiàn)前端路由控制

    在現(xiàn)代Web應(yīng)用中,前端路由控制是非常重要的一部分,它可以幫助我們將不同的頁面內(nèi)容展示給用戶,同時保持用戶在瀏覽不同頁面時的連貫性,本文將介紹如何使用Vue Router來實(shí)現(xiàn)前端路由控制,需要的朋友可以參考下
    2024-10-10
  • vue設(shè)置路由title,但刷新頁面時title失效的解決

    vue設(shè)置路由title,但刷新頁面時title失效的解決

    這篇文章主要介紹了vue設(shè)置路由title,但刷新頁面時title失效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 基于Vue自定義指令實(shí)現(xiàn)按鈕級權(quán)限控制思路詳解

    基于Vue自定義指令實(shí)現(xiàn)按鈕級權(quán)限控制思路詳解

    這篇文章主要介紹了基于vue自定義指令實(shí)現(xiàn)按鈕級權(quán)限控制,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • 手寫Vue源碼之?dāng)?shù)據(jù)劫持示例詳解

    手寫Vue源碼之?dāng)?shù)據(jù)劫持示例詳解

    這篇文章主要給大家介紹了手寫Vue源碼之?dāng)?shù)據(jù)劫持的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • vue3項(xiàng)目打包成apk(android)詳細(xì)圖文教程

    vue3項(xiàng)目打包成apk(android)詳細(xì)圖文教程

    Vue本身是一個構(gòu)建用戶界面的漸進(jìn)式框架,不能直接打包成APK文件,但是你可以使用工具將Vue應(yīng)用打包成一個可以在Android設(shè)備上安裝的APK文件,這篇文章主要給大家介紹了關(guān)于vue3項(xiàng)目打包成apk(android)的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • vue使用wavesurfer.js解決音頻可視化播放問題

    vue使用wavesurfer.js解決音頻可視化播放問題

    Wavesurfer.js是一款基于HTML5?canvas和Web?Audio的聲紋可視化插件,功能十分強(qiáng)大,在Vue框架中嵌入使用該插件,今天重點(diǎn)給大家介紹下vue使用wavesurfer.js解決音頻可視化播放問題,感興趣的朋友一起看看吧
    2022-04-04
  • vue2.0的計(jì)算屬性computed和watch的區(qū)別及各自?使用場景解讀

    vue2.0的計(jì)算屬性computed和watch的區(qū)別及各自?使用場景解讀

    這篇文章主要介紹了vue2.0的計(jì)算屬性computed和watch的區(qū)別及各自?使用場景,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • vue刷新頁面后params參數(shù)丟失的原因和解決方法

    vue刷新頁面后params參數(shù)丟失的原因和解決方法

    這篇文章主要給大家介紹了vue刷新頁面后params參數(shù)丟失的原因和解決方法,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-12-12
  • 使用vue初用antd 用v-model來雙向綁定Form表單問題

    使用vue初用antd 用v-model來雙向綁定Form表單問題

    這篇文章主要介紹了使用vue初用antd 用v-model來雙向綁定Form表單問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue實(shí)現(xiàn)點(diǎn)擊按鈕倒計(jì)時

    vue實(shí)現(xiàn)點(diǎn)擊按鈕倒計(jì)時

    這篇文章主要為大家詳細(xì)介紹了vue實(shí)現(xiàn)點(diǎn)擊按鈕倒計(jì)時,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07

最新評論