2016-09-21 20 views
5

Tôi đang sử dụng d3.js v4. Tôi hiện đang triển khai thu phóng có lập trình. Điều này Panning and Zooming Tutorial đã giúp rất nhiều. Zoom của tôi hoạt động với bánh xe cuộn, nhưng tôi muốn tạo các nút để thu phóng. Tôi biết điều cần thiết để phóng to và thu phóng là bản dịch [tx, ty] và hệ số tỷ lệ k. Tôi đang sử dụng thời gian cho trục x của tôi. Tôi đã quản lý để có được tx và hệ số tỷ lệ của k, bằng cách nhận giá trị pixel của p1 (point 1)p2(point 2) trên trục x và sau đó sử dụng các giá trị đó để lấy k (Hệ số tỷ lệ). Giống như ví dụ:Số phát hành w/Thu phóng có lập trình v4

var k = 500/(xScale(p2) - xScale(p1)); //500 is desired pixel diff. between p1 and p2, and xScale is my d3.scaleTime() accessor function. 
// for this zoom i just want the first value and last value to be at scale difference of the entire width. 

Sau đó, tôi tính toán tx của thành viên này:

var tx = 0 - k * p1; 

Sau đó ăn nó sang một d3.zoomIdentity() và rescaling xdomain tôi. Tôi đã tạo một nút để thu nhỏ lại. Vấn đề là khi tôi phóng to và sau đó cố gắng sử dụng nút để thu nhỏ, nó thu nhỏ nhưng co lại trục x. Tôi dường như không thể tìm ra lý do tại sao nó thu hẹp trục x thay vì thu nhỏ lại chính xác.

My JSFiddle

https://jsfiddle.net/codekhalifah/Lmdfrho7/2/

Những gì tôi đã cố gắng

Mã My

Sau khi bánh xe zoom được áp dụng tôi chạy chức năng này:

function zoomed() { 
     if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush 
var t = d3.event.transform; 
console.log(t); 
console.log(xScale.domain()); 
xScale.domain(t.rescaleX(x2).domain()); 
usageAreaPath.attr("d", area); 
usageLinePath.attr('d',line); 
weatherAreaPath.attr('d',weatherChart.area); 
focus.select(".axis--x").call(xAxis); 
focus.selectAll('.circle') 
    .attr('cx', function(d) { return xScale(getDate(d)); }) 
    .attr('cy', function(d) { return yScale(d.kWh); }) 
    .attr("transform", "translate(0," + 80 + ")"); 

     ... other non related items 
    } 

Các zoom hoạt động đúng, nhưng sau khi phóng to và sau đó tự cố gắng để phóng to vị trí trở lại bình thường tôi muốn. tay nút zoom chức năng My

function programmaticZoom(){ 
var currDataSet = usageLinePath.data()[0], //current data set 
     currDataSetLength = currDataSet.length,//current data set length 
     x1 = currDataSet[0].usageTime, //getting first data item 
     x2 = currDataSet[currDataSetLength-1].usageTime, //2nd data item 
     x1px = xScale(moment(x1)), //Get current point 1 
     x2px = xScale(moment(x2)); // Get current point 2 

     // calculate scale factor 
     var k = width/(x2px - x1px); // get scale factor 
     var tx = 0 - k * x1px; // get tx 
     var t = d3.zoomIdentity.translate(tx).scale(k); //create zoom identity 

     xScale.domain(t.rescaleX(window.x2).domain()); 
     usageAreaPath.attr("d", area); 
     usageLinePath.attr('d',line); 
     weatherAreaPath.attr('d',weatherChart.area); 
     focus.select(".axis--x").call(xAxis); 
     focus.selectAll('.circle') 
      .attr('cx', function(d) { return xScale(getDate(d)); }) 
      .attr('cy', function(d) { return yScale(d.kWh); }) 
      .attr("transform", "translate(0," + 80 + ")"); 

} 
+0

chỉ để rõ ràng; bạn muốn nút thu phóng của mình luôn thu phóng lại chế độ xem ban đầu mặc định? – Hamms

+0

@Hamms Vâng tôi muốn thực sự có thể phóng to các cấp độ khác nhau. Đây chỉ là cấp độ thử nghiệm đầu tiên của tôi. Nhưng trên Timescale tôi muốn thu phóng từ xem tháng, để xem tuần, đến một ngày, đến giờ, đến 15 phút. Mức độ thử nghiệm đầu tiên của tôi chỉ là trở lại để nhìn thấy tháng. – inspired

+0

@Hamms bất kỳ ý tưởng nào? – inspired

Trả lời

3

Tôi đã nhìn vào điều này cho một chút thời bây giờ, và tôi đã nhận nó loại làm việc, có một điều tôi không thể tìm ra nhưng bạn có thể có thể kể từ khi bạn dường như quen thuộc hơn với d3 hơn tôi. Trong hàm programmaticZoom() của bạn, tôi nhận thấy rằng tx là độ lệch cho vị trí bắt đầu của biểu đồ và k là tỷ lệ. Sử dụng này, tôi đã thay đổi khối:

var k = width/(x2px - x1px); // get scale var tx = 0 - k * x1px; // get tx var t = d3.zoomIdentity.translate(tx).scale(k);

để

var k = 1; var t = d3.zoomIdentity.scale(k);

Đầu tiên, khi k = 1.0, biểu đồ sẽ phù hợp trong cửa sổ một cách hoàn hảo. Lý do tôi tin rằng việc đặt k thành giá trị cũ của nó sai là khi bạn tăng giá trị k sao cho k > 1.0, nó trải rộng chiều rộng của biểu đồ qua màn hình.Nội dung trên biểu đồ phải được điều chỉnh sao cho có thể chiếm nhiều không gian trên biểu đồ nhất có thể, trong khi vẫn nằm trong giới hạn của màn hình. Với k < 1, đó là những gì sẽ xảy ra với width/(x2px - x1px);, biểu đồ co lại ít hơn kích thước của màn hình. Điều chỉnh như thế này sẽ chỉ làm cho nội dung của đồ thị phù hợp với mức tối đa có thể trong biểu đồ, nhưng vì biểu đồ nhỏ hơn màn hình, nó sẽ được điều chỉnh để vừa với đồ thị bị thu hẹp và xuất hiện nhỏ hơn màn hình.

Tôi đã loại bỏ tx hoàn toàn vì bù trừ vị trí bắt đầu đồ thị. Khi đồ thị được phóng to, chiều rộng của nó được kéo dài qua màn hình. Nó có ý nghĩa để bù đắp ở đây bởi vì bạn cần phải có bù đắp của bạn bằng nơi bạn muốn bắt đầu xem đồ thị, và cho phép các bộ phận bạn không cần phải vẫn còn tắt của màn hình. Trong trường hợp bạn phóng to hết cỡ, biểu đồ kích thước của màn hình, vì vậy bù trừ sẽ làm cho biểu đồ của bạn không bắt đầu ở đầu màn hình và thay vào đó đẩy một phần của nó ra khỏi màn. Trong trường hợp của bạn, với k đã thu hẹp biểu đồ, bù đắp sẽ làm cho biểu đồ bị thu hẹp xuất hiện ở giữa màn hình. Tuy nhiên nếu đồ thị không bị thu hẹp, phần bù sẽ đẩy một phần đồ thị ra khỏi màn hình.

Bằng cách thay đổi điều đó, nút thu phóng xuất hiện để hoạt động, tuy nhiên vẫn có sự cố. Trong chức năng zoomed(), bạn đặt var t = d3.event.transform;. d3.event.transform chứa các giá trị của k, x, and y cần phải tương ứng là 1, 0, and 0 khi thu nhỏ hoàn toàn. Tuy nhiên, tôi không thể thay đổi các giá trị này trong hàm programmaticZoom()d3.event.transform chỉ tồn tại sau khi sự kiện được kích hoạt, cụ thể là bánh xe chuột. Nếu bạn chỉ có thể nhận các giá trị này là k = 1, x = 0, y = 0 khi nút thu phóng được nhấp, sự cố phải được khắc phục hoàn toàn.

Hy vọng rằng đã giúp một số, tôi không phải rất quen thuộc với d3 nhưng điều này sẽ giải quyết hầu hết các vấn đề của bạn và hy vọng cung cấp cho bạn một ý tưởng về những gì đã xảy ra sai.

Các vấn đề liên quan