JfreeChart Axis custom precision or range - jfreechart

I am trying to plot a XYPlot using JfreeChart. My X axis has number or client say 30, 50 ,70
and Y axis has cache hit ratio( Value of which sometime varies by 0.01) When i set AutoRange the y axis show range as 0.1 0.2 0.3..... 1.0. So sometimes my plot is nearly straight line since it varies by such a small factor.
I have tried this code
JFreeChart chart = ChartFactory.createXYLineChart(
"Effect of Number of Clients", // Title
"Number of Clients", // x-axis Label
"Cache Hit Ratio", // y-axis Label
datasetLRU, // Dataset
PlotOrientation.VERTICAL, // Plot Orientation
true, // Show Legend
true, // Use tooltips
false // Configure chart to generate URLs?
);
chart.setBackgroundPaint(Color.white);
plot= chart.getXYPlot();
plot.setBackgroundPaint(Color.black);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
final ValueAxis axis = plot.getDomainAxis();
axis.setAutoRange(false);
final NumberAxis axis2 = new NumberAxis("Axis 2");
axis2.setAutoRangeIncludesZero(false);
axis2.setTickUnit(new NumberTickUnit(0.01));
plot.setDataset(1, datasetMARS);
plot.setRenderer(1, new StandardXYItemRenderer());
plot.setDataset(2, datasetNEW);
plot.setRenderer(2, new StandardXYItemRenderer());
So Can any one help in setting Y axis range as 0.01 0.02 0.03 .... 0.98 0.99 1.00
Thanks

Your code doesn't configure the range axis because you create axis2 but you never assign it. When using auto range you can also configure the minium size of an auto ranged axis (method setAutoRangeMinimumSize(double)).
Please try the following source code part:
final NumberAxis axis2 = plot.getRangeAxis();
axis2.setAutoRange(true);
axis2.setAutoRangeIncludesZero(false);
axis2.setAutoRangeMinimumSize(0.001);
axis2.setTickUnit(new NumberTickUnit(0.01));

Related

How to make DrawString work for negative y scale factor?

Working on a private stock chart where I use a rendering rectangle with an origin at lower left and inverted y axis, scale factor y is negative. Y axis ticks render nicely but drawing text (drawstring) is where I run into problems.
using (Pen pen = new Pen(_color))
using (Font drawFont = new Font("Arial", 16))
using (SolidBrush drawBrush = new SolidBrush(Color.Black))
{
pen.Width = 1F / e.Graphics.DpiX;
foreach (float tick in this.TimeSeriesPanelControl.YTicks)
{
e.Graphics.DrawLine(pen, right, tick, right + 10, tick);
// this is not producing text to the right of the tick that renders properly.
e.Graphics.DrawString(tick.ToString("F2"), drawFont, drawBrush, right + 15, tick);
}
}
I have seen that the text is upside down caused by the negative scale factor on the y coordinate.
The question is how to make drawstring render the text to the right of the tick?

Display sun position with Expo and Three.js

So the idea is quite simple: given the sun's position (azimuth and elevation) I want my app to be able to display a shape using augmented reality when the camera is pointing at the sun.
So there is a few steps:
Convert azimuth and elevation into radians, then into cartesian coordinates to get a simple vector {x, y, z}.
Get the phone's gyroscope data to get its orientation in space as a 3D vector {x, y, z}.
Calculate new coordinates for the sun regarding the phone orientation.
Display a random shape using Three.js at these coordinates.
1 and 2 are quite easy. There are a lot of APIs out there giving the sun's position depending on a location. Then I used a formula to convert the sun's spherical coordinates into cartesian ones:
x = R * cos(ϕ) * sin(θ)
y = R * cos(ϕ) * cos(θ)
z = R * sin(ϕ)
with R, the distance of the point from the origin, θ (the azimuth) and ϕ (the elevation).
I got the device's orientation in space with Expo.io, using their Device Motion API. Documentation here
I'm really struggling with the third step. I don't know how to combine sun and device coordinates in space, and project the whole thing through Three.js perspective camera.
I found this post the other day: Compare device 3D orientation with the sun position but I've found the explanations a bit confusing.
Let's say I want to display a cube with Three:
const geometry = new THREE.BoxGeometry(0.07, 0.07, 0.07);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
cube.position.x = 0;
cube.position.y = 0;
cube.position.z = -1;
The final goal here will be to find the correct {x, y, z} so the cube can be displayed at the sun's location. This vector will be of course updated every time the user moves his phone in space.

Map scale factor when converting from Mercator to Equirectangular

Lets say I have a map in Mercator projection, and I know top and bottom latitudes:
topLatitude = 80; bottomLatitude = -55;
I also know width and height of a map:
width = 800; height = 500;
I want to rescale the map to Equirectangular projection, keeping the same width.
How can I calculate new height of a map?
I came up with a solution.
This is formula to calculate x and y of Mercator projected map:
Here is function for y:
function degreesToRadians(degrees){
return degrees / 180 * Math.PI;
}
function mercatorLatitudeToY(latitude){
return Math.log(Math.tan(Math.PI / 4 + degreesToRadians(latitude) / 2));
}
When R=1 the result you get is radians. So I calculate y for top and bottom latitudes.
Next, I calculate the same radians if the projection is Equirectangular - I simply need to convert top and bottom latitude to radians. And last thing - I just need to find aspect ratio of differences:
var scale = (mercatorLatitudeToY(topLatitude) - mercatorLatitudeToY(bottomLatitude))/ (degreesToRadians(topLatitude) - degreesToRadians(bottomLatitude));
For map without Antarctica, aspect ratio is ~1.5

jfreechart get current TickUnit value

I have an XYPlot displaying points and lines.
The points are created randomly so the chart will be different every time I launch the application.
With my current example, I've got the following TickUnit :
- Y axis : 1 2 3 4 5 6 ...
- X axis : 0.2 0.4 0.6 0.8 ...
I'm trying to get current TickUnit but it returns "size=1" for both axis :
NumberAxis range1 = (NumberAxis)plot.getRangeAxis();
NumberTickUnit ntu1 = range1.getTickUnit();
System.out.println(""+ range1.getTickUnit().toString());
NumberAxis range2 = (NumberAxis)plot.getDomainAxis();
NumberTickUnit ntu2 = range2.getTickUnit();
System.out.println(""+ range2.getTickUnit().toString());
Any idea how I can get 0.2 for X axis ?
I'd like to get these values so that I can add an annotation over a line at an appropriated distance.
The documentation mentions:
Note: if the autoTickUnitSelection flag is true the tick unit may be changed while the axis is being drawn, so in that case the return value from this method may be irrelevant if the method is called before the axis has been drawn.
Try calling the method after the graph is displayed, e.g. using SwingUtilities.invokeLater().

Applying in-place transformations to 3D Model in WPF

I have a simple 3D cube that I can rotate using the following code:
void mui3D_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
RotateTransform3D rotation = new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 0), mui.Model.Bounds.Location);
DoubleAnimation rotateAnim = new DoubleAnimation(0, 130d TimeSpan.FromMilliseconds(3000));
rotateAnim.Completed += new EventHandler(rotateAnim_Completed);
mui.Transform = rotation;
rotation.Rotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, rotateAnim);
}
Each time it executes, this code rotates the cube using an animation around the Y axis from an angle of 0 to 130 degrees.
However I would like to apply the rotation "cumulatively" so that the any previous rotation is taken into account and the cube commences each rotation from the angle it finished the previous rotation.
For example: the animation constructor, instead of requiring a "from" and "to" value for the angle, simply rotates the cube an an additional 130 degrees based on whatever the current rotation angle is.
I could easily use a member variable that contains the current angle, pass it to the animation and then update it when the animation has completed. But I'm wondering if there is a standard approach using WPF to achieve this.
I'm sure there's a method for retrieving the current Euler rotation angle in degrees from the object's transformation matrix. You could then use that as the "from" value and animate to the "to" value.
Failing that, simply create a variable somewhere in your application that remembers the number of degrees the cube as been rotated. Each time the function is run just add the number of degrees you'd like it to rotate and then store the result back in your variable.
some pseudo-code:
angle = 0
function onClick:
new_angle = angle + 30
Animate(angle, new_angle)
angle = new_angle

Resources