最近的工做與可視化有關,有展現血緣關係樹的需求 ,相似於這樣:javascript
碰巧搜到 D3(用於可視化的js庫,做者呂之華),瞬間沒法自拔,它的樹狀圖功能基於SVG、js ,暴露的可操做入口也簡潔恰當,能幫助你快速完成svg開發。css
D3的使用: 入門教程:http://wiki.jikexueyuan.com/project/d3wiki/author.htmlhtml
開發筆記:前端
1. SVG DOM 與HTML DOM 不同,屬性、樣式是不共用的,但也有類似之處java
2. Svg中一段文本用<text>標籤,若是要集中控制多個元素用<g>(group)標籤node
3. 鉤子: css3
nodeEnter nodeUpdate nodeExit
var flare = { "name": "前端應用", "children": [ { "name": "服務1", "children": [ { "name": "cluster", "children": [ {"name": "AgglomerativeCluster", "size": 3938} ] }, { "name": "graph", "tablename" : "public.conf_hanzhi_pinyin", "dataowner" :"hippopMan", "datadeveloper":"hippopMan", "url":"/biReport/report/aabbcc.html", "children": [ {"name": "BetweennessCentrality", "size": 3534}, {"name": "LinkDistance", "size": 5731} ] }, { "name": "optimization", "children": [ {"name": "AspectRatioBanker", "size": 7074} ] } ] }, { "name": "服務2", "children": [ {"name": "Easing", "size": 17010}, {"name": "FunctionSequence", "size": 5842} ] }
........ ] };
具體代碼:app
var margin = {top: 20, right: 120, bottom: 20, left: 120}, width = 3200 - margin.right - margin.left, height = 1200 - margin.top - margin.bottom; var i = 0, duration = 750, root; var tree = d3.layout.tree() .size([height, width]); var diagonal = d3.svg.diagonal() .projection(function(d) { return [d.y, d.x]; }); var svg = d3.select(".canvan").append("svg") .attr("width", width + margin.right + margin.left) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + 80 + "," + 20 + ")"); function collapse(d) { if (d.children) { d._children = d.children; d._children.forEach(collapse); d.openFlag = false; //自定義屬性 }else{ if(searchFlag){ d.openFlag = false; }else{ if(reportKey){ d.openFlag = true; } } } } function update(source) { // Compute the new tree layout轉換數據 var nodes = tree.nodes(root).reverse(), links = tree.links(nodes); // Normalize for fixed-depth. nodes.forEach(function(d) { d.y = d.depth * 240; }); // Update the nodes… var node = svg.selectAll("g.node") .data(nodes, function(d) { return d.id || (d.id = ++i); }); // Enter any new nodes at the parent's previous position. var nodeEnter = node.enter().append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; }); //css3屬性 二維動畫 var htm = "<div class='infoBox'>123</div>"; //寫文字的變遷 nodeEnter.append("circle") //畫圓 .attr("x","0px") .attr("y", "10px") //x,y表明座標,注意在group元素中,座標是指在該元素中的相對座標 .attr("cx","0px") .attr("cy", "0px") .attr("dy", ".35em") .attr("text-anchor", "middle") .style("fill-opacity", 1) //透明度 顯示隱藏用display(none,block) .style("fill", function (d) { //填充顏色 return d.openFlag ? "#fff":"#12a566" }) .on("click", click) //給元素添加事件 .on("mouseover",hover); nodeEnter.append("text") //text標籤 .attr("class", "tablename") .attr("x","0px") .attr("y", "15px") .attr("dy", ".35em") .attr("text-anchor", "middle") .attr("width","60") .attr("height","45") .text(function(d) { return "表名" + d.tablename; }) //文字 .style("display",showTableName?"block":"none") .style("fill-opacity", 1e-6); ...... // Transition nodes to their new position. var nodeUpdate = node.transition() .duration(duration) .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; }); nodeUpdate.select("circle") .attr("r", 4.5) .style("fill", function(d) { return d.openFlag ? "#fff":"#12a566" }); nodeUpdate.select("text") .style("fill-opacity", 1); // Transition exiting nodes to the parent's new position. var nodeExit = node.exit().transition() .duration(duration) .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; }) .remove(); nodeExit.select("circle") .attr("r", 1e-6); nodeExit.select("text") .style("fill-opacity", 1e-6); // Update the links… var link = svg.selectAll("path.link") .data(links, function(d) { return d.target.id; }); // Enter any new links at the parent's previous position. link.enter().insert("path", "g") .attr("class", "link") .attr("d", function(d) { var o = {x: source.x0, y: source.y0}; return diagonal({source: o, target: o}); }); // Transition links to their new position. link.transition() .duration(duration) .attr("d", diagonal); // Transition exiting nodes to the parent's new position. link.exit().transition() .duration(duration) .attr("d", function(d) { var o = {x: source.x, y: source.y}; return diagonal({source: o, target: o}); }) .remove(); // Stash the old positions for transition. nodes.forEach(function(d) { d.x0 = d.x; d.y0 = d.y; }); } // Toggle children on click. function click(d) { if(d.childHasShowed){//已經加載出child //收起 d.children 展開 d._children; if (d.children) { d._children = d.children; d.children = null; d.openFlag = false; } else { d.children = d._children; d._children = null; d.openFlag = true; } update(d); }else{ //點擊加載child getDepenInfo(d.tablename, true, true ,d); // d.children = obj.children; // update(d); } } function hover(d) { console.log("over") }