I have code that draws a square and plots points inside a canvas element. I use a d3.drag function to drag the square separate from the points and a d3.zoom function to zoom on BOTH the points and the square as well as pan both. The problem I'm having is two-fold:
Once zoomed, I sort of lose the ability to drag the square. Sort of in the sense that if you click around enough (typically the original spot of the square, not current), you can grab the square again.
Once I am able to grab the square again, the zoom renders to the very original zoom layer, not the current zoom.
Here is a jsFiddle
I found this answer that recommends adding:
square.on("mousedown", function() { d3.event.stopPropagation(); });
but have not had any luck.
TIA
Related
I have draw several polygons in a canvas. I am now interested in how to find the coordinates (vertices) of the selected polygon. I can find the selected polygon (region) using mouse coordinates, but I need to redraw it if it is selected, which is why I need its coordinates to do that.
A similar answer that I found so far is this one https://help.geogebra.org/topic/-solved-how-do-i-get-a-list-of-coordinates-from-a-polygon- using GeoGebra, but I am using HTML5 and JavaScript!
Once you draw something on a canvas, you can not get the coordinates of the object you drew unless you have some image processing algorithm.
Instead, you need need to keep the polygon object you drew on the canvas in memory and you need to define it's boundaries on the canvas.
This way, when the user clicks on the canvas, you simply get the mouse coordinates on the canvas and you calculate which polygon was clicked by checking where you drew your polygon and checking if the mouse clicks enters the boundaries of this polygon.
Sounds like you are trying to solve a couple different problems:
1) Figure out which polygon the user clicked. As was mentioned, if you are keeping an array of your polygons in memory, and can implement an isPointInPath method, then you can loop through your in-memory polygons and check if any of them were clicked. Don't forget that to get an accurate check, you may need to take your given "mouse x" and "mouse y" coordinates (from a click event, for example) and subtract the canvas's page X and Y coordinate.
(See the SO answer How do I get the coordinates of a mouse click on a canvas element? for more detail.)
2) Once you've determined the user has clicked polygon P, you want to redraw it. You should be able to redraw it no problem, by simply redrawing the same polygon using the same coordinates as before (for example, you could change your strokeStyle or fillStyle to a different color to represent the selection).
If you want to make the polygon larger and in the same position, that's a different question - basically, you need to translate the canvas to the center of the polygon, then scale the canvas, then draw your polygon. If this is new to you, there's a tutorial available at http://codetheory.in/canvas-rotating-and-scaling-images-around-a-particular-point/ (uses images instead of polygons, but same concept).
Note that if your polygon is complex, even determining the right point to scale around may be difficult. The question "what is the center of a complex polygon" has several different answers; a simple answer is to average all of the polygon's point's X and Y values (Center X = avg(X), Center Y = avg(Y)). If that doesn't look right, there are more complicated approaches available in another SO question, What is the fastest way to find the "visual" center of an irregularly shaped polygon? .
Hope this points you in the right direction!
I'm using d3js and SVG to resize and rotate rectangles, I capture the mouse events on handles that are positioned in each corner of the rectangle, there are two handles in each corner, one for resizing (square) and other to rotate (circle).
When I do the following process, the rectangle "jumps" from its location to another one:
Rotate (it means it's not more in zero degrees)
Resize (any direction)
Rotate again (here is when the shape "jumps")
The jump only occurs when the center of the rectangle is updated, using transform rotate from SVG.
One thing that gave me a lead was updating the rotation center while the shape is being resized, when I do this the shape starts to move to the final position where the "jump" would have placed it.
I can post code examples, it will take some time to do, but if helps to see the problem, no problems.
All I need is some direction from someone that already had this problem.
Edit:
I've made a Plunker with somewhat the current structure that I'm using in my project. All events controls are concentrated in the svgApp.directive.js.
Things I've noticed while developing this example:
The center of the element is not correctly calculated after the angle is not zero, this is my main issue;
If you apply the {{vm.model.image.transform.rotate}} to the ng-attr-transform attribute in the center <circle> element, you are going to notice how it always is in the correct center (the right circle - blue - is commented at the bottom of the main SVG);
I know this is not the perfect version of the tool, it still has some bugs, like the inversion of the mouse direction (resize/rotate handles) while rotated, but it's well documented and structured very close to how I'm working on the project.
The Plnkr: http://plnkr.co/edit/fXT0kZcRwJTPb7wQVHpg?p=preview
Any help with this problem will be very appreciated.
Is there any way to stop OL3 from only showing the points inside the viewport? Specifically when on a polygon for me. I have polygons being clipped because some points are outside the viewport and I need to zoom out in order to have the entire polygon displayed.
Figured it out - turns out you can make a square shaped polygon with 4 points fine, which I had done. But to avoid the problem I was having you need to add the first point again as a fifth point.
I have a regular grid with Pan+Zoom where I draw squares in subsequent orders, when a user click on a button, e.g.
However, if I zoom-in before adding a new item, it gets added to wrong position, i.e.
Demo of the issue http://jsbin.com/dewiq/2/edit
Any ideas?
You're mixing up two different ways of zooming in d3 -- zooming with scales ("semantic" zooming) and zooming with transforms ("geometric" zooming). See this answer for a detailed breakdown of the differences.
You've attached your scales to the zoom behaviour, so when you zoom or pan your scales get modified to reflect the change. However, you're only using that modification to redraw the axes, for the plot you're creating the zoom effect with a geometric transformation. That works until you try to redraw any of your plot (or, draw a new shape). When you do that, the modified scales and the transformed plot add together to double the zoom and pan effects, resulting in shapes that are out of position with the axes.
The solution is to simply do one or the other. Either connect your scales to the zoom behaviour, and then use those scales to redraw all your shapes after every zoom event; or use transformations -- but then your axes won't automatically change the tick spacing as you zoom in and out.
I have a problem, when zooming with a rectangle who drew on the chart, it should make a zoom into the selected area. The error occurs when I try to return me zooming out, this should work but for some reason this is locked and I can not return to the starting position.
Here is the code to perform the zoom with the rectangle, first pressing the shift key and click to draw down the area on which you need to perform zoom in.
http://jsfiddle.net/cristian540/VFqeV/8/
This is happening because you have set .scaleExtent([1, Infinity]), and when you zoom using a rectangle selection you aren't resetting the scale.
Perhaps you'd be better turning off .scaleExtent, since there is only a single scale value for d3.behavior.zoom whereas the zoom rectangle effectively has two (one for x- and one for y-).