I'm porting a D3 v3 graph widget that uses panning and zooming to v4 and got stuck on the zooming changes. The zooming API in v4 uses a different model where zooming is managed on the elements rather than a general zoom transform.
I have a lot of datapoints that get plotted on a timescale that initially intentionally clumps the datapoints very close to each other, and the user can use zooming to drill deeper into the data for more detail. In v3 when zooming in the svg line automatically adjusted with the new scale however in v4 when applying zoom scaling on the svg line I get an increases the thickness of the svg line elements rather than resolving more detail (and keeping the line thickness constant). I have no problems with scaling the x or y axis.
This behavior is expected with a scale function but not what I want. I've read the new API for zoom and can't work out what zoom function to use that would give me v3 behaviour where zooming in shows more detail in the line graph and doesn't scale up the line thickness.
In v3 D3 would zoom the svg line with the following in the zoom event handler, however this won't work in v4.
chart.select("#seriesLine" + i).attr("d", series[i].d3Line(series[i].data))
Its been a while since I wrote the original graphing widget so possibly I'm just not remembering how to setup D3 correctly, but I think I'm just not groking the new zoom function, and there are no similar zoom examples to learn from.
Any tips?
Related
I am trying to figure out how to create different zoom factors on the X- and Y-axis in d3. It seems to be created with a single zoom-factor for both axis, and basically I would like to know if there is a way to separate them.
The basics is simple enough: There is excellent support in d3 for an even zoom-effect on x- and y-axises. It is also easy to turn off the zoom for one axis. But I cant find a way to create this intermediate effect. The goal is to have the y-axis zoom 10 times more than the x-axis for each mouse wheel zoom-event.
I have no actual code to show, since I dont know if it is possible. Perhaps a useful hint, is that I work with D3 version 5. The usual, more or less standardized zoom code is used.
I have a graph that has zoom and pan from this example code: (https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172). My graph is almost exactly like that one, except with different data points, and circles noting each data point.
Now I'm trying to allow for a mouseover function that will display the data for each data point when hovering. However, the zoom behavior is taking precedence, and I'm not sure how to switch the behaviors so that the zoom is listening and the mouseover/hover happens (first, maybe?).
I'm trying to use this code sample since it has both the hover and zoom behaviors: (https://bl.ocks.org/lorenzopub/013c0c41f9ffab4d27f860127f79c5f5)
Adding
d3.select("#rect").style("pointer-events", "all")
Have solved my problem.
I think the mouse events where not propagated properly.
I am trying to implement zooming and Linking&Brushing in Bubble chart.
Aplaying linking and brushing while data are still on initial position works just fine. Also zooming alone works just fine.
But if I zoom the chart and then i try to select the data, then it's not selecting the right ones.
Example:
Brushing while zooming is not applied
Bushing after zooming was applied
I am using brush.extent() to get the position of brushing space. Somehow the position of dots is never updated, while zooming.
I can take under consideration the scale size while I am brushing. But I am asking if there is something which updates the dots position after zooming automatically. Or am I missing something as I am pretty new at using d3.js and also on visualization field.
If anyone is facing the same error, maybe my solution will be helful.
While brushing I add the translate values to the x and y coordinates.
d3.event.translate
I have a timeseries graph done using c3.js. When I zoom the graph the bars do not change the width and the x axis does not adopt accordingly. Is there anyway I can do that? I have tried making axis.x.tick.fit = false. The zoom in works perfectly then. But the groups of data in the graphs are getting overlapped. Any idea on what to do is welcome. Thankyou
I'm trying to build a stock chart with zooming functionality using D3.js
I'm looking to start with this example here and attempt to make the zoom feel more natural for a stock chart. A perfect example is this. So the difference as far as I understand is that zoomng and panning are both locked on the Y-axis, and the only way the Y-axis moves is to autmatically fill the price range of the currently visible data.
Another noticeable difference is that zooming does not zoom into the current position of the mouse like it does in the first example.
How can the example be adjusted to work more closely as the other chart? What is the pertitent code, how should it be changed?
Setting the zoom behaviour to not affect the y-axis is simple: just don't attach your y-scale to the zoom behaviour.
In the sample code you linked to, the zoom functionality is added in this line:
this.plot.call(d3.behavior.zoom()
.x(this.x)
.y(this.y)
.on("zoom", this.redraw() )
);
That creates a zoom behaviour object/function, links it to the graphs x and y scales, and tells it to call the function returned by this.redraw() after every zoom event. The zoom behaviour automatically changes the domain of the scales on zoom, and then the redraw function uses the modified zoom. If you don't give it a y scale to modify, then zooming won't affect the y domain.
Getting the y scale to automatically adjust to the given extent of the data is a little trickier. However, remember that the zoom behaviour will have automatically adjusted the domain of the x scale to represent the extent of visible data horizontally. You'll then have to get the corresponding slice of your data array and figure out the extent of y values from it, set your y domain accordingly, and then call the redraw function (remembering that this.redraw() just returns the redraw function, to call it within another function you'll need to use this.redraw()() ).
To have the zoom be independent of the mouse position, set a center point for the zoom behaviour.