I'm working on a project which involves having a pannable and zoomable d3.js graph. I've got it working mostly ok, however I've found a problem:
While testing on an iPad, I've found that some gestures can cause d3 to error -
TypeError: 'undefined' is not an object in the latest d3.js (not the .min version), line 1264 (which appears to be the start of function moved()...
It seems to occur when a zoom event starts partially outside the graph - e.g. one finger on the graph and one outside, then zoom. It may take a few tried in various places; I've not been able to find the exact one that triggers it.
I've copied the project and cut it down into a basic example, which is available at ---no longer available---.
Waterbug is installed, so when testing on an iPad (and possibly anything else that supports rotation) there is an error log console when rotated right.
Does this look like a bug in d3, or in my code?
Update
I've narrowed down the problem to a touch event which starts within the graph, but then extends outside. So, if you are panning the graph with one finger, then decide to zoom, but place the second finger outside of the graph, the error occurs. If the second finger is also within the graph, there is no issue.
Update 2
It appears the example at http://bl.ocks.org/mbostock/3892919 also suffers from the same isuse - see ---no longer available--- which is using the code provided, plus I've included Waterbug so rotating the device to the right (from vertical) will show the console.
The issue appears to be with the moved() function - line 1264 in v3.2.8 and line 1387 in v3.3.2.
Turns out it was a bug in d3 - see https://github.com/mbostock/d3/issues/1497 for details
Related
I've been trying to draw a network of streets. I used paths and images to perform this as you guys can see in the image :
I am also displaying labels on top of the images with some information about them. The problem is that the data source sometimes has overlapping traffic lights in the same coordinate. And as a result of that the labels get overlapped. I was wondering what's the best way to handle those overlaps in d3 v5? I've found some similar questions but none of them seem to work in d3 version 5.
This is one question that I looked at : D3js: Automatic labels placement to avoid overlaps? (force repulsion)
I guess I am looking for something similar, but something that would work with version 5?
Version and info
THREE.ObjectLoader2: 2.4.1
THREE.LoaderSupport.MeshBuilder: 1.2.1
THREE.LoaderSupport.WorkerSupport: 2.2.0
THREE.WebGLRenderer: 93
THREE.REVISION: 93
The problem
When I raycast an object in my scene, I found that it worked perfectly down to the pixel, until I moved the object. In my program I expload the scene, so I move all the objects, and child objects away from the center of the scene.
To easily visualise the issue instead of raycasting a single point at a mouse click, I opted to raycast the entire screen, this is what I get (Figure 1)
(Figure 1)
The reason for the gaps is because it took to long to raycast every pixel, so instead I raycasted every fourth. The reason for the gap in the middle is because I zoomed away from the original position.
Now, see what happens when I expload the object (Figure 2),
(Figure 2)
As you can see, there is almost a circle. Why is this?
What I've tried
I've tried many things across the internet, and came here when I could find no more.
I've tried a range of different models, some work differently to others, strangely enough. The lamborghini-aventador which was created in Blender works the strangest.
To see if it was a problem with the exploading code, I moved the object to the right. This is where things get interesting (Figure 3).
(Figure 3)
It looks as if my outlining I put on the object (the outlines are an EdgesGeometry) is behind, the actual object is in the middle, and the raycasts are further.
What I speculate
I suspect the issue is to do with scaling. So I tried removing all scaling I did in the code, however I got the same result, unfortunately.
Apologies if this is some noobie mistake, though I do hope it is :)
The code
For those who are adventurous enough to delve into my terrible code base, here it is (the majority of the code is inside demo.js):
github
Testing it
Press G to shoot the raycasts (will freeze for a bit), press X to expload, press S to unexpload. Standard orbit controls.
What I've found
Here are some of the links I have already found and tried on this issue:
https://threejs.org/docs/#api/core/Raycaster
Three.js Raycaster not detecting scene mesh
https://github.com/mrdoob/three.js/issues/1325 (Updating the matrix)
http://barkofthebyte.azurewebsites.net/post/2014/05/05/three-js-projecting-mouse-clicks-to-a-3d-scene-how-to-do-it-and-how-it-works (Followed step by step)
... and many more ...
Any ideas?
I think that your model might not have proper bounding boxes/spheres generated.
The circular shape could result from the rays passing the bounding sphere check of a bounding sphere that is too small.
You mention resizing/processing your geometries in some way... After you do that, try calling geometry.computeBoundingBox() and geometry.computeBoundingSphere() to rebuild boxes and spheres, and see if that helps?
edit: Apparently this problem was due to bounding boxes and spheres not being recomputed...
the fix was to:
scene.traverse( (o)=>if(o.geometry){o.geometry.computeBoundingBox();o.geometry.computeBoundingSphere();} );
I came across a problem today where diagrams I have created are not working in Firefox when created via getPointAtLength. Here is a fiddle showing the problem:
http://jsfiddle.net/xfpDA/9/
Note comments at the top of the javascript.
The relevant part of the SVG path is:
C189.5,423.237,266.965,390.696,266.965,390.696
This works perfectly in Chrome and IE, but Firefox skips right over the curve and just closes the path.
However, a tiny change to the curve is enough to fix the problem:
C189.5,423.236,266.965,390.696,266.965,390.696
^
Why does changing that value by a thousandth make the difference between a pretty curve and a broken SVG?
EDIT: That coordinate is not the only one that can be changed to 'fix' the problem, so it appears that Firefox does not play nicely with high-precision curve values.
Firefox is not able to calculate the length of the curve under some circumstances (e.g. delta=0/0). So the result for that path part is NaN/0/undefined and therefore is not added to the total length and the domain for getPointAtLength is smaller.
I've created an interactive hierarchical D3 partition based visualization for displaying portions of a network. The visualization works by allowing users to traverse levels in the binary tree and down to a leaf level of /24 subnets.
A functioning example visualization can be interacted with on bl.ocks.org, with source and data available to create the visualization provided in this Gist (not inlined due to size).
In general everything renders correctly, however after a transition the new position of some rect elements becomes corrupted. An example of which is seen in the following screen shot:
Thus far the corruption appears unpredictable, is apparently unrelated to the underlying data, and is fixed during the next transition. Sometimes clicking around triggers it, sometimes it doesn't.
What might be causing these visualization errors? At first I thought it to be a concurrency issue caused by an async call to multiple interactions at once, but debouncing doesn't seem to fix things. My next fear is that it is just too much data for D3 to handle, but that seems unlikely.
The issue occurs in both Chrome and Internet Explorer.
I have a javascript routine which is designed to flickering sun rays. The routine creates 'numRays' rays, then begins to overwrite the rays using globalCompositeOperation = 'copy' and drawing a transparent ray over the oldest ray.
You can see the program here:Sun Ray Page
JSFiddle.net code located here:JSFiddle Sun Rays (I'm not sure how to make it work on JSFiddle, so if someone can fix my fiddle, I'd appreciate that, too.)
(Note: I have left a yellow stroke around the erased rays for diagnostic purposes, so you can see them executed.)
The code works in Chrome and Firefox, however, in IE9, the original rays are not drawn when I leave the erase section active. In other words, if I remark out the section that creates the erase stroke, the ray fills occur. If I do not, then only the erase strokes occur.
I have tested various fixed alpha values and IE9 seems to handle them perfectly. I've set both sections to globalCompositeOperation = 'source-over' and still do not get the original rays.
Can someone help me correct this code to work on IE9?
Thanks
It isn't working in jsfiddle because you never call init()
IE9 is probably breaking script execution on the line:
ctx.rotate(rayArray[currentRay]); // Rotate to the rayAngle
Because it throws an error the first 11 times it is called, because you keep trying to access a value that is undefined the first 10-11 times through.
So I moved your incrementing code down to after the ctx.rotate statement and added the init. It doesn't have errors in IE or FireFox, but I have no way of knowing if its what you intended:
http://jsfiddle.net/Y5Y48/18/