日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

用D3.js进行图谱展示时连接线长度随节点大小动态变化的实现方式

發布時間:2024/1/18 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用D3.js进行图谱展示时连接线长度随节点大小动态变化的实现方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題起源:?用d3.js實現前端知識圖譜的展示,開始跟著視頻做了一個基本功能,但是節點的大小不能調整,于是做了一個大小調整的功能,即選中一個標簽,然后再選擇大小,從而實現讓節點根據類型的不同來變化,然后自己就嘗試做了一下,基本實現了選擇大小的功能,但是新的問題隨之而來,發現節點變大之后連接線很短,節點變小之后,連接線上的箭頭又距離節點很遠,原因在于原來節點間的連線是根據節點的圓心來連接的,箭頭的位置是按照一個固定的半徑大小進行偏移的,然后現在的節點的半徑是用戶可以隨意調節的大小,所以設置一個固定的偏移量自然不能隨著節點半徑的變化而變化了。

知道了問題所在,就來解決問題,開始一個直觀的思路是,讓箭頭的偏移量可以跟隨半徑的大小而變化,因為節點的半徑的改變就是用的這個思路,獲取到所有節點,然后遍歷每一個,判斷這個節點的類型是否有對應的用戶自定義量,如果有的話就用用戶自定義的,沒有就用默認的。但是問題是,箭頭的實現方式和節點的實現方式不同,節點的實現方式是每個節點是一個獨立的個體,然后用<g>包著可以遍歷每一個,但是箭頭是用了兩個<marker>就像模具,每個路徑引用這個模具,每個模具都是一模一樣的。所以沒有辦法遍歷每一個箭頭,而且箭頭偏移量和節點的類型之間也沒有關聯,即使能夠遍歷也無法根據節點類型來動態調節偏移量。

后來在neo4j browser的前端代碼中找到了靈感,它在實現邊連線的時候,是用path在目的節點的與源節點的切點位置畫了一個箭頭,而不是用的圓心位置然后進行箭頭的偏移,所以就想到通過調整連線的起始位置,不讓path從圓心指向圓心的,而是連接兩個圓最接近的兩個點,這樣是不是就解決問題了,這樣問題的解決思路就從改變箭頭的偏移量變為改變連線的盡頭的位置,運動是相對的嘛,你不動,我就動。

有了這個思路,實現起來就比較容易了,用到的就是初中的幾何知識了。下面是代碼演示:

//給出源節點和目標節點,返回目標節點的邊上距離源節點最近的點的坐標getCoord(source, target) {//根據目標節點的類型,計算路徑的長度,讓路徑指向目標節點的邊,而不是圓心let r = 30;if (this.nodeSizeList.has(target.type)) {r = this.nodeSizeList.get(target.type);}let scale =r /Math.sqrt(Math.pow(target.y - source.y, 2) + Math.pow(target.x - source.x, 2));let targetX = target.x - scale * (target.x - source.x);let targetY = target.y - scale * (target.y - source.y);return targetX + " " + targetY;}

最后是在實現上的幾個問題:

  • 改變節點大小后,路徑的長度沒有更新

    這是因為最后沒有觸發力導向圖的更新,這個需要最后restart()一下
  • 當目標節點在源節點左側的時候路徑離節點很遠,而目標節點在源節點右側的時候有看不到箭頭(實際上是因為箭頭的底部靠近了連線的終點。示意圖如下:

  • 引發左右bug不一致的原因是源于路徑繪制時的一個問題:因為d3的機制,文字只會呈現在路徑的上方,所以當路徑是從右至左的時候,文字就會倒立起來,看起來奇怪,所以為了解決這個問題,因為路徑是從源節點指向目的節點的,所有目的節點出現在源節點的左邊,這個時候就會出現文字倒立的現象,這個時候就逆向思維讓目的節點指向源節點,這行路徑還是保持了自右至左,所以目的節點出現在源節點左側和右側的路徑繪制是不同的。

    先說左側的bug,左側的路徑距離節點遠了,說明減多了,對于正常的情況,也就是目標節點在源節點右側的時候,是通過計算目標節點端應該縮短多少,因為箭頭是附在目標節點端的。但是對于目標節點出現在源節點左側的時候,這個時候我們將目標節點和源節點調換身份,左側的目標節點變為源節點,右側的源節點變為目標節點,此時箭頭是附在“源節點”這一端的,所以應該縮短“源節點”端的長度,但是縮短的比例開始的時候是按目標端的半徑算的,所以開始的時候按目標端的比例去縮短源節點端就導致不匹配,驢唇對不上馬嘴。所以只計算一端的思路是滿足不了我們的需求的,所以就用一個函數來單獨計算坐標,分別計算兩端的坐標而不是只計算一端。

    右側的bug,不是因為這個原因,右側path的計算是正確的,但是因為上圖示意的那個問題,所以讓箭頭偏移一個箭頭的位置,這樣就能露出來了

    組件的地址如下,如果有需要的同學可以watch:

    https://github.com/lzzlzz/Knowledge_grap

    ?

    ?

    總結

    以上是生活随笔為你收集整理的用D3.js进行图谱展示时连接线长度随节点大小动态变化的实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。