2017-09-01 76 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(); 
} 

我怎样才能使背景图像棒本身的形状,所以它与含有它的形状的动作?

回答