2016-10-08 11 views
4

は現在、私は、FCCのプロジェクトの1 National Contiguityd3.js - フォース・レイアウト境界問題V4

を働いている基本的に私は、フラグスプライトをレンダリングノードとそのリンクを接続するためにどのようにそれを把握することができました。

問題が発生するのは、FCCのexampleと同じように動作する方法が実装されていることだけです。具体的には、例のようにノードを境界線からはずすようにする方法を試しています。

しかし、鉱山はそのようには動作しません(実際には非常にクラスタ化されていますが、私が調べるべき性質は正確にはわかりません)。その代わりに、ノードとリンクが境界付近で停止しても、それはシミュレーションのノードでこの機能を実行し、すべてのダニには、その時点で

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(-60).distanceMax(50).distanceMin(5)) 
    .force("center", d3.forceCenter(width/2, height/2)) 
    .force("collide", d3.forceCollide().radius(35)) 
    // .force("centering", d3.forceCenter(,height)) 
    // .force("position", d3.forceX(0).strength(.01)) 
    // .force("position", d3.forceY(-18)) 


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

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

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

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) 
     ) 

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

d3.forceX(width) 

//functions provided by D3.js 
// 
function ticked() { 
    node 
     .style("left", function(d) { 
      let xlimit = Math.max(radius, Math.min(width - radius, d.x)) 
      return (xlimit) + 'px' 
     }) 
     .style("top", function(d) { 
      let ylimit = Math.max(radius, Math.min(height - radius, d.y)) 
      return (ylimit - 2) + 'px' 
     }); 
    link 
     .attr("x1", function(d) { 
      let x1 = Math.max(radius, Math.min(width - radius, d.source.x)) 
      return x1; 
     }) 
     .attr("y1", function(d) { 
      let y1 = Math.max(radius, Math.min(height - radius, d.source.y)) 
      return y1 
     }) 
     .attr("x2", function(d) { 
      let x2 = Math.max(radius, Math.min(width - radius, d.target.x)) 
      return x2; 
     }) 
     .attr("y2", function(d) { 
      let y2 = Math.max(radius, Math.min(height - radius, d.target.y)) 
      return y2 
     }); 
    } 

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

答えて

1

を停止するようだ:

fixBounds() { 
    const graphNodes = this.forceSimulation.nodes(); 

    graphNodes.forEach((node) => { 
     if (node.x - this.nodeRadius < 0) { 
      node.x = this.nodeRadius; 
      node.vx = 0; 
     } 

     if (node.y - this.nodeRadius < 0) { 
      node.y = this.nodeRadius; 
      node.vy = 0; 
     } 

     if (this.width && node.x + this.nodeRadius > this.width) { 
      node.x = this.width - this.nodeRadius; 
      node.vx = 0; 
     } 

     if (this.height && node.y + this.nodeRadius > this.height) { 
      node.y = this.height - this.nodeRadius; 
      node.yx = 0; 
     } 
    }) 
} 

これは、ノードが境界線に詰まるのを引き起こし、ノード間の力によってそれらが境界線から離れるようになります。

関連する問題