2017-11-03 11 views
1

私は円を作成してテキストを追加するスクリプトを用意しています。異なる円のテキストが重ならないように力のシミュレーションを使いたい。バブルチャートでのテキストの強制シミュレーションが機能しません

私は現在直面しています問題は、下のグラフに示されている:(左の2個の赤い丸が重なったテキストを持っている)enter image description here

私はテキストのために私のスクリプトに力simuationを使用したが何も起こりません。私は何のエラーもないが、まだテキストが重なっている。私は多くの解決策を試みましたが、何も動作していないようです。続き

は私のスクリプトです:

function graph(data){ 
    //var margin = {top: 30, right: 20, bottom: 30, left: 50} 

    var margin = 40, 
    width = 600, 
    height = 400; 

    // var force = d3.layout.force() 
     // .nodes(datas) 
     // .size([width, height]); 

    simulation = d3.forceSimulation() 
     .force("x", d3.forceX()) 
     .force("y", d3.forceY()) 
     .force("collide", d3.forceCollide(20)); 

    var xscale = d3.scaleLinear() 
     .domain([0, d3.max(data, function (d) { 
      return +d.student_percentile; 
     })]) 
     .nice() 
     .range([0, width]); 

    var yscale = d3.scaleLinear() 
      .domain([0, d3.max(data, function (d) { 
       return +d.rank; 
      })]) 
      .nice() 
      .range([height, 0]); 

    var xAxis = d3.axisBottom().scale(xscale).tickFormat(function(d) { 
     return d > 100 ? "Not Available" : d 
    }); 

    var yAxis = d3.axisLeft().scale(yscale); 

    var svg = d3.select('.chart') 
     .classed("svg-container", true) 
     .append('svg') 
     .attr('class', 'chart') 
     .attr("viewBox", "0 0 680 490") 
     .attr("preserveAspectRatio", "xMinYMin meet") 
     .classed("svg-content-responsive", true) 
     .append("g") 
     .attr("transform", "translate(" + margin + "," + margin + ")"); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    var color = d3.scaleOrdinal(d3.schemeCategory10); 

    var local = d3.local(); 
    circles = svg.selectAll(null) 
      .data(data) 
      .enter() 
      .append("circle") 
      .attr("cx", width/2) 
      .attr("cy", height/2) 
      .attr("opacity", 0.3) 
      .attr("r", 20) 
      .style("fill", function(d){ 
      if(+d.admit_probability <= 40){ 
       return "red"; 
      } 
      else if(+d.admit_probability > 40 && +d.admit_probability <= 75){ 
       return "yellow"; 
      } 
      else{ 
       return "green"; 
      } 
      }) 
      .attr("cx", function(d) { 
      return xscale(+d.student_percentile); 
      }) 
      .attr("cy", function(d) { 
      return yscale(+d.rank); 
      }) 
      .on('mouseover', function(d, i) { 
      local.set(this, d3.select(this).style("fill")); 
      d3.select(this) 
       .transition() 
       .duration(1000) 
       .ease(d3.easeBounce) 
       .attr("r", 32) 
       .style("cursor", "pointer") 
       .attr("text-anchor", "middle"); 
       var d = this.__data__; 
       show_details(d); 
      } 
      ) 
      .on('mouseout', function(d, i) { 
      d3.select(this).style("fill", local.get(this)); 
      d3.select(this).transition() 
       .style("opacity", 0.3) 
       .attr("r", 20) 
       .style("cursor", "default") 
      .transition() 
      .duration(1000) 
      .ease(d3.easeBounce); 
      remove_details(); 
      }); 

    texts = svg.selectAll(null) 
     .data(data) 
     .enter() 
     .append('text') 
     .attr("text-anchor", "middle") 
     .text(function(d) { 
     return d.abbreviation; 
     }) 
     .attr("pointer-events", "none") 
     .attr("font-family", "sans-serif") 
     .attr("font-size", "12px") 
     .attr("fill", "black"); 

    simulation.nodes(data).on("tick", function(){ 
     texts.attr("x", function(d) { 
      return xscale(+d.student_percentile); 
      }) 
      .attr("y", function(d) { 
      return yscale(+d.rank); 
      }); 
    }); 


    //  force.on("tick", function() { 

    // texts.attr("x", function(d) { return +d.student_percentile; }) 
    //  .attr("y", function(d) { return +d.rank; }); 

    // }); 


    svg.append("text") 
     .attr("transform", "translate(" + (width/2) + " ," + (height + margin) + ")") 
     .style("text-anchor", "middle") 
     .text("Percentile"); 

    svg.append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 0 - margin) 
     .attr("x",0 - (height/2)) 
     .attr("dy", "1em") 
     .style("text-anchor", "middle") 
     .text("Rank"); 

    $('circle').tipsy({ 
     gravity: 'w', 
     html: true, 
     title: function() { 
      var d = this.__data__; 
      return d.name + '<br/> Rank: ' + d.rank + '<br/> Admit Probaility: ' + d.admit_probability + '%'; 
     } 
    }); 
} 

私もやってみました:

simulation.nodes(data).on("tick", function(){ 
     texts.attr("x", d3.forceX().x(function(d) { 
      return xscale(+d.student_percentile); 
      })) 
      .attr("y", d3.forceY().y(function(d) { 
      return yscale(+d.rank); 
      })); 
    }); 

また、これは動作しません。

答えて

2

あなたのデータや実行中のコードが見えなくても、うまく答えが出にくいです。しかし、いくつかのミスは明らかであり、これは一般的なソリューションです。

simulation = d3.forceSimulation() 
    .force("x", d3.forceX(function(d) { 
     return xscale(+d.student_percentile); 
    })) 
    .force("y", d3.forceY(function(d) { 
     return yscale(+d.rank); 
    })) 
    .force("collide", d3.forceCollide(20)); 

その後、tick機能に:

まず、あなたがforceYforceX機能でテキストにしたい位置を指定する必要があります、あなただけのシミュレーションによって作成xyプロパティを使用します。

simulation.nodes(data).on("tick", function() { 
    texts.attr("x", function(d) { 
      return d.x; 
     }) 
     .attr("y", function(d) { 
      return d.y; 
     }); 
}); 
+0

はあなたのソリューションをいただき、ありがとうございます。あなたが提供していることはある程度問題を解決しますが、値はこのように適切に拡大縮小されません。これは私のスクリプトへのリンクです:https://jsfiddle.net/ngfoha56/ 多くのバブルは、X = 100よりもさらにXの値が92で、X = 100のものがサイドと値から切り捨てられていますX = 100が100よりも前に来ています。基本的には、スケーリングに問題があると感じています。 – Yesha

+0

また、テキストの一部が重複しています – Yesha

+0

JSfiddleが機能しません。 –

関連する問題