2016-10-07 1 views
1

Ich habe den folgenden Code in meinem Codepen, der die Sprites-Flags (aus CSS) rendern kann, aber es ist nicht in der Position, wo es auf der Position des Knotens basieren sollte .D3.js - Beschriftungsknoten mit Bild in Force-Layout

In der Tat kann ich die Knoten von den Flags Sprites von oben ziehen!

Mit Blick auf einige console.logs scheint es, dass d.x und d.y Position von function ticked() nicht übergeben wird, wenn die Knoten aufgerufen werden.

Ich bin nicht sicher, wie dieses Problem

const width = w - (margin.left + margin.right); 
const height = h - (margin.top + margin.bottom); 

let flagNodes = d3.select("#canvas") 
        .append("div") 
        .classed("flag-nodes",true) 

let svg = d3.select("#canvas") 
       .append("svg") 
       .attr("id","chart") 
       .attr("width", w) 
       .attr("height", h) 

let chart = svg.append("g") 
       .classed("display", true) 
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

let simulation = d3.forceSimulation() 
    .force("link", d3.forceLink().id(function(d,i) { 
     return i; 
     })) 
    .force("charge", d3.forceManyBody().strength(-4)) 
    .force("center", d3.forceCenter(width/2, height/2)) 

let node = flagNodes.selectAll(".flag-nodes") 
     .data(data.nodes) 
     .enter() 
      .append("div") 
      .attr("class", function(d,i){ 
      return `flag flag-${d.code}` 
      }) 
      .call(d3.drag() 
      .on("start", dragstarted) 
      .on("drag", dragged) 
      .on("end", dragended) 
     ) 

let link = chart.append("g") 
     .classed("links",true) 
     .selectAll("line") 
     .data(data.links) 
     .enter() 
      .append("line") 


node.append("title") 
.text(function(d) { return d.country; }); 

simulation 
    .nodes(data.nodes) 
    .on("tick", ticked); 

simulation.force("link") 
    .links(data.links); 

//functions provided by D3.js 
// 
function ticked() { 
    link 
     .attr("x1", function(d) {return d.source.x;}) 
     .attr("y1", function(d) {return d.source.y;}) 
     .attr("x2", function(d) {return d.target.x;}) 
     .attr("y2", function(d) {return d.target.y;}); 

    node 
     .style("left", function(d) {return d.x}) 
     .style("top", function(d) {return d.y}); 
    } 

function dragstarted(d) { 
    if (!d3.event.active) simulation.alphaTarget(0.3).restart(); 
    d.fx = d.x; 
    d.fy = d.y; 
} 

function dragged(d) { 
    d.fx = d3.event.x; 
    d.fy = d3.event.y; 
} 

function dragended(d) { 
    if (!d3.event.active) simulation.alphaTarget(0); 
    d.fx = null; 
    d.fy = null; 
} 

Codepen

Antwort

0

Sie sind ganz nah zu beheben! Ich brauchte eine Weile, um es herauszufinden.

Ich habe schließlich einen Flag-Ordner mit Länder-PNGs in meinem Projektverzeichnis erstellt. Dann wurden sie dynamisch mit dem Ländercode geladen.

Hier ist, wie ich das Problem gelöst:

const node = svg.selectAll(".flag") 
    .data(data.nodes) 
    .enter().append("image") 
    .attr("xlink:href", d => require(`./flag/${d.code}.png`)) 
    .attr("width", radius) 
    .attr("height", radius) 
    .call(d3.drag() 
     .on("start", dragstarted) 
     .on("drag", dragged) 
     .on("end", dragended))