The problem with the software increase v4

I am using d3.js v4 . I am currently implementing software zoom. This Panoramic and Scaling tutorial really helped. My zoom works with a spinning wheel, but I want to create buttons for the zoom. I know what is necessary for scaling and panning - this is the translation of [tx, ty] and the scale factor k . I am using the timeline for the x-axis axis. I managed to get tx and the scale factor k , getting the pixel value p1 (point 1) and p2(point 2) along the x axis, and then using these values โ€‹โ€‹to get k (scaling factor). For instance:

 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. 

Then I compute tx as follows:

 var tx = 0 - k * p1; 

Then load it into d3.zoomIdentity() and rescale my xdomain. I created a button to enlarge. The problem is when I zoom in and then try to use the button to zoom out, it scales, but reduces the x axis. I canโ€™t understand why its reduction of the x axis instead of the correct scaling.

My jsfiddle

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

What i tried

My code

After applying wheel scaling, I run this function:

  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 } 

Scaling works correctly, but after scaling, then manually try to change the normal position that I want. Manual zoom function

 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 + ")"); } 
+5
source share
1 answer

I looked at this for a while, and it worked for me, and one thing I cannot understand, but you may be able to, as you seem to be more familiar with d3 than me. In your programmaticZoom() function, I noticed that tx is the offset for the beginning of the start of the graph, and k is the scale. Using this, I changed the block:

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

to

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

Firstly, when k = 1.0 , the graph will fit perfectly in the window. The reason I believe that setting k to its previous value was incorrect is because when you increase the value of k , so that k > 1.0 , it stretches the width of the graph behind the screen. The content on the graph should be adjusted so that it can take up as much space on the graph as possible, but still within the screen. With k < 1 , what happens with width / (x2px - x1px); , the graph is reduced to screen size. Such a setting will only make the contents of the graph suitable for making maximum use of it in the graph, but since the graph is smaller than the screen, it will be adjusted to fit the smaller graph and appear smaller than the screen.

I completely got rid of tx because it offsets the beginning of the chart. When the graph is enlarged, the width will be stretched across the screen. It makes sense to compensate for this, because you need your offset to be equal to where you want to start viewing the chart, and allow parts that you don't need to leave on the screen. In the case when you zoom in, the graph is the size of the screen, so shifting will cause your graph to not start at the beginning of the screen and instead pop out part of the screen. In your case, when k already shortening the graph, the offset causes a truncated graph to appear in the middle of the screen. However, if the graph has not been shortened, the offset will push part of the graph away from the screen.

By changing this, a zoom out button appears, but the problem still remains. In the zoomed() function, you set var t = d3.event.transform; . d3.event.transform contains the values k, x, and y , which should be 1, 0, and 0 respectively, with a complete decrease. I cannot change these values โ€‹โ€‹in the programmaticZoom() function, though, since d3.event.transform exists only after the event has been fired, namely the mouse wheel. If you can get these values k = 1, x = 0, y = 0 only when you click the zoom button, the problem should be fully fixed.

Hope this helps some, I am not very familiar with d3, but this should solve most of your problem and hopefully give you an idea of โ€‹โ€‹what is going wrong.

+3
source

All Articles