I have been looking around for quite a long time now, it seems that I am not the only one to ask but no working answers yet:
Generally, how can we align a secondary axis in D3 (Y2 ticks in front of Y1 ticks)?
I am not especially looking for a bit of code; even a general idea or algorithm could help me. The idea is to have something like this guy did in Highchart:
jsfiddle.net/jugal/3qdkc/
Any clues?
You can use a scale's .invert() function to convert projected (screen) coordinates back to values in the original domain. Bearing this in mind, the process is
Get the projected values for the first axis. If you want those to be the tick values, use scale.ticks() and pass them to the first scale to convert to screen coordinates.
Now pass those values to scale.invert() for the second axis scale. This will give you the values in the domain of the second scale.
Pass those values to .tickValues() of the second axis.
Related
I am working with D3.js in version 3.x.
Following this tutorial, I am trying to move an element, in this case a rectangle, along a path and rotate the element based on its position on the path.
This works perfectly fine for any path, that does not have an arc as part of it. Something like this:
M56.200012207,96.1999969482c-51,295,-52,294,280,184c-286,-273,-243,-261,-35,-204
The angle is calculated "correct" on a path like this, and the element translates along this path in a smooth way.
But as soon as the path contains an arc, the angle gets some strange values at some points of the arc and therefore the rectangle flips / jumps around based on this angle while translating along the path. A path with an arc looks like this for example:
M56.20001220703125,66.19999694824219a174.796117,174.796117,0,1,0,275.99999999996874,-2.000000000042192
My assumption:
As for creating an arc, we only give some values, like startpoint and angle, and the rest of the points needed to draw the arc are computed in some way by svg.
Based on my tries, i saw that some of the computed points are not actually where i would expect them to be.
The function used in the linked example calculates two points, p1 and p2 and calculates the angle for the rotation by using Math.atan2 on p1 and p2.
I know the points are very close together, but to simplify my explanation, i have some distance between them in the image.
In this image, i would expect p1 to have smaller values for x and y than p2.
There are a lot of points in that area between p1 and p2, so the function calculates the required angle for each of these pairs. For most of them, the angle is correct, but not for all of them as can be seen in the following console.log() output:
Notice that for most points, the angle is around 67 degree, which is supposed to be like this on the respective area of the path. But then there randomly is one angle that is 33 degree, which of course causes this flipping / jumping effect.
For "expected angles" the transition looks good and something like this:
For "not expected angles", the transition looks bad and something like this:
If this happens a few times throughout the transition, this produces the flipping / jumping effect.
My question:
Why is this happening? The arc looks fine and all the points seem to be in place based on visually looking at them on screen.
Is there any way to avoid this while still being able to use paths with an arc inside?
Thank you very much for any help.
Edit: Added a jsfiddle to show you the problems discussed here and in the comments: Element rotation with point-along-path interpolation - not possible on path with arc?
There is a bug in current Chrome (57 and 58 as of writing) that affects the return values for getPointAtLength() when operating on arc path commands.
https://bugs.chromium.org/p/chromium/issues/detail?id=719516
For now there seems to be no easy fix other than smoothing the output values yourself. Or avoiding arc commands in your paths.
I have a scatterplot created with d3. The circles/points are all the same size. The grid goes from 1-10 on both x and y axes. All points have x and y values of whole numbers (no decimals).
My problem is that I frequently have multiple data points with the same coordinates. Because the points are all the same size I can't tell how many points are at a single spot.
My points have tooltips, one for each data point. So, I was thinking that it's OK to show only a single point/circle if I can show a tooltip that contains information about all points with the same x/y coordinate. I can't think of a way to do that though because the tooltips seem to be generated for a single point, not "for all points at the same coordinate", or generated dynamically.
How can I do this?
As #LarsKotthoff mentioned, aggregating my data before rendering and adding a key function to identify each aggregate were the two steps needed to get everything working properly.
I have a situation that I'm not realy sure how I can handle. I have an openGl object of about 20k vertices, and I need to offer the user the possibility to select any one of these vertices (let's say with a smallest margin of error possible). Now here is what I want to do in order to do this:
Next to the 3D canvas of the object, I also offer the user 3 'slices' done by the planes x=0; y=0 and z=0. Say for the simplest example for a sphere these would be 3 circles, correponding to 'cutting' out one of the dimensions. Now let's take the z=0 one for the purpose of the example. When the user clicks on a point say (x_circle, y_circle) i would like to get the actual point in the 3d representation where he clicked. The z would be 0 of course but I can't figure out a way to get the x and y. I can easily translate that (x_circle, y_circle) -> (x_screen, y_screen) which would have the same result as a click on the canvas at those coordinates, but I need to find a way to translate that into the (x, y, 0) coordinate in 3D view.
The same thing would need to be done with x=0, y=0 but I think if I can understand/implement a way for z=0 I can just apply more or less the same solution with an added rotation over something. If anyone can help with any examples/code or even math behind this it would help a lot because at the moment I'm not really sure how to proceed.
When the user clicks, you can render the vertices using GL.POINTS (with a certain size, if you like) to an off-screen buffer using a shader that renders each vertex' index into RGBA. Then you read back the pixel on the mouse position and see what index it is.
So I am using jqPlot to display distance (y-axis) over time (x-axis) in a simple line graph.
However, while I have actual distances as the underlying data used to position the points, I'm not interested in displaying those distances on the y-axis.
Instead, there are a series of landmarks at given distances, that I want to appear on the y-axis as a 'tick' next to the appropriate point for the distance to that landmark. That way the line appears to "pass" each landmark as it travels upward.
Currently I'm "faking" this by hiding the ticks and putting a manually-created series of labels next to the graph. This works well enough, but I had to disable vertical zooming because if the user chose to zoom in, the labels would not match up with the actual distances. My users would really like to zoom in vertically, however, and I want to allow them to.
Therefore, does anyone know of a way (a plugin or similar) that would allow me to associate custom labels with given tick marks in jqPlot, that will match up nicely and respond to zooming? It would be necessary to hide some of the landmarks if the graph is zoomed out too much, so that would have to be a feature.
Alternatively, if someone knows of a "zoom event" that passes in the min and max y values, I could probably recreate my manual labels with that data, so let me know if you know of a way to get that information. I haven't been able to find one.
I would need to see a bit of your code to customize it to the distance but to start with you could label the ticks and it will display over the size of the chart.
axes:{yaxis:{ticks:['DiscanceA','DiscanceB', 'DiscanceC', 'DiscanceD', 'DiscanceE'],
renderer: $.jqplot.CategoryAxisRenderer,},
Let me know how it goes and if you have any code lets see it!
I'm a fresh in cocos3d, now I have a problem.
In cocos3d, I want to rotate a node. I got the angles in x axis, y axis, z axis, then I used the property:rotation to rotate, like this:
theNodeToBeRotated.rotation = cc3v(x,y,z);
But I found out it didn't rotate as I expected, because the document said the rotate order is y-x-z.
I want to change the order to x-y-z. Can anyone let me know how?
You might need to clarify further regarding the following: "it didn't rotate as I expected"
OpenGL ES (and ergo, cocos3D) uses the y-axis as up so the rotation order is still x-y-z. If you are importing a model, you then need to take into account the 3D editor's co-ordinate system and adapt accordingly.
If you are not used to working with three-dimensional representations, the leap from 2D to 3D can be a significant hurdle. Within Cocos3D:
the x-axis is positive on the right and negative on the left
the y-axis is positive upwards and negative downwards
the z-axis is positive moving towards you and negative moving away from you
Envisage those three lines of axis, or even better, a piece of string.
If you are rotating around the x-axis, hold the string horizontally from left to right: the object would rotating towards you or away from you.
If you are rotating around the y-axis, hold the string vertically from feet to head: the object would rotate as if like a revolving door.
If you are rotating around the z-axis, hold one end close to your chest and the other end as far away as possible: the object would rotate similar to a clock face.
-- Update
I heavily wouldn't recommend changing the rotation order as it is the OpenGL standard to use Y-X-Z. If you wish to modify it, take a look at CC3GLMatrixMath and look for kmMat4RotationYXZ - there is also kmMat4RotationZYX. If you want to have X-Y-Z, you would need to construct your own rotation matrix and update accordingly in CC3GLMatrix and CC3GLMatrixMath.
As a reference, you also have the OpenGL Red book - it should have some suggestions for you.