2012-12-20 16 views
17

d3.js kullanıyorum ve this example değiştirerek fırçalanmış alan grafiğinde çalışıyorum. Fırçayı temel alan x eksenine ek olarak, fırçanın içine düşen verilerin (a Google Finance chart davranışına benzer) y-değerlerini temel alarak grafiğin y ekseninin yeniden çizilmesini istiyorum.Fırçalanmış alan grafiğinin y eksenini güncelleyin

İşlevselliği çalıştım, ancak fırçanın hem x hem de y alanında çizilmesini sağlayan bir şekilde. İlk brush değişken bir y ölçek ekleyerek bunu: [ [x0, y0], [x1, y1] ]:

var brush = d3.svg.brush() 
    .x(x2) 
    .y(y2) 
    .on("brush", brush); 

Bu brush.extent() dönüş aşağıdaki çok boyutlu dizi yapar.

Bu çalışır
function brush() { 
    var extent = brush.extent(); 
    x.domain(brush.empty() ? x2.domain() : [ extent[0][0], extent[1][0] ]); 
    y.domain(brush.empty() ? y2.domain() : [ extent[0][1], extent[1][1] ]); 
    focus.select("path").attr("d", area); 
    focus.select(".x.axis").call(xAxis); 
    focus.select(".y.axis").call(yAxis); 
} 

, ancak bir yandan fırça değişken y ölçeği tanımlayarak, kullanıcı artık sürükleme ': Daha sonra odak grafik için x- ve y-alan yeniden tanımlanması brush() fonksiyonundaki bu verileri kullanır Orijinal şemada olduğu gibi, sadece batıdan doğuya sürüklenebilmekten ziyade odak çizelgesindeki kutular.

Esasen, sorum şu: Fırça alanının alanı yerine fırça alanının içine düşen değerler aralığı nasıl elde edilir? Bu mümkün mü? d3'ün fırça dokümantasyonu here'dir.

cevap

13

Bir çözüm buldum.

Orijinal veri kümemi filtrelemek için fırça filtrelenmiş x.domain alanını kullandım. Bu yeni filtre veri seti fırça dahilinde olması değerlere sahiptir:

// Use x.domain to filter the data, then find the max and min duration of this new set, then set y.domain to that 
    x.domain(brush.empty() ? x2.domain() : brush.extent()); 
    var dataFiltered = data.filter(function(d, i) { 
    if ((d.date >= x.domain()[0]) && (d.date <= x.domain()[1])) { 
     return d.duration; 
    } 
    }) 
    y.domain([0, d3.max(dataFiltered.map(function(d) { return d.duration; }))]); 

Son olarak, x-ekseni gibi y-ekseni yeniden çizmek için emin olun:

focus.select("path").attr("d", area); 
focus.select(".x.axis").call(xAxis); 
focus.select(".y.axis").call(yAxis); 
+3

Mükemmel cevap! Grafiğin kodunun içine doğru düşebildi, şerefe. – fundead

0

daha kısa bir olasılık şöyle senin brush.extent() üzerinde d3.scale.invert() kullanmak olacaktır: Ancak

var domainExtent = brush.extent().map(function(d){return scale.invert(d);}); 
var filteredData = data.filter(function(d){return ((d <= domainExtent[1]) && (d >= domainExtent[0]));}); 

, şimdi d3kazanmıştır tarafından, tasarımla sadece Doğu/Batı yönünde fırçalamaya izin veriyor.

İlgili konular