摘要:繪制力導(dǎo)向圖新建畫布創(chuàng)建,的繪制中為了避免混亂及后續(xù)事件的添加,建議使用標(biāo)簽將畫布分組。用拷貝數(shù)組,避免影響全局?jǐn)?shù)據(jù)。將數(shù)據(jù)整理為樹狀結(jié)構(gòu)使用樹狀布局計(jì)算位置重啟布局以改變位置在運(yùn)動前強(qiáng)制修改節(jié)點(diǎn)坐標(biāo)為樹狀結(jié)構(gòu)
D3力導(dǎo)向圖及樹狀布局變換
d3的力導(dǎo)向圖是表現(xiàn)關(guān)系型數(shù)據(jù)比較方便且直觀的方法,但是會遇到節(jié)點(diǎn)比較多且層級關(guān)系混亂的情況,這時(shí)樹狀布局就比較方便了,如何不破壞原來結(jié)構(gòu)以最小的代價(jià)變換樹狀布局呢?下面將為大家介紹。
最終效果http://en.jsrun.net/aXiKp/emb...
代碼解析首先我們需要準(zhǔn)備關(guān)系型數(shù)據(jù),數(shù)據(jù)包括節(jié)點(diǎn)數(shù)據(jù)nodes和連線關(guān)系數(shù)據(jù)links,links的source和target分別表示源和目標(biāo)的index。
var nodes = [ {value:"66666666",type:"home",index:"0"}, {value:"11111111111",type:"phone",index:"1"}, {value:"22222222222",type:"phone",index:"2"}, {value:"33333333333",type:"phone",index:"3"}, {value:"44444444444",type:"phone",index:"4"}, {value:"55555555555",type:"phone",index:"5"}, {value:"aaa",type:"weixin",index:"6"}, {value:"bbb",type:"weixin",index:"7"}, {value:"ccc",type:"weixin",index:"8"}, {value:"ffffd",type:"weixin",index:"9"}, {value:"eee",type:"weixin",index:"10"}, {value:"fff",type:"weixin",index:"11"}, ]; var links = [ {source:0,target:1}, {source:0,target:2}, {source:0,target:3}, {source:0,target:4}, {source:0,target:5}, {source:2,target:6}, {source:2,target:7}, {source:2,target:8}, {source:3,target:9}, {source:3,target:10}, {source:3,target:11}, ]繪制力導(dǎo)向圖
//新建畫布 var svg = d3.select("#forceMap").append("svg") .attr("width",width) .attr("height",height) .attr("id","forceSvg"); //創(chuàng)建group,svg的繪制中為了避免混亂及后續(xù)事件的添加,建議使用g標(biāo)簽將畫布分組。 var mapG = svg.append("g") .attr("id","forceGroup"); //使用d3的力學(xué)布局,通過設(shè)定的屬性,將數(shù)據(jù)計(jì)算 var force = d3.layout.force() .nodes(nodes) .links(links) .size([width,height]) .linkDistance(100) .charge([-1250]) .gravity(0.5) .friction(0.5); force.start();//開始計(jì)算 //繪制線,svg的覆蓋順序是后面標(biāo)簽覆蓋前面的,所以為了避免線在點(diǎn)上面,要先畫line var linkG = mapG.selectAll(".link") .data(links) .enter() .append("line") .attr("class","link") .attr("stroke","#ccc"); //繪制點(diǎn) var nodeG = mapG.selectAll(".node") .data(nodes) .enter() .append("circle") .attr("class","node") .attr("r",8) .attr("fill",function(d){ switch(d.type){ case "home": return "red";break; case"phone": return "blue";break; case "weixin": return "green";break; } }); //tick是力導(dǎo)向圖每一次運(yùn)動需要計(jì)算的過程 force.on("tick", function () { linkG.attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y; }); nodeG.attr("cx", function (d) { return d.x }) .attr("cy", function(d){ return d.y }); });
在tick中,d3自帶的布局計(jì)算幫我們完成了點(diǎn)和線每一次運(yùn)動的坐標(biāo),
我們只需要在tick中重新賦給頁面中的點(diǎn)和線即可完成運(yùn)動效果。
在這里,我們利用d3的tree layout完成點(diǎn)的坐標(biāo)計(jì)算。
前提是必須把關(guān)系型數(shù)據(jù)改變?yōu)闃錉顚蛹墧?shù)據(jù)。
用concat拷貝數(shù)組,避免影響全局?jǐn)?shù)據(jù)。
function drawTree(){ var middleData = {}; var linksBak = links.concat(); var nodesBak = nodes.concat(); //將數(shù)據(jù)整理為樹狀結(jié)構(gòu) nodesBak.forEach(function(d){ if(d.index == 0){ var temp = { name:d.index, children:[] }; var treeData = toTreeData(linksBak); function toTreeData(data){ var pos={}; var tree=[]; var i=0; while(data.length!=0){ if(data[i].source.index==d.index){ tree.push({ name:data[i].target.index, children:[] }); pos[data[i].target.index]=[tree.length-1]; data.splice(i,1); i--; }else{ var posArr=pos[data[i].source.index]; if(posArr!=undefined){ var obj=tree[posArr[0]]; for(var j=1;jdata.length-1){ i=0; } } return tree; } temp.children = treeData; middleData = temp; } }); //使用樹狀布局計(jì)算位置 var tree = d3.layout.tree() .size([450,450]); var tempNodes = tree.nodes(middleData); //重啟布局以改變位置 force.start(); force.on("tick",function(){ //在運(yùn)動前強(qiáng)制修改節(jié)點(diǎn)坐標(biāo)為樹狀結(jié)構(gòu) tempNodes.forEach(function(d,i){ nodes[d.name].x = d.x; nodes[d.name].y = d.y }); linkG.attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y+10; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y+10; }); nodeG.attr("cx", function (d) { return d.x }) .attr("cy", function(d){ return d.y+10 }); }) }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/88754.html
摘要:哎,其實(shí)完全可以不用力導(dǎo)向圖布局來處理拓?fù)鋱D的,力導(dǎo)向圖來處理也并不合適。初始化數(shù)據(jù)數(shù)據(jù)轉(zhuǎn)換處理可以通過力導(dǎo)向圖或者自己處理就行得到數(shù)據(jù)主要是鏈路可繪制坐標(biāo)一開始以為,力導(dǎo)向圖鏈路得到的鏈路數(shù)據(jù),會隨著節(jié)點(diǎn)數(shù)據(jù)位置變化而更新。 http://codepen.io/jingxiao/pe... https://bl.ocks.org/mbostock/...哎,其實(shí)完全可以不用力導(dǎo)向圖布...
摘要:該事件不會區(qū)分字母的大小寫,例如和被視為一致。這些布局的作用都是將某種數(shù)據(jù)轉(zhuǎn)換成另一種數(shù)據(jù),而轉(zhuǎn)換后的數(shù)據(jù)是利于可視化的。而有元素與數(shù)據(jù)對應(yīng)的部分稱為。 1.安裝
摘要:我們在上文源碼解析發(fā)現(xiàn)版的節(jié)點(diǎn)碰撞采用四叉樹進(jìn)行了優(yōu)化。那么版本的力導(dǎo)圖具體和版的有何不同點(diǎn)呢,四叉樹又如何優(yōu)化碰撞校驗(yàn)的呢原文鏈接被重命名為。性能的提高歸功于的新的四叉樹。 我們在上文源碼解析發(fā)現(xiàn)v4版的節(jié)點(diǎn)碰撞采用四叉樹進(jìn)行了優(yōu)化。那么V4版本的力導(dǎo)圖具體和v3版的有何不同點(diǎn)呢,四叉樹又如何優(yōu)化碰撞校驗(yàn)的呢? v3-force VS v4-force https://github...
摘要:通過力導(dǎo)向算法計(jì)算位置,繪制出對應(yīng)的力導(dǎo)向圖,這樣的分配是最佳位置的分布圖。力導(dǎo)向算法是根據(jù)自然界中電子直接互相作用的原理來實(shí)現(xiàn)的,自然界中。 前言 說到力導(dǎo)向可能很多小伙伴都只是會使用,不知道其中的實(shí)現(xiàn)原理,今天,我們一起來自己實(shí)現(xiàn)一套力導(dǎo)向算法,然后做一些技術(shù)相關(guān)的延伸。發(fā)散下思維。 什么是力導(dǎo)向算法? 根據(jù)百科的介紹:力導(dǎo)向算法是指通過對每個(gè)節(jié)點(diǎn)的計(jì)算,算出引力和排斥力綜合的合力...
閱讀 2611·2021-11-02 14:39
閱讀 4328·2021-10-11 10:58
閱讀 1456·2021-09-06 15:12
閱讀 1842·2021-09-01 10:49
閱讀 1330·2019-08-29 18:31
閱讀 1885·2019-08-29 16:10
閱讀 3341·2019-08-28 18:21
閱讀 875·2019-08-26 10:42