2016-09-08 25 views
8

Tôi đang di chuyển mã d3 của tôi từ v3 sang v4 và gặp sự cố tương đương với thuộc tính d3.zoom.x, d3.zoom.y.d3v4 - phóng to (Tương đương với d3.zoom.x)

Dưới đây là một phần ngắn của mã, bao gồm các yếu tố quan trọng nhất:

  this.init = function(obj, def) { 

      /* X-axis */ 
      x = d3.scaleTime() 
       .range([0, width]); 


      xAxis = d3.axisBottom(x) 
       .ticks(ticks); 

      svg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0," + height + ")"); 

      /* Y-axis */ 
      for (var i = 0; i < 1; i++) { 
       // Returns the y and yAxis as arrays 
       createYAxis(i); 
      } 

      initZoom(); 

     }; 
      // Zoom trigger 
      var drawUpdXY = function(){ 
       setPause(true); 
       drawUpd(); 
       zoomY.y(y[0]); 
       zoomX.x(x); 


      zoom = d3.zoom() 
       .on("zoom", drawUpdXY); 

      zoomX = d3.zoom() 
       .on("zoom", drawUpdX); 

      zoomY = d3.zoom() 
       .on("zoom", drawUpdY); 
      };  

Tôi đã cố gắng sử dụng này để thay thế "zoom.x (x); zoom.y (y [0]) "

 xAxis.scale(d3.event.transform.rescaleX(x)); 
     yAxis[0].scale(d3.event.transform.rescaleY(y[0])); 

Tuy nhiên, chúng chỉ giải phóng trục, để dữ liệu không được khuếch đại.

+0

Do đây là khá cũ, đã bao giờ bạn tìm một giải pháp? Tôi bị mắc kẹt trên cùng một vấn đề. – jmk

+0

Đã không tìm thấy giải pháp cho ngày này - tôi quyết định đợi cho đến khi có cộng đồng lớn hơn cho v4. –

+0

** _ tl; dr: _ Nó có thể giúp tái cấu trúc refactor của bạn, xem các liên kết để đi bộ qua lý do tại sao và làm thế nào, và một ví dụ của nó làm việc ** Tôi đang làm việc trên một dự án tương tự đang cố gắng thực hiện một panning/phóng to hệ tọa độ lưới tọa độ trong d3v4 và React. Trên đường đi, tôi đã sử dụng [bài viết này giải thích cách thu phóng/panning mới hoạt động] (http://emptypipes.org/2016/07/03/d3-panning-and-zooming/), và khiến tôi nhận ra rằng mình phải suy nghĩ lại cách tôi cấu trúc refactor của tôi. Sau đó, tôi tạo ra [codepen của những gì tôi đã cố gắng để thực hiện] (https://codepen.io/mduleone/pen/wJxrbj) trong d3 tinh khiết. Vẫn đang làm việc ở phía React. – mduleone

Trả lời

0

Tôi không thể nói về cách xử lý d3 v3 zoom, vì gần đây tôi mới bắt đầu làm việc với D3, nhưng mã bên dưới sẽ giúp bạn chỉ đúng hướng. Tôi sẽ cố gắng hết sức để mô tả những gì đang diễn ra. Tôi mời chỉnh sửa, cải tiến và giải thích tốt hơn.

Đầu tiên, một MCVE

<html> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Energy Visualizer</title> 
 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 
    <script src="https://d3js.org/d3-color.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-interpolate.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> 
 
    <style> 
 
    body { 
 
     background-color: #4e5965; 
 
    } 
 
    </style> 
 
    </svg> 
 
</head> 
 

 
<body> 
 
    <div class="chart" /> 
 
    <script> 
 
    var svg = d3.select(".chart").append("svg") 
 
     .attr("width", 200) 
 
     .attr("height", 200); 
 

 
    var data = [{ 
 
     "x": 2, 
 
     "y": 8, 
 
     "color": "green" 
 
    }, { 
 
     "x": 4, 
 
     "y": 6, 
 
     "color": "red" 
 
    }]; 
 

 
    var width = svg.attr("width"); 
 
    var height = svg.attr("height"); 
 

 
    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]); 
 
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]); 
 

 
    var circles = svg.selectAll("circle") 
 
     .data(data) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("cx", function(d) { 
 
     return x_scale(d.x); 
 
     }) 
 
     .attr("cy", function(d) { 
 
     return y_scale(d.y); 
 
     }) 
 
     .attr("r", 5) 
 
     .attr("fill", function(d) { 
 
     return d.color 
 
     }); 
 

 
    var xAxis = d3.axisBottom(x_scale); 
 
    var yAxis = d3.axisRight(y_scale); 
 

 
    var x_axis = svg.append("g").call(xAxis); 
 
    var y_axis = svg.append("g").call(yAxis); 
 
    </script> 
 
</body> 
 

 
</html>

Đây chỉ là một âm mưu phân tán đơn giản với một vòng tròn màu đỏ và xanh lá cây. Bạn có thể thấy cách tôi đã chia nhỏ các thành phần của trục x và y. Điều này đi vào chơi với d3.zoom().

Tiếp theo, hãy thêm thành phần thu phóng.

<html> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Energy Visualizer</title> 
 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 
    <script src="https://d3js.org/d3-color.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-interpolate.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> 
 
    <style> 
 
    body { 
 
     background-color: #4e5965; 
 
    } 
 
    </style> 
 
    </svg> 
 
</head> 
 

 
<body> 
 
    <div class="chart" /> 
 
    <script> 
 
    var svg = d3.select(".chart").append("svg") 
 
     .attr("width", 200) 
 
     .attr("height", 200); 
 

 
    var zoom = d3.zoom() 
 
     .on("zoom", zoomed); 
 

 
    svg.call(zoom); 
 

 
    var data = [{ 
 
     "x": 2, 
 
     "y": 8, 
 
     "color": "green" 
 
    }, { 
 
     "x": 4, 
 
     "y": 6, 
 
     "color": "red" 
 
    }]; 
 

 
    var width = svg.attr("width"); 
 
    var height = svg.attr("height"); 
 

 
    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]); 
 
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]); 
 

 
    var circles = svg.selectAll("circle") 
 
     .data(data) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("cx", function(d) { 
 
     return x_scale(d.x); 
 
     }) 
 
     .attr("cy", function(d) { 
 
     return y_scale(d.y); 
 
     }) 
 
     .attr("r", 5) 
 
     .attr("fill", function(d) { 
 
     return d.color 
 
     }); 
 

 
    var xAxis = d3.axisBottom(x_scale); 
 
    var yAxis = d3.axisRight(y_scale); 
 

 
    var x_axis = svg.append("g").call(xAxis); 
 
    var y_axis = svg.append("g").call(yAxis); 
 

 

 
    function zoomed() { 
 
     var new_x_scale = d3.event.transform.rescaleX(x_scale); 
 
     var new_y_scale = d3.event.transform.rescaleY(y_scale); 
 

 
     x_axis.transition() 
 
     .duration(0) 
 
     .call(xAxis.scale(new_x_scale)); 
 

 
     y_axis.transition() 
 
     .duration(0) 
 
     .call(yAxis.scale(new_y_scale)); 
 

 
     circles 
 
     .attr("cx", function(d) { 
 
      return new_x_scale(d.x) 
 
     }) 
 
     .attr("cy", function(d) { 
 
      return new_y_scale(d.y) 
 
     }); 
 

 
    } 
 
    </script> 
 
</body> 
 

 
</html>

Ở đây, bạn có thể xem biểu đồ cho phép zoom-in, zoom-out và kéo trên cả hai trục. Tôi tin rằng bạn chỉ muốn thu phóng một trục, vì vậy trong trường hợp đó, chỉ giải phóng trục x và thành phần x của mỗi vị trí vòng tròn.

Một đoạn cuối làm những gì tôi nghĩ bạn muốn.

<html> 
 

 
<head> 
 
    <meta charset="UTF-8"> 
 
    <title>Energy Visualizer</title> 
 
    <script src="https://d3js.org/d3.v4.min.js"></script> 
 
    <script src="https://d3js.org/d3-color.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-interpolate.v1.min.js"></script> 
 
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script> 
 
    <style> 
 
    body { 
 
     background-color: #4e5965; 
 
    } 
 
    </style> 
 
    </svg> 
 
</head> 
 

 
<body> 
 
    <div class="chart" /> 
 
    <script> 
 
    var svg = d3.select(".chart").append("svg") 
 
     .attr("width", 200) 
 
     .attr("height", 200); 
 

 
    var zoom = d3.zoom() 
 
     .on("zoom", zoomed); 
 

 
    svg.call(zoom); 
 

 
    var data = [{ 
 
     "x": 2, 
 
     "y": 8, 
 
     "color": "green" 
 
    }, { 
 
     "x": 4, 
 
     "y": 6, 
 
     "color": "red" 
 
    }]; 
 

 
    var width = svg.attr("width"); 
 
    var height = svg.attr("height"); 
 

 
    x_scale = d3.scaleLinear().domain([0, 10]).range([0, width]); 
 
    y_scale = d3.scaleLinear().domain([0, 10]).range([0, height]); 
 

 
    var circles = svg.selectAll("circle") 
 
     .data(data) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("cx", function(d) { 
 
     return x_scale(d.x); 
 
     }) 
 
     .attr("cy", function(d) { 
 
     return y_scale(d.y); 
 
     }) 
 
     .attr("r", 5) 
 
     .attr("fill", function(d) { 
 
     return d.color 
 
     }); 
 

 
    var xAxis = d3.axisBottom(x_scale); 
 
    var yAxis = d3.axisRight(y_scale); 
 

 
    var x_axis = svg.append("g").call(xAxis); 
 
    var y_axis = svg.append("g").call(yAxis); 
 

 

 
    function zoomed() { 
 
     var new_x_scale = d3.event.transform.rescaleX(x_scale); 
 

 
     x_axis.transition() 
 
     .duration(0) 
 
     .call(xAxis.scale(new_x_scale)); 
 

 
     circles 
 
     .attr("cx", function(d) { 
 
      return new_x_scale(d.x) 
 
     }); 
 

 
    } 
 
    </script> 
 
</body> 
 

 
</html>

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