2012-05-02 3 views
9

확대/축소 및 이동이 가능한 간단한 D3.js 선형 차트를 구현했습니다. 이는 Stephen Bannasch의 우수 사례 인 here을 기반으로합니다.D3.js에서 확대/축소 또는 패닝 할 때 도메인 제한

내 데이터의 도메인은 x 차원에서 [0, n]입니다.

내장 된 확대/축소 동작 (마우스 휠 이벤트 사용)을 사용하여 확대/축소 및 이동을이 도메인으로 어떻게 제한 할 수 있습니까?

사용자가 맨 아래쪽에서 0을 지나치거나 상단에서 n을 패닝하지 못하게하려는 경우 (예 : x 축에서 음수 값을 볼 수 없어서 동일한 창으로 확대/축소하는 것을 제한해야하는 경우) .

Jason Davies의 Extent ([...], [...], [...]) 작업을 기반으로 한 예제는 더 이상 버전 2.9.1에서 작동하지 않는 것 같습니다. 불행히도 확대/축소 동작은 현재 다른 뛰어난 API 문서에 설명되지 않은 몇 가지 기능 중 하나입니다.

모든 안내를 환영합니다.

추신. 동일한 질문을 D3.js 메일 링리스트에 올렸지 만 응답을 얻지 못했습니다 : https://groups.google.com/d/topic/d3-js/w6LrHLF2CYc/discussion. 교차 게시에 대한 사과.

답변

0

다시 그리기 할 때 도메인을 제한하기 만하면됩니다. 다음 코드는 그래프가 초기 도메인 (예 : 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

본인은이 게시물이 오래되었음을 알고 있습니다. 참고 : 참조하는 링크를 사용하면 내 마음대로 콘텐츠를 축소하고 이동할 수 있습니다. (Chrome 29.0) – SgtPooki

+0

코드가 내 자신의 그래프로 작동합니다. 건배. – SgtPooki

+1

이 예제를 사용하여 패닝하는 동안 그래프가 확대됩니다. –

6

슬프게도, 빌에 의해 게시 된 솔루션은 절반 속임수를 썼는지 : 그것은 참으로 패닝을 억제 않지만, 그것은 줌이 적용되는 경우 왜곡 그래프가 발생합니다. 그런 다음 적절한 비율의 배치 된 그래프로 돌아가는 것은 대개 불가능합니다.

다음 버전에서는 테두리로 스크롤하는 경우에도 축의 비율이 유지됩니다.

스케일링이 100 %에 도달하면 스케일의 도메인은 원래 위치로 재설정됩니다. 중간 단계가 축에 대해 잘못된 매개 변수를 반환하는 경우에도 올바른 위치 지정이 보장됩니다.

완벽하지는 않지만이 스크립트가 d3 (다시) 기능을 구현할 때까지이 스크립트가 도움이되기를 바랍니다.

# 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

거의 완벽합니다. 이 문제는 줌 동작 중에는 아무 효과가 없다는 점에서 문제가 있습니다. 오른쪽 한계 근처를 확대 할 경우 커서를 보이는 영역의 왼쪽 가장자리에 놓고 축소하면 보이는 영역의 오른쪽 가장자리가 예상 한도를 초과합니다. 번역에 대한 변경 사항을 단순히 수락하거나 거절하는 대신 전체 솔루션을 생각하면 다른 방향으로 가야합니다. 도메인 제한에서 변환의 유효 범위를 계산하고 변환 값을 제한하십시오. – mdaoust