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.
Related
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'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.
I have a large dataset in an array which translates into about a million 6-pixel wide bars,
Given that about 130 bars fit into 800 pixels of screen, I need to only display a portion of the data at a time. Then, when the user pans the chart, new data will be added and non-visible data will be removed. The user could pan right or left so data need to be able to enter and exit from both sides of the chart.
I feel like the solution involves D3's enter and exit, but I'm unsure how to implement it.
One idea I've had is to use Array.prototype.concat and redraw on pan. Another idea would be to use Array.prototype.slice. I hope those are fast enough.
Any examples?
There are no examples that I'm aware of. Roughly, you would need to do the following.
Draw the initial bar chart. Pass in only the data you'll display (i.e. the first 130 data points if your screen is 800px wide).
On pan, get the translation for the pan. The x translation corresponds to a certain number of bars. Take off this many data points from the beginning of your data array and add that many to the end.
Pass that new data array to D3 and redraw. This tutorial should give you some pointers. Remember to pass a key function to .data() so it knows how to match data to DOM elements.
Similar thing on subsequent pans. Figure out how many bars have been panned and modify the data array accordingly (e.g. using slice and concat -- doesn't matter that much). Redraw the bars.
The concept is very similar to what's done in the tutorial I've linked to, except that the redraw isn't triggered by a timer, but by the pan event.
There are fundamentally two ways to do this. One is that you draw all 1M bars using svg and rely on svg's built in panning. The other is that you draw 130 bars and redraw each time the user pans. enter() and exit() are useful for doing things to data elements in your set that are entering or exiting the scene since the last time it rendered. (d3 determines which elements are
"new" by calling a predicate function on each element. The function has a default but can be user supplied.) You don't actually have to use them here unless you want to be fancy. You can just selectAll the rects from last draw, and .data() them with your new data, and supply the usual calls for drawing rects.
I have a map of counties in a state.
I am using the code found here http://bl.ocks.org/mbostock/2206590 to implement zooming on my map.
The original example works like this:
This works well enough, the user clicks on a state and it is zoomed and centered using the state centroid. Is it possible to use the mouse location as the point about which to zoom? It would seem easy enough, but I'm not sure how to get the mouse coordinates.
Use d3.event.x and d3.event.y instead of the computed centroid. See here.
I am learning d3js and trying to incorporate zooming/panning features on a graph, however on the initial zoom event it jumps to a random spot and zooms in. After that, the zooming and panning work as expected. Why is the initial event moving the starting point and adjusting the scale oddly?
Code and example here: bl.ocks.org/dbaileychess/7570631
This is because the zoom behaviour is attached to a different element than the one you're zooming. It determines the position of the mouse cursor relative to its own position and passes that information to the callback. If you're zooming a different element, the relative coordinates are no longer correct.
To fix, add the offset between the elements that the zoom behaviour is attached to and the elements you're zooming to the translation. This question has come up a number of times already, see e.g. here.