2013-07-19 22 views
9

Ben d3.js. kullanarak görüntüleyeceğim bir veri kümesi var.d3.js kabarcıklarını zorunlu/yerçekimi tabanlı düzenine dönüştürme

xp, yp, colorp ve radiusp gibi tanımlanmıştır
var dot = svg.selectAll("g") 
      .data(data) 
      .enter() 
      .append("g"); 

dot.append("circle") 
    .attr("class", "dot") 
    .attr("cx", function(d) { return xp(x(d)); }) 
    .attr("cy", function(d) { return yp(y(d)); }) 
    .style("fill", function(d) { return colorp(color(d)); }) 
    .attr("r", function(d) { return radiusp(radius(d)*2000000); }); 

dot.append("text") 
    .attr("x", function(d) { return xp(x(d)); }) 
    .attr("y", function(d) { return yp(y(d)); }) 
    .text(function(d) { return d.name; }) 

aşağıdaki gibidir::

var xp = d3.scale.log().domain([300, 1e5]).range([0, width]), 
    yp = d3.scale.linear().domain([10, 85]).range([height, 0]), 
    radiusp = d3.scale.sqrt().domain([0, 5e8]).range([0, 40]), 
    colorp = d3.scale.category10(); 

Bu noktada, aşağıdaki kabarcıkları için yapılandırma gibi kabarcıklar şeklinde, veri noktalarını temsil am kabarcıklar pozisyonlarında statik olarak (pozisyonun xp ve yp ile tanımlandığı), kabarcık büyüklüğü temelde yarıçaptan geliyor ve renk colorp ile tanımlanıyor.

Şu anda bu örnekte olduğu gibi tam olarak bunları gösteriyorum: http://bl.ocks.org/mbostock/4063269

enter image description here

ben onları bu forma göstermektir gerekenler: http://jsfiddle.net/andycooper/PcjUR/1/

enter image description here

Yani: Yerçekimi fonksiyonu kullanılarak paketlenmeli, biraz şarj olmalı, sürüklenip bir dereceye kadar itilebilirler. Bunu d3.layout.force() 'dan bir yol olduğunu görebiliyorum ama bunu gerçekten buna entegre edemedim. Bana doğru yolu ya da bazı çalışma örneklerini ve hatta ipuçlarını önerebilirseniz gerçekten minnettar olacağım. Teşekkür ederim.

+0

Henüz cevap yok mu? – user2480542

+0

'd3.layout.force()' ile bağlantı kurarken karşılaştığınız sorun nedir? – user568109

+0

Sorun şu ki d3.layout.force() otomatik olarak cx ve cy koordinatlarını tanımlar ve tam olarak nasıl yaklaşılacağını ve uygulanacağını tam olarak anlayamıyorum. Kabarcıkların konumlandırılmasını zorlayan xp ve yp değişkenlerini kaldırsam bile, bunu başaramıyorum. İlk olarak, bu kabarcıklar için zorunlu düzeni uygulamaya çalıştım ama bunun için başarısız oldu. : -/ – user2480542

cevap

2

Sanırım neredeyse oradaydık ama dot değişkeninizin özellikleri en iyi olanı değil. Ben böyle dönüşümü olacaktır: çevreler çizilen edildikten sonra

var dot = svg.selectAll(".dot") 
     .data(data) 
     .enter() 

Sonrasında, ne yapmak sen, bir force düzen oluşturmak Yeni oluşturduğunuz düğümlerle örneğini yani daha sonra on("tick") yöntemi ekleyin ve start düzeni. Ne vardı sorunu düşünmek

var force = d3.layout.force().nodes(data).size([width, height]) 
      .gravity(0) 
      .charge(0) 
      .on("tick", function(e){ 
       dot 
       .each(gravity(.2 * e.alpha)) 
        .each(collide(.5)) 
        .attr("cx", function (d) {return d.x;}) 
        .attr("cy", function (d) {return d.y;}); 
      }) 
      .start(); 

(düzeltilmiş değişken adları ile) tam bir cevap, ben gravity ve collide yöntemleri keman dan da katacak sahip olmak

function gravity(alpha) { 
     return function (d) { 
      d.y += (d.cy - d.y) * alpha; 
      d.x += (d.cx - d.x) * alpha; 
     }; 
    } 

    function collide(alpha) { 
     var padding = 6 
     var quadtree = d3.geom.quadtree(dot); 
     return function (d) { 
      var r = d.r + radiusp.domain()[1] + padding, 
       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.r + quad.point.r + (d.color !== quad.point.color) * padding; 
        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; 
      }); 
     }; 
    } 

: Bir örnek şudur Belki de kuvvet düzenini, dairelerin her birinin g elemanına uyguladınız, maalesef çalışmadı. Umarım bu, nasıl devam edeceğiniz konusunda size bir fikir verecektir. dot bildiriminin son satırınız, her bir daire için g öğesinin eklenmesiydi; bu işlem biraz zordu.

Teşekkürler.

PS Ben senin data ait x, y ve r nitelikleri x, y ve radius içerdiğini varsayalım.