2013-05-22 10 views
10

Zastanawiałem się, czy mógłbyś mi pomóc z follwoing D3js Zoom i funkcjonalności Pan w poniższej skrzypce: http://jsfiddle.net/moosejaw/nUF6X/5/D3 Pan zoom przelewowy

Mam nadzieję, że kod (choć nie wielki) jest prosta.

Mam wykres, który ma całkowitą długość chromosomu przez całkowitą długość chromosomu. Wartości tick są indywidualnymi długościami (sumami) każdego chromosomu. Tiki są sformatowane tak, aby były nazwą chromosomów (aby wyglądały ładnie dla użytkownika końcowego).

Problemy, mam to:

  1. oś X i oś Y etykiety rozciąga się na zewnątrz obszaru wykresu. Kiedy nie dostarczam wyraźnie wartości kleszcza, etykiety "znikają" tak, jak powinny. Zobacz:

    var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left") 
    .tickValues(tickValues) 
    .tickFormat(function(d) { 
        var ret = bpToChrMBP(d); 
        return ret.chr; 
    }); 
    
  2. Jak mogę zapobiec osi X, aby nie przesuwać w lewo przed wartością minimalną? Nie przesuwaj w prawo poza maksymalną wartość? Zdarza się to niezależnie od tego, czy jestem powiększony. (Taka sama dla osi Y, z wyjątkiem góry i dołu).

  3. Czy istnieje sposób na wycentrowanie etykiet osi między znacznikami. Znaki podziałki nie są równomiernie rozmieszczone. Próbowałem użyć podziału na mniejsze znaczniki, ale to nie dzieli poprawnie znaczników.

Każda pomoc będzie bardzo ceniona!

Matt

Odpowiedz

7

Ten Fiddle rozwiązuje większość problemów: http://jsfiddle.net/CtTkP/ Wyjaśnienia są poniżej:

  • Nie jestem pewien co masz na myśli przez wykraczającym poza obszar wykresy. Czy etykiety powinny być ins z ? Jeśli masz na myśli, że na panoramowanie, etykiety wykraczać poza osią, problem może być rozwiązany za pomocą dwóch bardziej clip-path s rozważnie, choć nie pozwala na wdzięku blaknięciem wartości, które svg.axis tłumaczenia zapewniają:
var clipX = svg.append("clipPath") 
     .attr('id', 'clip-x-axis') 
     .append('rect') 
     .attr('x', 0) 
     .attr('y', 0) 
     .attr('width', width) 
     .attr('height', margin.bottom); 

svg.append("g") 
    .attr("class", "x axis") 
    .attr('clip-path', 'url(#clip-x-axis)') 
    .attr("transform", "translate(0, " + height + ")") 
    .call(xAxis); 

// ... 

var clipY = svg.append("clipPath") 
     .attr('id', 'clip-y-axis') 
     .append('rect') 
     .attr('x', - margin.left) 
     .attr('y', 0) 
     .attr('height', height) 
     .attr('width', margin.left); 

svg.append("g") 
    .attr("class", "y axis") 
    .attr('clip-path', 'url(#clip-y-axis)') 
    .call(yAxis); 
  • aby zapobiec rozszerzeniu panoramowanie poza wartościami, trzeba będzie ręcznie ograniczyć translate dla zoom:
function zoomed() { 

    var trans = zoom.translate(), 
     scale = zoom.scale(); 

    tx = Math.min(0, Math.max(width * (1 - scale), trans[0])); 
    ty = Math.min(0, Math.max(height * (1 - scale), trans[1])); 

    zoom.translate([tx, ty]); 

    svg.select(".x.axis").call(xAxis); 
    svg.select(".y.axis").call(yAxis); 

    // ... 

Nie pozwoli to na przesuwanie wykresu poza granice.

  • Jak wyraźnie przesłanianie tickValues można dostrojenia wartości ich centrum:
var tickValues2 = []; 
tickValues.forEach(function (t, idx) { 
    if (idx < tickValues.length - 1) { 
     tickValues2.push((t + tickValues[idx + 1])/2); 
    } 
}); 

Wtedy zamiast korzystania tickValues dla xAxis i yAxis użyć tickValues2.

+0

Tak ... Zgadzam się, że ścieżka klipu nie zapewnia tej samej funkcjonalności co oś, ale jest najlepszą alternatywą/obejściem. Dziękuję za rozwiązanie ... Wiedziałem, że czegoś brakuje! – mattjvincent

+0

Super rozwiązanie. Działa jak marzenie. –

2
  1. jest problem, że ustawiasz tickValues ręcznie, zamiast pozwolić X i Y skala zrobi to za Ciebie. Spróbuj skomentować: // .tickValues(tickValues)

    var x = d3.scale.linear(). RangeRound ([0, szerokość]) .domena (d3.extent (tickValues));

    var OśX = d3.svg.axis() .scale (x) .orient ("dolnej") // .tickValues ​​(tickValues) .tickFormat (funkcja (d) { var retencji = bpToChrMBP (d); return ret.chr; });

Szybka i brudna poprawka umożliwiająca ustawienie parametru tickValues ​​jawnie może definiować ścieżkę obcinania dla każdej osi.

Nie potrzebujesz również funkcji make_x_axis (to samo dotyczy osi y). Sprawdź tę zoomable przykład Scatterplot: http://bl.ocks.org/ameliagreenhall/raw/d30a9ceb68f5b0fc903c/

  1. Aby uniemożliwić przesuwanie w lewo/w prawo obok odcięcia będzie trzeba ponownie wdrożyć d3.behavior.zoom().Teraz jest funkcja o nazwie mousemove który wywołuje translateTo i ta funkcja nie posiada limitu:

    funkcji translateTo (P, L) { l = punkt (L); tłumaczyć [0] + = p [0] - l [0]; tłumaczyć [1] + = p [1] - l [1]; }

  2. Można spróbować gry z dx i dy atrybutów podczas definiowania osi.

+0

Dziękuję za udzieloną odpowiedź, ale to nie odpowiada ani nie naprawia moich pytań/problemów. Mogę zrobić wykres rozproszenia i powiększyć go. To nie problem. Problem polega na ograniczeniu panoramowania po powiększeniu. – mattjvincent