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

vue3中如何使用d3.js繪制流程圖(TS語(yǔ)法)

 更新時(shí)間:2023年10月17日 11:23:05   作者:是淺笑耶  
這篇文章主要給大家介紹了關(guān)于vue3中如何使用d3.js繪制流程圖的相關(guān)資料,D3.js是由javaScript語(yǔ)言編寫繪圖庫(kù),其原理是通過(guò)調(diào)用一系列內(nèi)置函數(shù),生成SVG,并在網(wǎng)頁(yè)渲染,需要的朋友可以參考下

先放效果圖:

1.安裝dagre-d3和d3:

npm install d3
npm install dagre-d3

2.在組件中導(dǎo)入并使用d3和dagre-d3:

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

3.在模板中創(chuàng)建節(jié)點(diǎn)元素:

<template>
    <div class="top_model">
        <div class="flow_chart" ref="flowchartContainer"></div>
    </div>
</template>

4.在setup中定義所需數(shù)據(jù):

setup()  {
    //創(chuàng)建一個(gè)ref引用對(duì)象,它用于引用以上綁定ref為flowchartContainer的DOM元素
    const flowchartContainer = ref(null);
    const taskLogData = reactive({
        dataSource: [] as any,
        //流程圖數(shù)據(jù)
        list: {
          nodeInfos: [] as any,
          edges: [] as any,
        },
    })
}

5.進(jìn)行繪制:

//mounted生命周期鉤子函數(shù)是在組件實(shí)例掛載到 DOM 后調(diào)用的,
//在這個(gè)時(shí)候可以獲取到組件的根元素,并且可以執(zhí)行相應(yīng)的操作
//因此將繪制代碼放在這里執(zhí)行
onMounted(async () => {
    //調(diào)用了接口getListData,需要從其中取出數(shù)據(jù),因此需要執(zhí)行異步方法async/await
    await getListData();
    //nextTick函數(shù)確保了在DOM更新之后再執(zhí)行相應(yīng)的操作,
    //避免了由于異步更新導(dǎo)致的狀態(tài)不一致問(wèn)題
    nextTick(() => {
        //使用dagreD3庫(kù)來(lái)創(chuàng)建一個(gè)有向無(wú)環(huán)圖的圖形
        var g = new dagreD3.graphlib.Graph().setGraph({
          rankdir: 'LR', // 指定布局方向?yàn)閺淖蟮接?
          nodesep: 200, // 設(shè)置節(jié)點(diǎn)間距
          ranksep: 250, //垂直間距
        });
        //添加節(jié)點(diǎn)
        taskLogData.list.nodeInfos.forEach(
          (
            item: {
              id: string;
              label: any;
              tooltip: any;
              tipone: any;
              tiptow: any;
              tipthree: any;
              color: any;
            },
            index: any,
          ) => {
            //設(shè)置圖形中指定節(jié)點(diǎn)的屬性
            g.setNode(item.id, {
              label: item.label,//節(jié)點(diǎn)內(nèi)容
              //自定義屬性,調(diào)整樣式使其成為節(jié)點(diǎn)備注
              tooltip: item.tooltip,//節(jié)點(diǎn)備注(對(duì)應(yīng)圖片中的節(jié)點(diǎn)下的名稱,開(kāi)始-結(jié)束)
              tipone: item.tipone,//節(jié)點(diǎn)備注1(對(duì)應(yīng)圖片中的時(shí)間)
              tiptow: item.tiptow,//節(jié)點(diǎn)備注2(對(duì)應(yīng)圖片中的操作人員)
              tipthree: item.tipthree,//節(jié)點(diǎn)備注3(對(duì)應(yīng)圖片中的藍(lán)色備注)
              style: `fill: ${item.color}`,//節(jié)點(diǎn)填充顏色,item.color為變量
              shape: 'circle',//節(jié)點(diǎn)形狀設(shè)置為圓形
              class: 'node',//設(shè)置節(jié)點(diǎn)類名
              rank: 0, // 設(shè)置節(jié)點(diǎn)的rank屬性為0,表示在同一水平排列
            });
          },
        );
        //添加節(jié)點(diǎn)關(guān)系
        taskLogData.list.edges.forEach(
          (item: { source: string; target: string; edgeColor: string }) => {
            //創(chuàng)建并設(shè)置圖形中兩個(gè)節(jié)點(diǎn)之間的邊(Edge)
            g.setEdge(item.source, item.target, {
              // 設(shè)置邊的樣式
              style: 'stroke: ' + item.edgeColor + '; 
              fill: none; stroke-width: 2px;',
              arrowheadStyle: 'fill: none;', // 設(shè)置箭頭樣式為無(wú)箭頭
            });
          },
        );
        //創(chuàng)建一個(gè)SVG元素作為繪圖容器,
        //并將其添加到flowchartContainer.value所引用的DOM元素中
        const svg = d3
          .select(flowchartContainer.value)
          //在選定的DOM元素內(nèi)添加一個(gè)SVG元素
          .append('svg')
          //設(shè)置SVG元素的寬度與高度屬性
          .attr('width', '')
          .attr('height', 240);
        // 創(chuàng)建渲染器
        const render = new dagreD3.render();
        // 執(zhí)行渲染
        render(svg as any, g as any);
        // 添加節(jié)點(diǎn)備注
        //獲取并遍歷類名為node的元素
        svg.selectAll('.node').each((nodeId, index) => {
          // 獲取節(jié)點(diǎn)的備注信息
          const tooltipText = g.node(nodeId as any).tooltip;
          const tipone = g.node(nodeId as any).tipone;
          const tiptow = g.node(nodeId as any).tiptow;
          const tipthree = g.node(nodeId as any).tipthree;
          //獲取節(jié)點(diǎn)對(duì)象
          const node = d3.select(flowchartContainer.value);
          // 獲取元素的位置
          const bbox = g.node(nodeId as any);
          // 在節(jié)點(diǎn)下方添加備注文本
          const remarkText = (node as any)
            .append('text')
            .attr('class', 'node-remark')
            .text(tooltipText);
          const remarkTextone = (node as any)
            .append('text')
            .attr('class', 'node-remark')
            .text(tipone);
          const remarkTexttow = (node as any)
            .append('text')
            .attr('class', 'node-remark')
            .text(tiptow);
          const remarkTextthree = (node as any)
            .append('text')
            .attr('class', 'node-remark')
            .text(tipthree)
            .attr('class', 'remarkLast')
            .attr('id', 'remarkLast' + nodeId);
          //添加氣泡彈窗
          const remarkTextFour = (node as any)
            .append('div')
            .attr('class', 'remarkFlow')
            .attr('id', 'remarkFlow' + nodeId)
            .text(tipthree);
          // 調(diào)整備注位置
          remarkText
            .style('position', 'absolute')
            .style('top', `${bbox.y + 60}px`)
            .style('left', `${bbox.x + 30}px`);
          remarkTextone
            .style('position', 'absolute')
            .style('top', `${bbox.y + 80}px`)
            .style('left', `${bbox.x + 30}px`);
          remarkTexttow
            .style('position', 'absolute')
            .style('top', `${bbox.y + 100}px`)
            .style('max-width', '130px')
            .style('left', `${bbox.x + 30}px`);
          remarkTextthree
            .style('position', 'absolute')
            .style('top', `${bbox.y + 130}px`)
            .style('left', `${bbox.x + 30}px`);
          remarkTextFour
            .style('position', 'absolute')
            .style('top', `${bbox.y + 60}px`)
            .style('left', `${bbox.x + 30}px`);
          //鼠標(biāo)懸停效果
          (document.getElementById('remarkLast' + nodeId) as any).onmouseover
            = function () {
               (document.getElementById('remarkFlow' + nodeId) as any)
               .style.display = 'block';
           };
          (document.getElementById('remarkLast' + nodeId) as any).onmouseout
            = function () {
                (document.getElementById('remarkFlow' + nodeId) as any)
                .style.display = 'none';
           };
        });
      });
});

6.對(duì)接口數(shù)據(jù)進(jìn)行處理:

// 獲取流程圖數(shù)據(jù)
    const getListData = async () => {
      const res: any = await getTaskLogs();
      console.log('res', res);
      if (res.status_code == '0000') {
        const nodeList= res.data;
        // 打印數(shù)組中的節(jié)點(diǎn)
        console.log('節(jié)點(diǎn):', nodeList);
        for (var i = 0; i < nodeList.length; i++) {
          //默認(rèn)節(jié)點(diǎn)連線顏色為綠色
          let edgeColor = '#52c41a';
          //當(dāng)前節(jié)點(diǎn)之后的節(jié)點(diǎn)都設(shè)為灰色
          for (var j = i - 1; j > 0; j--) {
            if (nodeList[j].isCurNode == true) {
              taskLogData.list.nodeInfos[i].color = '#d9d9d9';
              edgeColor = '#d9d9d9';
            }
          }
          //當(dāng)前節(jié)點(diǎn)設(shè)為藍(lán)色
          if (nodeList[i].isCurNode == true) {
            taskLogData.list.nodeInfos[i].color = '#1890ff';
            edgeColor = '#1890ff';
          }
          //節(jié)點(diǎn)之間的連線
          if (i > 0) {
            taskLogData.list.edges.push({
              source: nodeList[i - 1].nodeId,
              target: nodeList[i].nodeId,
              edgeColor: edgeColor,
              style: 'stroke-solid',
            });
          }
        }
      } else {
        message.error(res.reason);
      }
    };

總結(jié) 

到此這篇關(guān)于vue3中如何使用d3.js繪制流程圖的文章就介紹到這了,更多相關(guān)vue3用d3.js繪制流程圖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • el-form-item表單label添加提示圖標(biāo)的實(shí)現(xiàn)

    el-form-item表單label添加提示圖標(biāo)的實(shí)現(xiàn)

    本文主要介紹了el-form-item表單label添加提示圖標(biāo)的實(shí)現(xiàn),我們將了解El-Form-Item的基本概念和用法,及添加提示圖標(biāo)以及如何自定義圖標(biāo)樣式,感興趣的可以了解一下
    2023-11-11
  • vue圖片壓縮與批量上傳方式

    vue圖片壓縮與批量上傳方式

    文章介紹了使用Vue和Element UI的el-upload組件實(shí)現(xiàn)圖片的批量上傳和壓縮功能,前端需引入image-conversion庫(kù)并設(shè)置相關(guān)屬性,關(guān)閉自動(dòng)上傳,通過(guò)on-change事件校驗(yàn)文件名和大小,并增加一個(gè)提交到服務(wù)器的按鈕
    2025-01-01
  • 在Vue中使用HOC模式的實(shí)現(xiàn)

    在Vue中使用HOC模式的實(shí)現(xiàn)

    這篇文章主要介紹了在Vue中使用HOC模式的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • vue前端框架vueuse的useScroll函數(shù)使用源碼分析

    vue前端框架vueuse的useScroll函數(shù)使用源碼分析

    這篇文章主要為大家介紹了vueuse的useScroll函數(shù)源碼分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • vue新手入門出現(xiàn)function () { [native code] }錯(cuò)誤的解決方案

    vue新手入門出現(xiàn)function () { [native code]&nbs

    這篇文章主要介紹了vue新手入門出現(xiàn)function () { [native code] }錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 5個(gè)實(shí)用的Vue技巧分享

    5個(gè)實(shí)用的Vue技巧分享

    在這篇文章中,我們將探討五個(gè)實(shí)用的?Vue?技巧,這些技巧可以使你日常使用?Vue?編程更高效、更富有成效,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-08-08
  • Vue的混合繼承詳解

    Vue的混合繼承詳解

    這篇文章主要介紹了Vue的混合繼承,有需要的朋友可以借鑒參考下,希望能夠有所幫助,希望能夠給你帶來(lái)幫助
    2021-11-11
  • vue類名如何獲取動(dòng)態(tài)生成的元素

    vue類名如何獲取動(dòng)態(tài)生成的元素

    這篇文章主要介紹了vue類名如何獲取動(dòng)態(tài)生成的元素,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue如何使用Element-ui表單發(fā)送數(shù)據(jù)與多張圖片到后端詳解

    Vue如何使用Element-ui表單發(fā)送數(shù)據(jù)與多張圖片到后端詳解

    在做項(xiàng)目的時(shí)候遇到一個(gè)問(wèn)題,前端需要上傳表單到后端,表單數(shù)據(jù)包括文本內(nèi)容和圖片,這篇文章主要給大家介紹了關(guān)于Vue如何使用Element-ui表單發(fā)送數(shù)據(jù)與多張圖片到后端的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • Vue判斷數(shù)組內(nèi)是否存在某一項(xiàng)的兩種方法

    Vue判斷數(shù)組內(nèi)是否存在某一項(xiàng)的兩種方法

    這篇文章主要介紹了Vue判斷數(shù)組內(nèi)是否存在某一項(xiàng),今天給大家分享兩種方法,分別是findIndex()和 indexOf()方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07

最新評(píng)論