2013-02-04 16 views
10

D3 kullanılarak oluşturulan bir dağılım grafiği var. Çizgideki noktalar (SVG daireler) üzerlerine tıklanarak seçilebilir ve bölgeler D3 fırçası kullanılarak seçilebilir.D3 fırçalarla ince taneli olay işleme

Çevrelerin tıklama olayını elde etmesini sağlamak için öncelikle fırçayı oluşturmam gerektiğini, böylece dairelerin üstündedir. Ne yazık ki bu, imlecim komplodaki bir noktayı aştığında fırça boyutunu oluşturmak için sürükleyemem anlamına geliyor.

Vurgulamak ve olayları çevrelere tıklatmak için bir yol var mı, ancak ilgili olayları fırçayla sürükleyin?

cevap

13
Bu yapılabilir

ancak use of the D3 brush API ile (aşağıdaki nota bakınız).

  1. brush eleman
  2. çevreler mousedown olaya tepki arkasında çevreler ise:

    Bu

    bir örnektir http://bl.ocks.org/4747894 olduğunu. (Diğer olaylara da yanıt verebilir.)
  3. brush öğesi, sürükleme dairelerden birinin içinden başlasa bile iyi davranılır.

Bazı izleme ve D3 source code bir göz bir mousemove olay fırça tepesinde bir circle öğeden ateşlendiğinde extent düzgün sıfırlanmaz Bu davranış göstermektedir. Yani circle elemanları mousedown dinleyici de fırça extent sıfırlayarak sabitlenebilir:

 circles.on("mousedown", function (d, i) { 
      // _svg_ is the node on which the brush has been created 
      // x is the x-scale, y is the y-scale 
      var xy = d3.mouse(svg.node()), 
       xInv = x.invert(xy[0]), 
       yInv = y.invert(xy[1]); 

      // Reset brush's extent 
      brush.extent([[xInv, yInv], [xInv, yInv]]); 

      // Do other stuff which we wanted to do in this listener 
     }); 

Not: fırça seçimi otomatik .extent(values) çağırmayıAs per the API yenilenir edilmeyecektir. Sadece bir daireye tıklamak extent'u sıfırlar, ancak yapılan seçimi yeniden çizmez. Seçim, yalnızca circle içinde farklı bir seçim başlatıldığında veya çevrelerin ve geçerli seçimin dışına tıklandığında atılır. Bu, numaralı sorudan anladığım kadarıyla istenen davranış. Bununla birlikte, bu, fırçanın extent'u ne olursa olsun, grafikte görünür seçim olacağı varsayımıyla yazılan kodu bozabilir.

+0

Bu çok yakın. İdeal olarak, bir çember üzerinde başlansa bile, yaratıldıktan sonra fırçayı sürükleyebiliyorum, ama şimdi nasıl çalıştığına dair büyük bir adım! – RichH

+0

Gerçekten de, bir seçimin '' içinden sürüklenmesinin hala mümkün olmadığını görüyorum. Temiz bir olayın yapılmasının d3 için bir yama içereceğini düşünmeme rağmen, bunu nasıl temizleyeceğimi düşüneceğim. –

5

Kullanım selection.on: http://jsfiddle.net/NH6zD/1

var target, 
    dimensions = {width: 200, height: 200}, 
    svg = d3.select("body").append("svg").attr(dimensions), 
    rect = svg.append("rect").attr(dimensions); // Must be beneath circles 
svg 
    .on("mousedown", function() { 
     target = d3.event.target || d3.event.srcElement; 
     if (target === rect.node()) { 
      /* Brush */ 
     } else { 
      /* Circle */ 
     } 
    }) 
    .on("mousemove", function() { 
     if (!target) return; 
     if (target === svg.rect()) { 
      /* Brush */ 
     } else { 
      var mouse = d3.mouse(svg.node()); 
      target.attr({x: mouse[0], y: mouse[1]}); 
     } 
    }); 
(function(exit) { 
    for (var i in exit) svg.on(exit[i], function() { target = undefined; }); 
})(["mouseout", "mouseup"]);