2016-09-08 5 views
8

Я переношу свой код d3 с v3 на v4 и имеет проблемы с поиском эквивалента для свойств d3.zoom.x, d3.zoom.y.d3v4 - масштабирование (эквивалентно d3.zoom.x)

Вот короткая часть кода, в том числе наиболее важных элементов:

  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); 
      };  

Я пытался использовать это, чтобы заменить «zoom.x (х); zoom.y (у [0]) "

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

Однако они только изменяют масштаб оси, оставляя данные незамкнутыми.

+0

Поскольку это довольно старый, вы когда-нибудь найти решение? Я застрял в той же проблеме. – jmk

+0

Не найдено решений по сей день - я решил подождать, пока есть большая община для v4. –

+0

** _ tl; dr: _ Это может помочь реструктурировать ваш рефакторинг, увидеть ссылки для прохода через почему и как, и пример этого работает ** Я работаю над аналогичным проектом, пытающимся реализовать панорамирование/масштабирование системы координат сетки в d3v4 и React. По пути я использовал это [статья, объясняющую, как работает новое масштабирование/панорамирование) (http://emptypipes.org/2016/07/03/d3-panning-and-zooming/), и заставило меня понять, что мне пришлось переосмыслить, как я структурировал свой рефактор. Затем я создал этот код (код того, что я пытался сделать) (https://codepen.io/mduleone/pen/wJxrbj) в чистом d3. Все еще работает на стороне Реагента. – mduleone

ответ

0

Я не могу говорить о том, как d3 v3 обрабатывал масштабирование, так как я только недавно начал работать с D3, но приведенный ниже код должен указывать вас в правильном направлении. Я сделаю все возможное, чтобы описать, что происходит. Я предлагаю исправления, улучшения и лучшие объяснения.

Во-первых, 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>

Это только простой график рассеяния с красным и зеленым кругом. Вы можете увидеть, как я разбил компоненты оси x и y. Это вступает в игру с d3.zoom().

Затем добавим компонент масштабирования.

<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>

Здесь вы можете увидеть, что диаграмма позволяет увеличения масштаба, уменьшения масштаба и перетаскиванием по обеим осям. Я верю, что вам нужно только одноосное масштабирование, поэтому в этом случае только масштабируйте ось x и x-компонент каждой позиции кругов.

Один последний фрагмент, который делает то, что я думаю, вы хотите.

<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>

Смежные вопросы