2017-09-01 10 views
0

私は、チームメンバーのスキルと関心を力を持ったグラフに描こうとしています。d3の形をした形の背景画像を移動するには

基本構造がマップされます。サークルの隣に書かれた名前の代わりに、サークルに人の写真が含まれていればそれを持たせたいと思います。

.force('charge', d3.forceManyBody())を呼び出すと、初期化中に自分のシェイプの向きを変更することができます。これは、形状と一緒に動いていないので、背景画像に幾分奇妙な反復効果を引き起こしています。ここで

Fiddleとしても利用可能です完全なコード、次のとおりです。

var width = 640, 
    height = 480; 

    var team = [ 
     {name: "User 1", skills: ["C#", "Typescript", ".Net", "ArcGIS"]}, 
     {name: "User 2", skills: ["Project Management", "Candy Crush", ".Net"]}, 
     {name: "User 3", skills: ["C#", "Javascript", ".Net"]}, 
     {name: "User 4", skills: ["Consulting", "Release Management", "Xml"]}, 
     {name: "User 5", skills: ["Consulting", "Powerpoint"]}, 
     {name: "User 6", skills: ["Cold Fusion", "ArcGIS", "SQL Server"]}, 

    ]; 

    var links = []; 
    team.forEach((member, idx) => { 
     member.skills.forEach(skill => { 
      //foreach skill iterate over each member and find fitting matches 
      team.forEach((memberToCompare, idx2) => { 
       var compareIndex = memberToCompare.skills.indexOf(skill) 
      // console.log(member.name, idx, skill, "---",memberToCompare.name, memberToCompare.skills[compareIndex], idx2, compareIndex); 
      if(compareIndex !== -1 && idx !== idx2) { 
       links.push({source: idx, target: idx2, value: skill}) 
      } 
      }) 
     }) 
     }) 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height); 

svg.append("g").attr("class", "nodes"); 
svg.append("g").attr("class", "links"); 

var defs = svg.append('svg:defs'); 

defs.append("svg:pattern") 
    .attr("id", "grump_avatar") 
    .attr("width", 40) 
    .attr("height", 40) 
    .attr("patternUnits", "userSpaceOnUse") 
    .append("svg:image") 
    .attr("xlink:href", 'http://placekitten.com/g/40/40') 
    .attr("width", 40) 
    .attr("height", 40); 

var force = d3.forceSimulation(team) 
    .force("link", d3.forceLink().links(links) 
     .distance(150) 
    // .strength(-1) 
    ) 
    .force('charge', d3.forceManyBody()) 
    .force('center', d3.forceCenter(width/2, height/2)) 
    //.force('collision', d3.forceCollide().radius((d) => { return d.radius; })) 
    .on('tick', ticked); 



function ticked() { 
    updateLinks(); 
    var u = d3.select('svg') 
     .selectAll('circle') 
     .data(team) 

    u.enter() 
     .append('circle') 
     .attr('r', 20) 
     .merge(u) 
     .attr('cx', function (d) { 
      return d.x 
     }) 
     .attr('cy', function (d) { 
      return d.y 
     }) 
     .style("fill", "#fff") 
     .style("fill", "url(#grump_avatar)"); 

    u.exit().remove() 
} 

function updateLinks() { 
    var u = d3.selectAll(".links") 
     .selectAll("path") 
     .data(links); 

    u.enter() 
     .append("path") 
     .merge(u) 
     .attr("d", (d) => { 
      var dx = d.target.x - d.source.x, 
       dy = d.target.y - d.source.y, 
       dr = Math.sqrt(dx * dx + dy * dy); 
      return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
     }) 
     .attr("class", "link"); 

    u.exit().remove(); 
} 

にはどうすれば形状自体に背景画像のスティックを作ることができるので、それを含む形で動きますか?これを利用

.attr("patternUnits", "objectBoundingBox") 

は、それが使用される形状、それが定義されている全体のSVG要素のisntead内部座標を使用するように画像を生じさせる:

答えて

関連する問題