基於d3.js/neovis.js/neod3.js實現鏈接neo4j圖形數據庫的圖像化顯示功能
一、基於D3.js (自由度高,寫起來麻煩)
二、基於neovis.js (基於d3庫,簡潔,但樣式固定,自由度低。)
三、基於neo4jd3.js (融合neovis與d3,數據格式可用d3\neo4j的,或根據需求自己重寫方法) https://github.com/eisman/neo4jd3
Svg 不推薦在HTML4和XHTML中使用(但在HTML5允許)
一、使用d3.js
效果:
1.引入官方js
定義背景/圖片大小
用svg繪制背景、節點、線條、箭頭。
1.請求json 數據(處理成可用等d3格式{node:{ },relaton:{source: ,target: ,type: })
2. d3默認按索引鏈接結點,要強制改為通過id鏈接它們(myerror: 註意 === 與 == 的不同,數據類型會導致錯誤)
3.構造力導向佈局
力佈局使用:https://github.com/d3/d3/wiki/%E5%8A%9B%E5%B8%83%E5%B1%80
D3.layout.force( )構造力導向佈局,force.start( ) 啟動模擬;
force.tick觸發仿真第一步(如更新節點的x和y屬性);
force.drag( )交互式拖動;
4.Select元素,並操作select,據需求自定義樣式屬性()。
選擇器使用參考:https://github.com/d3/d3/wiki/%E9%80%89%E6%8B%A9%E5%99%A8#append
https://github.com/d3/d3/wiki/%E9%80%89%E6%8B%A9%E5%99%A8
【D3中,select 返回第一個匹配的元素,selectAll遍歷次序中所有匹配的元素。】
代碼:
<html> <head> <meta charset="utf-8"> <title>Force</title> <style> .nodetext { font-size: 12px ; font-family: SimSun;//字體 fill:#000000; } .linetext { /*font-family: SimSun;*/ fill:#1f77b4; fill-opacity:0.0; .circleImg { stroke: #ff7f0e; stroke-width: 1.5px; </style></head> <body> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script> <script> var width = 900; var height = 800; var img_w = 77; var img_h = 80; var radius = 30; //圓形半徑 var svg = d3.select("body") .append("svg") .attr("width",width) .attr("height",height); var edges = []; d3.json("my.json",function(error,root){ if( error ){ return console.log(error); console.log(root); //默認按索引鏈接結點,我強制改成通過id鏈接它們。 root.edges.forEach(function (e) { var sourceNode = root.nodes.filter(function (n) { return n.id === e.source; })[0], targetNode = root.nodes.filter(function (n) { return n.id === e.target; })[0]; edges.push({ source: sourceNode, target: targetNode, relation: e.type }) }); console.log(edges) //D3力導向佈局 var force = d3.layout.force() .nodes(root.nodes) .links(edges) .size([width,height]) .linkDistance(200) .charge(-1500) .start(); var defs = svg.append("defs"); var arrowMarker = defs.append("marker") .attr("id","arrow") .attr("markerUnits","strokeWidth")//圖最前端大小 .attr("markerWidth","15")//標識長寬 .attr("markerHeight","15") .attr("viewBox","0 0 12 12")//坐標系區域 .attr("refX","17") .attr("refY","6") .attr("orient","auto");//方向 var arrow_path = "M2,2 L10,6 L2,10 L6,6 L2,2"; arrowMarker.append("path") .attr("d",arrow_path) .attr("fill","#ccc"); //邊 var edges_line =svg.selectAll("line") .data(edges) .enter() .append("line") .attr("class","line") .style("stroke","#ddd") .style("linewidth",2) .attr("marker-end","url(#arrow)") .style("stroke-width",3); //邊上的文字(人物之間的關系) var edges_text = svg.selectAll(".linetext") .append("text") .attr("class","linetext") .text(function(d){ return d.relation; }) .style("fill-opacity",1.0);//不透明度 // 圓形圖片節點(人物頭像) var nodes_img = svg.selectAll("image") .data(root.nodes) .append("circle") .attr("class", "circleImg") .attr("r", radius) .attr("fill", function(d, i){ //創建圓形圖片 var defs = svg.append("defs").attr("id", "imgdefs") var catpattern = defs.append("pattern") .attr("id", "catpattern" + i) .attr("height", 1) .attr("width", 1) catpattern.append("image") .attr("x", - (img_w / 2 - radius)) .attr("y", - (img_h / 2 - radius)) .attr("width", img_w) .attr("height", img_h) .attr("xlink:href", d.labels) return "url(#catpattern" + i + ")"; // .on("mouseover",function(d,i){ // //顯示連接線上的文字 // edges_text.style("fill-opacity",function(edge){ // if( parseInt(edge.source) === d || parseInt(edge.target) === d ){ // return 1.0; // } // }); // }) // .on("mouseout",function(d,i){ // //隱去連接線上的文字 // if( edge.source === d || edge.target === d ){ // return 0.0; .call(force.drag); var text_dx = -20; var text_dy = 20; var nodes_text = svg.selectAll(".nodetext") .style("stroke","#ff7f0e") .attr("class","nodetext") .attr("dx",text_dx) .attr("dy",text_dy) var uservalue = d.properties.username; var personvalue = d.properties.person; var phonevalue = d.properties.phone; if ( uservalue == undefined ){ uservalue = ""; } if(personvalue == undefined){ personvalue = ""; if (phonevalue == undefined){ phonevalue = ""; return uservalue + phonevalue + personvalue; }); force.on("tick", function(){ //限制結點的邊界 root.nodes.forEach(function(d,i){ d.x = d.x - img_w/2 < 0 ? img_w/2 : d.x ; d.x = d.x + img_w/2 > width ? width - img_w/2 : d.x ; d.y = d.y - img_h/2 < 0 ? img_h/2 : d.y ; d.y = d.y + img_h/2 + text_dy > height ? height - img_h/2 - text_dy : d.y ; //更新連接線的位置 edges_line.attr("x1",function(d){ return d.source.x; }); edges_line.attr("y1",function(d){ return d.source.y; }); edges_line.attr("x2",function(d){ return d.target.x; }); edges_line.attr("y2",function(d){ return d.target.y; }); //更新連接線上文字的位置 edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; }); edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; }); //更新結點圖片和文字 nodes_img.attr("cx",function(d){ return d.x }); nodes_img.attr("cy",function(d){ return d.y }); nodes_text.attr("x",function(d){ return d.x }); nodes_text.attr("y",function(d){ return d.y + img_w/2; }); }); </script> </body> </html>
mydata.json
{ "nodes": [{ "id": "2", "labels": "./image/wode.png", "properties": { "person": "Person2" } }, { "id": "58688", "phone": "85266978333" "id": "128386", "username": "Samuel_lee" }], "edges": [{ "id": "23943", "type": "has", "startNode": "2", "endNode": "58688", "properties": {}, "source": "2", "target": "58688" "id": "94198", "type": "registered", "startNode": "58688", "endNode": "128386", "source": "58688", "target": "128386" }] }
二、 neo4jd3.js
https://github.com/eisman/neo4jd3
效果:
與neovis.js類似,根據d3/neo4j的數據格式,將數據傳入,根據需求渲染結點圖像關系,但樣式固定。
可以重寫js中的數據與方法。
在這裡,出現瞭問題:我在js中修改的方法無法被使用。
根據排查,最後發現在代碼末尾有一行註釋:
源映射是用來為壓縮後的代碼調試提供方便的,為瞭提高性能,很多站點都會先壓縮 JavaScript 代碼然後上線,
但如果代碼運行時出現錯誤,瀏覽器隻會顯示在已壓縮的代碼中的位置,很難確定真正的源碼錯誤位置。
要更改js記得將這行註釋刪除。
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="description" content=""> <meta name="viewport" content="width=device-width"> <title>neo4jd3.js</title> <link rel="stylesheet" href="css/bootstrap.min.css" rel="external nofollow" > <link rel="stylesheet" href="css/font-awesome.min.css" rel="external nofollow" > <link rel="stylesheet" href="css/neo4jd3.min.css?v=0.0.1" rel="external nofollow" > <script src="js/d3.min.js"></script> <script src="js/2.js?v=0.0.2"></script> <style> body, html, .neo4jd3 { height: 100%; overflow: hidden; } </style> </head> <body> <div id="neo4jd33"></div> <!-- Scripts --> <script type="text/javascript" > function init() { var neo4jd3 = new Neo4jd3('#neo4jd33', { icons: { }, images: { 'person': 'img/twemoji/wode.png', minCollision: 50, neo4jDataUrl:'./json/mydata.json', nodeRadius: 30, zoomFit: false }); window.onload = init; </script> <script> </body> </html>
三、neovis.js
詳細使用文檔見:
https://www.npmjs.com/package/neovis.js
https://github.com/neo4j-contrib/neovis.js#readme
Neovis.js 需要鏈接 neo4j 的bolt地址,並書寫cypher語句獲取查詢結果。
創建一個div,在其中制定οnlοad=“draw( )”,然後自己定義draw( )。
使用簡單,但模板樣式固定。
function draw() { var config = { container_id: "viz", server_url:"bolt://xxxxxxxx", server_user: "", server_password: "", labels: { "person": { "caption": "person", }, "phone":{ "caption": "phone", }, "zello":{ "caption": "username", } relationships: { "has": { "thickness": 0.003, "caption": true ,"registered":{ initial_cypher: "MATCH (n) RETURN n LIMIT 25", arrows: true }; viz = new NeoVis.default(config); console.log(viz); viz.render(); }
到此這篇關於基於d3.js/neovis.js/neod3.js實現鏈接neo4j圖形數據庫的圖像化顯示功能的文章就介紹到這瞭,更多相關neo4j圖像化顯示內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!