javascript
THREEJS相关3d-force-graph 3d力导图使用
3d-force-graph 一個生成力導圖的插件,但是api文檔不是很友好,網上教程也很少幾乎找不到,寫完一個例子所以記錄一下自己用到的一些api的配置使用,最開始看官方例子最簡單,建議初學者先看官方例子熟悉配置,再參考這邊的配置,最后深入可以研究threejs結合起來可擴展性還是很強的
3d力導圖3d-force-graph github地址
使用ThreeJS / WebGL進行3D渲染,使用d3-force-3d或ngraph作為底層物理引擎。
它要使用需要對THREE.js有基本的了解
注意:
它的最新版有所不同,以前的bug也改進了,以前graph.refresh()有這個方法但是更新有問題,修改nodeOpacity等反而可以觸發更新。現在.refresh()可以更新整個圖譜,修改node屬性只能更新節點。包括新增了一些方法。
本文檔不保證適合最新版,最好的辦法是上手并查閱官方文檔,英語不好翻譯軟件翻譯一下也夠用了
引入
script可直接引入,npm 可通過npm install --save 3d-force-graph安裝再通過import引入。我試了幾臺電腦npm 都會報錯不能引入,cnpm就沒有問題.。但是cnpm引入three可能會出問題,最好使用npm
使用
第一次接觸最好看官方github上的例子開始著手,上手熟悉屬性,后續再根據需求和官方文檔開發
vue 中的使用
initGraph(){this.elem = document.getElementById('3d-graph');let WIDTH = document.getElementById('3d-graph').clientWidth;let HEIGHT = document.getElementById('3d-graph').clientHeight;let colors = { //定義數組,方便操作節點顏色。例初始隨機色,點擊節點,節點及其相連節點變亮,其他節點變暗,可查看官方例子,有專門的講這一點的caNodes : [], mainLinks : [],};this.Graph = ForceGraph3D()(this.elem) //數據格式{nodes:[{id:1,..},{id:2,..}...],links:[{source:1,target:2,..}...]}// .jsonUrl('../datasets/block.json') //引入json文件數據.graphData(this.graphData) //引入其他數據,更新數據也可用this.Graph.graphData(this.graphData).backgroundColor('rgba(0,0,0,0)').nodeLabel((node)=>{ //鼠標移上節點展示數據return node.id; //可采用`<p style="">${node.name}<p>`dom元素模式}).nodeRelSize(4); //可用于更新數據和修改節點大小,只能存數字,需要用方法可以使用nodeVal().linkLabel((link)=>{//鼠標移上連線展示信息// console.log(link);let label = '';return label;})// .nodeAutoColorBy('id') //節點隨機色.nodeColor((node)=>{ //自定義色})// .nodeOpacity(0.75) //節點透明度.linkColor((link)=>{ //連線顏色}).linkWidth((link)=>colors.mainLinks.indexOf(link)!=-1 ? 3 : 1) //如果是主連線,其寬度為3否則為1.width(WIDTH).height(HEIGHT).onNodeHover(node => this.elem.style.cursor = node ? 'pointer' : null).onNodeClick(node => {// this.handleCamera(node); 相機操作,比如拉近this.Graph.nodeRelSize(4);//(最新版用refresh更新)修改節點大小/半徑,并更新。如果修改了顏色用這個方法可以觸發更新才能看到效果,}).onLinkHover(link => this.elem.style.cursor = link ? 'pointer' : null).onLinkClick(link=>{});//修改節點連線長度,同d3引擎用法,如果要調整物理引擎需要對d3有一定了解再參考官方提供的配置項this.Graph.d3Force('link').distance(this.space); },初始化之后會遇到不同的需求去修改初始化后的屬性
// 調整拉近相機,官方例子上有,修改distance大小即修改相機拉近距離handleCamera(node){const distance = 600;const distRatio = 1 + distance/Math.hypot(node.x, node.y, node.z);this.Graph.cameraPosition({ x: node.x * distRatio, y: node.y * distRatio, z: node.z * distRatio }, // new positionnode, // lookAt ({ x, y, z })3000 // ms transition duration);},// 播放/暫停runCanvas(){this.run = !this.run;!this.run?this.Graph.pauseAnimation():this.Graph.resumeAnimation();},添加其他three模型進入3d-force-graph場景,要先安裝three再引入
npm install three -S import * as THREE from 'three' //或者 var THREE = require("three");再引入相關的渲染插件。一般可以不通過npm 安裝,直接放入文件夾再引入。如此處節點上顯示2d字體
import CSS2DObject,CSS2DRenderer} from '../utils/THREE/CSS2DRenderer.js render() { //兩個render需要對three.js有一定了解requestAnimationFrame(this.render);this.twoDRenderer.render(this.Graph.scene(), this.Graph.camera());},render2D() { //CSS2DRendererlet a = document.getElementById("3d-graph");this.twoDRenderer = new THREE.CSS2DRenderer();this.twoDRenderer.setSize(a.clientWidth, a.clientWidth);this.twoDRenderer.domElement.style.position = "absolute";this.twoDRenderer.domElement.style.top = "0px";this.twoDRenderer.domElement.style.pointerEvents= "none";//this.twoDRenderer.domElement.style.zIndex = -1;//一般情況下2d字體在3d-graph下面是有一個div放置的,可能會出現看不到的情況,//調整z-index和樣式或者直接加pointerEvents:none就可以解決,每個人遇到的情況都不同,比如我用z-index有些地方這樣寫可行有的就不行。//還有如果使用3drenderer其本質還是dom,但是3drenderer會存在景深層級比z-index更高,這種情況下去掉景深perspective,z-index:-1可以正常,但是dom不會隨控制器縮放而縮放。可以給canvas一個樣式pointer-events:none,使canvas可穿透,但是canvas點擊事件會失效,可以嘗試取消dom的點擊事件,canvas即可正常(提供一種解決方案,具體視情況而定)a.appendChild(this.twoDRenderer.domElement); this.twoDRenderer.render(this.Graph.scene(), this.Graph.camera());/* let grid = new THREE.GridHelper(1000, 50, 0x64FE00, 0x0C291F); //網格輔助,大小,行距,中心線顏色,網格線條顏色this.Graph.scene().add(grid); */},如果需要在原有力導圖的基礎上,添加別的模型或者需要將球體換成別的自定義three模型。例如原api沒有提供的長顯示文字信息,只有鼠標移上才能顯示相關信息。可以調用上面的創建2d文字方法
需要graph配置時定義
相比于2d字體其實用three-spritetext會更好,也更簡單,有近大遠小的空間感。但是精靈字體會比2d字體性能更差,可酌情選擇(3d字體需要下載字體文件,占用空間和加載性能最好不要用)
import SpriteText from 'three-spritetext';//添加文字 addSpriteText(node){const sprite = new SpriteText(node.id);sprite.color = '#fff';sprite.textHeight = 10;sprite.position.set(0,12,0);return sprite;},//......使用this.Graph = ForceGraph3D() (this.elem).nodeThreeObject(node=>{return this.addSpriteText(node);}).nodeThreeObjectExtend((node=>{return true}))這里我用的是默認的d3引擎,如果需要實現更深入的重力引力等調整需要對d3力導圖有一定的了解,對照官方文檔和d3寫法,就可以找到解決問題的方案。如果需要做更多的3d效果可以參考three.js,
總結
以上是生活随笔為你收集整理的THREEJS相关3d-force-graph 3d力导图使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 推荐 : 你想用深度学习谱写自己的音乐吗
- 下一篇: 西安恒智小寨java_Java常用异常整