2012-05-02 29 views
9

Zaimplementowałem prosty wykres liniowy D3.js, który można powiększać i przesuwać. Opiera się na doskonałym przykładzie Stephena Bannascha: here.Ograniczanie domeny podczas powiększania lub przesuwania w D3.js

Domeną moich danych jest [0, n] w wymiarze x.

Jak ograniczyć powiększanie i przesuwanie do tej domeny przy użyciu wbudowanego zoomu (np. Za pomocą kółka myszy)?

Chcę uniemożliwić użytkownikom panoramowanie przeszłości 0 na dolnym końcu lub n na górnym końcu, na przykład nigdy nie powinni widzieć ujemnych wartości na osi X, i chcą ograniczyć powiększanie do tego samego okna .

Przykłady, które znalazłem na podstawie pracy Jasona Daviesa przy użyciu zakresu ([...], [...], [...]) wydają się już nie działać w wersji 2.9.1. Niestety, zachowanie zoomu jest obecnie jedną z niewielu funkcji, których nie udokumentowano w znakomitej dokumentacji interfejsu API.

Wszystkie wskaźniki są mile widziane.

PS. Opublikowałem to samo pytanie na liście adresowej D3.js, ale nie otrzymałem odpowiedzi: https://groups.google.com/d/topic/d3-js/w6LrHLF2CYc/discussion. Przepraszamy za cross-posting.

Odpowiedz

0

Po prostu musisz ograniczyć domenę po przerysowaniu. Poniższy kod zapobiegnie pomniejszeniu wykresu poza jego początkowe domeny (używane w http://bl.ocks.org/1182434).

SimpleGraph.prototype.redraw = function() { 
    var self = this; 
    return function() { 

    self.x.domain([Math.max(self.x.domain()[0], self.options.xmin), Math.min(self.x.domain()[1], self.options.xmax)]); 

    self.y.domain([Math.max(self.y.domain()[0], self.options.ymin), Math.min(self.y.domain()[1], self.options.ymax)]); 

    .... 
+1

Wiem, że ten wpis jest stary, ale dla Twojej wiadomości: link, który umieściłeś, pozwala mi pomniejszać zawartość i przesuwać ją do moich serc. (Chrome 29.0) – SgtPooki

+0

Twój kod działa na moim własnym wykresie. Twoje zdrowie. – SgtPooki

+1

Wykres jest powiększany podczas panoramowania za pomocą tego przykładu. –

6

Niestety, rozwiązanie wysłane przez Bill zrobił tylko pół trick: Chociaż rzeczywiście hamują panoramowanie, powoduje wykres zakłóceniem jeśli stosowany jest zoom. Zwykle nie ma możliwości powrotu do prawidłowo ustawionego i umiejscowionego wykresu.

W następującej wersji zachowywane są proporcje osi, nawet jeśli są przewijane do granic.

Gdy tylko skalowanie osiągnie 100%, domeny skal zostaną przywrócone do pierwotnej pozycji. Gwarantuje to prawidłowe pozycjonowanie, nawet jeśli kroki pośrednie zwrócą nieprawidłowe parametry dla osi.

Chociaż nie jest doskonały, mam nadzieję, że ten skrypt pomoże komuś, dopóki d3 (re) nie wdroży tej funkcji.

# x and y are the scales 
# xAxis and yAxis are the axes 
# graph is the graph you want attach the zoom to 

x0 = x.copy() 
y0 = y.copy() 

successfulTranslate = [0, 0] 

zoomer = d3.behavior.zoom() 
    .scaleExtent([1,2]) 

onZoom = -> 
    ev = d3.event # contains: .translate[x,y], .scale 
    if ev.scale == 1.0 
    x.domain x0.domain() 
    y.domain y0.domain() 
    successfulTranslate = [0, 0] 
    else 
    xTrans = x0.range().map((xVal) -> (xVal-ev.translate[0])/ev.scale).map(x0.invert) 
    yTrans = y0.range().map((yVal) -> (yVal-ev.translate[1])/ev.scale).map(y0.invert) 
    xTransOk = xTrans[0] >= x0.domain()[0] and xTrans[1] <= x0.domain()[1] 
    yTransOk = yTrans[0] >= y0.domain()[0] and yTrans[1] <= y0.domain()[1] 
    if xTransOk 
     x.domain xTrans 
     successfulTranslate[0] = ev.translate[0] 
    if yTransOk 
     y.domain yTrans 
     successfulTranslate[1] = ev.translate[1] 
    zoomer.translate successfulTranslate 

graph.select('g.x.axis').call(xAxis) 
graph.select('g.y.axis').call(yAxis) 
drawBars() 

zoomer.on('zoom', onZoom) 

# ... 
graph.call(zoomer) 
+1

Prawie idealnie. Problem z tym związany polega na tym, że nie działa on podczas operacji powiększania. Jeśli zbliżasz się do zbliżonego limitu, ustaw kursor na lewej krawędzi widocznego obszaru i pomniejsz: Prawy brzeg widocznego obszaru przekroczy oczekiwany limit. Uważam, że aby uzyskać kompletne rozwiązanie, zamiast po prostu zaakceptować/odrzucić zmiany w tłumaczeniu, trzeba pójść w drugą stronę. Z limitów domeny obliczyć prawny zakres translacji i ograniczyć wartości translate. – mdaoust

Powiązane problemy