1. 程式人生 > 實用技巧 >D3製作力導向圖

D3製作力導向圖

<html>
<head>
    <meta charset="utf-8">
    <title>Force</title>
    <style>
        .nodetext {
            font-size: 12px ;
            font-family:"Times New Roman",Georgia,Serif;

            fill:#000000;
        }
        .attrtext {
            font-size
: 12px ; font-family:"Times New Roman",Georgia,Serif; fill:#000000; fill-opacity:0.0; } .linetext { font-size: 18px ; font-family:"Times New Roman",Georgia,Serif; fill:#1f77b4; fill-opacity:0.0; }
.circleImg { stroke: #ff7f0e; stroke-width: 1.5px; } .link { fill: none; stroke: #666; stroke-width: 2.5px; } #licensing { fill: green; } .link.licensing {
stroke: green; } .link.resolved { stroke-dasharray: 0,2 1; } circle { fill: #ccc; /* stroke: #333; */ /* stroke-width: 1.5px; */ } text { font: 28px Microsoft YaHei; pointer-events: none; text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; } .linetext { font-size: 20px ; } .container { height: 525px; width: 575px; border:2px solid #000; overflow-y: scroll; overflow-x: hidden; } svg { display: block; width: 200%; height: 200%; } </style></head> <body> <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> <script> // var width = 900; // var height = 800; var width = 1360, height = 1000; img_w = 40; img_h = 40; radius = 50; //圓形半徑 radius1=3; var svg = d3.select("body").append("svg") .attr("width",width) .attr("height",height); //var data = "{{ data }}" d3.json("relation.json",function(error,root){ if( error ){ return console.log(error); } console.log(root); // high level nodes and edges var nodes = {}; var links = root.edges; links.forEach(function(link) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, label: link.label}); link.target = nodes[link.target] || (nodes[link.target] = {name: link.target, label: link.label}); }); // // secondary nodes and edges // var secondary_nodes = {}; var secondary_links = root.secondary_edges; secondary_links.forEach(function(link, index) { link.source = nodes[link.source] || (nodes[link.source] = {name: link.source, label: link.label,size: link.size}); link.target = (nodes[index+"_"+link.target] = {name: link.target, label: link.label,size: link.size}); links.push(link); index++; }); // debugger console.log(nodes); console.log(links); // //D3力導向佈局 var force = d3.layout.force() .nodes(d3.values(nodes)) .links(links) .size([width,height]) .linkDistance(function(d) { if (d.label != "property") { return 280; } return 150; }) .charge(-1500) .on("tick",tick) .start(); // var edges_line = svg.selectAll("line") .data(force.links()) .enter() .append("line") .style("stroke","#9dc477") .style("stroke-width",1) .on("mouseover",function(edge){ //單擊時讓連線線加粗 edges_line.style("stroke-width",function(line){ if(line.source.name==edge.source.name && line.target.name==edge.target.name){ return 4; } else { return 0.5; } }); }) .on("mouseout",function(edge){ edges_line.style("stroke-width",function(line){ return 0.5; }); }); //邊上的文字(人物之間的關係) var edges_text = svg.append("g").selectAll(".linetext") .data(force.links()) .enter() .append("text") .attr("class","linetext") .text(function(d){ return d.relation; }) .style("fill-opacity", 1.0) .call(force.drag); var circle = svg.append("g").selectAll("circle") .data(force.nodes()) .enter().append("circle") // .style("fill", "#99BBFF") .style("fill", function(node){ var color;//圓圈背景色 var link=links[node.index]; if(node.label=="relation"){ color="#e9b99f"; } else{ color="#afd1fc"; } return color; }) .attr("r", radius) .attr("r", function(d) { if (d.label == "property") { return Math.sqrt(d.size*65); } return radius; }) .on("click",function(node){ //單擊時讓連線線加粗 edges_line.style("stroke-width",function(line){ console.log(line); if(line.source.name==node.name || line.target.name==node.name){ return 4; }else{ return 0.5; } }); }) .call(force.drag) .on("mouseover",function(d,i){ //顯示連線線上的文字 edges_text.style("fill-opacity",function(edge){ if( edge.source === d || edge.target === d ){ return 1.0; } }); }) .on("mouseout",function(d,i){ //隱去連線線上的文字 edges_text.style("fill-opacity",function(edge){ if( edge.source === d || edge.target === d ){ return 0.0; } }); }); circle.append("svg:title") .text(function(node) { return "雙擊可檢視詳情" }); var text_dx =0; var text_dy = -80; var text = svg.append("g").selectAll("text") .data(force.nodes()) .enter() .append("text") .attr("dy", ".35em") .attr("text-anchor", "middle")//在圓圈中加上資料 .style('fill', "#000000") .attr('x',function(d){ if (d.label == "property") { if (Math.sqrt(d.size*65)>15){ // console.log(d.name+"---"+ d.name.length); var re_en = /[a-zA-Z]+/g; //如果是全英文,不換行 if(d.name.match(re_en)){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-2) .text(function(){return d.name;}); } //如果小於四個字元,不換行 else if(d.name.length<=6){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-6) .text(function(){return d.name;}); }else{ var top=d.name.substring(0,6); var bot=d.name.substring(6,d.name.length); d3.select(this).text(function(){return '';}); d3.select(this).append('tspan') .attr('x',0) .attr('y',-7) .text(function(){return top;}); d3.select(this).append('tspan') .attr('x',0) .attr('y',10) .text(function(){return bot;}); } } else{ // console.log(d.name+"---"+ d.name.length); var re_en = /[a-zA-Z]+/g; //如果是全英文,不換行 if(d.name.match(re_en)){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-22) .text(function(){return d.name;}); } //如果小於四個字元,不換行 else if(d.name.length<=6){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-16) .text(function(){return d.name;}); }else{ var top=d.name.substring(0,6); var bot=d.name.substring(6,d.name.length); d3.select(this).text(function(){return '';}); d3.select(this).append('tspan') .attr('x',0) .attr('y',-7) .text(function(){return top;}); d3.select(this).append('tspan') .attr('x',0) .attr('y',10) .text(function(){return bot;}); } } } else{ if (d.label == "relation") { // console.log(d.name+"---"+ d.name.length); var re_en = /[a-zA-Z]+/g; //如果是全英文,不換行 if(d.name.match(re_en)){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-2) .text(function(){return d.name;}); } //如果小於四個字元,不換行 else if(d.name.length<=6){ d3.select(this).append('tspan') .attr('x',0) .attr('y',-6) .text(function(){return d.name;}); }else{ var top=d.name.substring(0,6); var bot=d.name.substring(6,d.name.length); d3.select(this).text(function(){return '';}); d3.select(this).append('tspan') .attr('x',0) .attr('y',-7) .text(function(){return top;}); d3.select(this).append('tspan') .attr('x',0) .attr('y',10) .text(function(){return bot;}); } } } }); //直接顯示文字 /*.text(function(d) { return d.name; */ // }); function tick() { //path.attr("d", linkArc);//連線線 circle.attr("transform", transform1);//圓圈 text.attr("transform", transform2);//頂點文字 //更新連線線的位置 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 ; }); } //設定圓圈和文字的座標 function transform1(d) { return "translate(" + d.x + "," + d.y + ")"; } function transform2(d) { return "translate(" + (d.x) + "," + d.y + ")"; } }); </script> </body> </html>

json檔案格式

結果圖為: