2016-10-21 12 views
0

バブルチャートに問題があります.D3.JS(https://d3js.org/)を使用しています。D3.JSバブルチャート - 円のサイズを小さくするときのグラフをリセット

私はライブラリを理解していないと確信しています。任意のhepが評価されます

バブルチャートを作成し、jQuery経由でonclickイベントをサークルに追加して半径を小さくすると、チャートは更新されません。これにより、まるでフルサイズのサークルがそのまま残っているかのように、同じパディングがサークルに残されます。

私の質問は、サークルの新しいサイズが使用されて見苦しいギャップが残らないようにグラフをリセットまたは再生成する方法です。ここで

が私のコードです:

<!DOCTYPE html> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
    <meta name="robots" content="noindex, nofollow"> 
    <meta name="googlebot" content="noindex, nofollow"> 
     <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
     <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script> 
     <script type="text/javascript" src="//rawgit.com/ngryman/jquery.finger/v0.1.2/dist/jquery.finger.js"></script> 
    <title></title> 
<script type='text/javascript'>//<![CDATA[ 
$(document).ready(function() { 
     var width = 700, 
     height = 700, 
     padding = 12, 
     clusterPadding = 4, 
     maxRadius = 36; 

     var n = 17, 
      m = 1; 

     var color = d3.scale.category10().domain(d3.range(m)); 
     var clusters = new Array(m); 

     var nodes = d3.range(n).map(function() { 
      var i = m, 
       r = 36, 
       d = { 
        cluster: i, 
        radius: r, 
        name: "Label", 
        x: Math.cos(i/m * 2 * Math.PI) * 200 + width/2 + Math.random(), 
        y: Math.sin(i/m * 2 * Math.PI) * 200 + height/2 + Math.random() 
       }; 

      if (!clusters[i] || (r > clusters[i].radius)) clusters[i] = d; 
      return d; 
     }); 

     var force = d3.layout.force() 
      .nodes(nodes) 
      .size([width, height]) 
      .gravity(0.52) 
      .charge(0.02) 
      .on("tick", tick) 
      .start(); 

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

     var node = svg.selectAll("circle") 
      .data(nodes) 
      .enter().append("g").call(force.drag); 
       node.append("circle") 
       .style("fill", '#efeeeb') 
       node.append("text") 
       .text(function (d) { 
        return d.name; 
       }) 

      .text(function (d) { 
       return d.name 
      }) 
      .style("fill", "black"); 

     svg.on("click", function() { 
      force.resume(); 
     }); 

     function tick(e) { 
      node.each(cluster(0.5*e.alpha * e.alpha)) 
       .each(collide(0.25)) 
      .attr("transform", function (d) { 
       var k = "translate(" + d.x + "," + d.y + ")"; 
       return k; 
      }) 
     } 

     // Move d to be adjacent to the cluster node. 
     function cluster(alpha) { 
      return function (d) { 
       var cluster = clusters[d.cluster]; 
       if (cluster === d) return; 
       var x = d.x - cluster.x, 
        y = d.y - cluster.y, 
        l = Math.sqrt(x * x + y * y), 
        r = d.radius + cluster.radius; 
       if (l != r) { 
        l = (l - r)/l * alpha; 
        d.x -= x *= l; 
        d.y -= y *= l; 
        cluster.x += x; 
        cluster.y += y; 
       } 
      }; 
     } 

     // Resolves collisions between d and all other circles. 
     var ID=0; 
     function collide(alpha) { 
      var quadtree = d3.geom.quadtree(nodes); 
      return function (d) { 
       var r = d.radius + maxRadius + Math.max(padding, clusterPadding), 
        nx1 = d.x - r, 
        nx2 = d.x + r, 
        ny1 = d.y - r, 
        ny2 = d.y + r; 
       quadtree.visit(function (quad, x1, y1, x2, y2) { 
        if (quad.point && (quad.point !== d)) { 
         var x = d.x - quad.point.x, 
          y = d.y - quad.point.y, 
          l = Math.sqrt(x * x + y * y), 
          r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding); 
         if (l < r) { 
          l = (l - r)/l * alpha; 
          d.x -= x *= l; 
          d.y -= y *= l; 
          quad.point.x += x; 
          quad.point.y += y; 
         } 
        } 
        return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
       }); 
      }; 
     } 

      var SVG = document.getElementsByTagName('svg')[0] 
      var children = SVG.childNodes; 

      [].forEach.call(children, function (child) { 
       if(child.nodeType === 1 && child.tagName == "g"){ 
        child.setAttribute('class', 'normal'); 
        child.setAttribute('id', 'g'+ID); 
        ID++; 
       } 
       $('#totalBubbles').val(ID); 
      }); 

      // click event to change appearance of circle 
      $('#bubbles').on('click', '.normal', function() { 
       $(this).find('circle').css({ fill: "#ffcc00" }); 
       $(this).find('circle').attr('r', 34); 
       force.resume(); 
       }); 

      // long press event to reduce circle size 
       $('#bubbles').on('press', '.normal', function() { 
        $(this).find('circle').css({ fill: '#595959' }); 
        $(this).find('circle').attr('r', 20); 
        $(this).find('text').css('font-size',"6px"); 
       }); 

     var labels = ["One",'Two','three','Four','Five','Six','Seven','Eight','Nine','Ten','Eleven','Twelve','Apple','Banana','Carrot','Onion','Beans']; 

     var z=0; 
     $('g').each(function() { 
      $(this).find('text').html(labels[z]); 
        $(this).find('circle').attr('r', 36); 
        $(this).find('text').attr("text-anchor","middle").attr("alignment-baseline","central"); 
      z++; 
     }); 
    });//]]> 
</script> 


</head> 

<body> 

    <div id='bubbles'></div> 
https://jsfiddle.net/amkdhpst/ 
</body> 

</html> 

私はここにJSFiddleを作成しました:任意のポインタのためのJS FIddle

感謝を事前に

デビッド

答えて

0

あなたの最善の策は、になりますD3.jsイベントハンドラを使用してクリックイベントを管理し、jQueryクリックハンドラを完全に削除します。

var node = svg.selectAll("circle") 
    .data(nodes) 
    .enter().append("g").call(force.drag); 
     node.append("circle") 
     .style("fill", '#efeeeb') 
     .on("click", function() { 
      d3.select(this) 
      .style("fill", '#ffcc00') 
      .attr("r", 25)     
     }); 

Updated Fiddle

+0

返事に感謝:私はこのように見えるためにあなたのvarノードを変更しました。私はあなたの更新されたJSFiddleを試して、私のページであなたのコードを使用していますが、泡はまだ元のサイズスペースを占有しています。バブルの大きさが変わった後で、チャートを閉じるのを奨励しているようには思えません:( –

+0

ああ、私のミス。どのようにサイズを変更するか質問していると分かりましたあなたが占めるスペースを小さくするには、クリック時に強制アルゴリズムを再実行する必要があります(クリックコールバックでforce.start()を呼び出すなど)。カスタムクラスターアルゴリズムでは、サークルのサイズを考慮する必要があります。カスタムのアルゴリズムを必要とせずに、すぐに使用できるout.box()メソッドが目的に役立ちます。 – bartelski

関連する問題